From 95cd60db52edc023363544889b74ad8a9b17b81d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Sep 2014 21:50:09 +0200 Subject: [PATCH 001/240] Some initial bugfixing for the map generation --HG-- branch : develop --- .../screenshot_islands.cpp | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index c0fcb667d..363414aa5 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -85,7 +85,7 @@ CScreenshotIslands::CScreenshotIslands() void CScreenshotIslands::init() { // Create a driver - driver = UDriver::createDriver(); + driver = UDriver::createDriver(0, true); nlassert(driver); sceneMaterial = driver->createMaterial(); @@ -99,8 +99,6 @@ void CScreenshotIslands::init() CConfigFile cf; cf.load("island_screenshots.cfg"); - CPath::remapExtension("dds", "tga", true); - // get the value of searchPaths CConfigFile::CVar * searchPaths = cf.getVarPtr("SearchPaths"); if(searchPaths) @@ -110,6 +108,7 @@ void CScreenshotIslands::init() CPath::addSearchPath(searchPaths->asString(i).c_str(), true, false); } } + CPath::remapExtension("dds", "tga", true); // get the scenario entry points file CConfigFile::CVar * epFile = cf.getVarPtr("CompleteIslandsFile"); @@ -1348,11 +1347,13 @@ void CScreenshotIslands::buildIslandsTextures() int maxLoop = 6; // Create the window with config file values - driver->setDisplay(UDriver::CMode(1024, 768, 32, false)); + driver->setDisplay(UDriver::CMode(512, 512, 32, true)); // Create a scene UScene * scene = driver->createScene(true); scene->animate(CTime::ticksToSecond(CTime::getPerformanceTime())); + scene->setMaxSkeletonsInNotCLodForm(1000000); + scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); // Create a camera UCamera camera = scene->getCam(); @@ -1360,6 +1361,7 @@ void CScreenshotIslands::buildIslandsTextures() // Create and load landscape ULandscape * landscape = scene->createLandscape(); + landscape->setThreshold(0.0005); if(_InverseZTest) { landscape->setZFunc(UMaterial::greaterequal); @@ -1394,6 +1396,7 @@ void CScreenshotIslands::buildIslandsTextures() string coarseMeshWithoutExt = CFile::getFilenameWithoutExtension(coarseMeshFile); string coarseMeshExt = CFile::getExtension(coarseMeshFile); coarseMeshFile = coarseMeshWithoutExt + seasonSuffix + "." + coarseMeshExt; + nldebug("Coarse mesh texture: '%s'", coarseMeshFile.c_str()); scene->setCoarseMeshManagerTexture(coarseMeshFile.c_str()); // Load the landscape @@ -1468,6 +1471,7 @@ void CScreenshotIslands::buildIslandsTextures() } } } + scene->animate(CTime::ticksToSecond(CTime::getPerformanceTime())); // Clear all buffers driver->clearBuffers(_BackColor); @@ -1535,17 +1539,36 @@ void CScreenshotIslands::buildIslandsTextures() CIFile proxFS(proxFileName.c_str()); proxBitmap.load(proxFS); + // resize proximity bitmap CBitmap tempBitmap; int newWidth = islandBitmap.getWidth(); int newHeight = islandBitmap.getHeight(); tempBitmap.resize(newWidth, newHeight, islandBitmap.PixelFormat); // blit src bitmap - tempBitmap.blit(proxBitmap, 0, 0, newWidth, newHeight, 0, 0); + //tempBitmap.blit(proxBitmap, 0, 0, newWidth, newHeight, 0, 0); + { + const uint8 *prox = &(proxBitmap.getPixels(0)[0]); + uint8 *temp = &(tempBitmap.getPixels(0)[0]); + for (uint y = 0; y < newHeight; ++y) + for (uint x = 0; x < newWidth; ++x) + { + uint ys = (y * proxBitmap.getHeight()) / newHeight; + uint xs = (x * proxBitmap.getWidth()) / newWidth; + uint addr = ((y * newWidth) + x) * 4; + uint addrs = ((ys * proxBitmap.getWidth()) + xs) * 4; + temp[addr] = prox[addrs]; + temp[addr+1] = prox[addrs+1]; + temp[addr+2] = prox[addrs+2]; + temp[addr+3] = prox[addrs+3]; + } + } // swap them proxBitmap.resize(newWidth, newHeight, proxBitmap.PixelFormat); proxBitmap.swap(tempBitmap); + + //proxBitmap.resample(newWidth, newHeight); // create final bitmap @@ -2081,7 +2104,7 @@ void CProximityMapBuffer::_prepareBufferForZoneProximityMap(const CProximityZone { zoneBuffer[offset]= InteriorValue; - if(offset-zoneWidth>0 && zoneBuffer[offset-zoneWidth]==(TBufferEntry)~0u) + if(offset>zoneWidth && zoneBuffer[offset-zoneWidth]==(TBufferEntry)~0u) { zoneBuffer[offset-zoneWidth] = ValueBorder; } From 4f648ba736f6d1eb21d8bacfa2cfd923bd0aa12e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Sep 2014 22:09:43 +0200 Subject: [PATCH 002/240] Fix texture lookup --HG-- branch : develop --- .../tools/client/r2_islands_textures/screenshot_islands.cpp | 1 + .../server/build_world_packed_col/build_world_packed_col.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index 363414aa5..db115b154 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -109,6 +109,7 @@ void CScreenshotIslands::init() } } CPath::remapExtension("dds", "tga", true); + CPath::remapExtension("dds", "png", true); // get the scenario entry points file CConfigFile::CVar * epFile = cf.getVarPtr("CompleteIslandsFile"); diff --git a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp index a9d1daa9e..9bd4f7f3c 100644 --- a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp @@ -111,6 +111,7 @@ int main(int argc, char* argv[]) CPath::addSearchPath(builderConfig.SearchPaths[k], true, false); } CPath::remapExtension("dds", "tga", true); + CPath::remapExtension("dds", "png", true); // R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); try From 6c28bfb45931416f84b058c770a2f80907a369f7 Mon Sep 17 00:00:00 2001 From: kishan_grimout Date: Thu, 11 Apr 2013 14:30:00 +0200 Subject: [PATCH 003/240] avoid recursion problem when 'taking all' in quarter temp inventory in EGS --HG-- branch : develop --- .../entities_game_service/creature_manager/harvestable.h | 2 +- .../entities_game_service/player_manager/character.cpp | 2 +- .../src/entities_game_service/player_manager/character.h | 4 ++-- .../player_manager/character_inventory_manipulation.cpp | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/creature_manager/harvestable.h b/code/ryzom/server/src/entities_game_service/creature_manager/harvestable.h index cd1ecfd06..f966e6cb0 100644 --- a/code/ryzom/server/src/entities_game_service/creature_manager/harvestable.h +++ b/code/ryzom/server/src/entities_game_service/creature_manager/harvestable.h @@ -188,7 +188,7 @@ protected: /// the harvestable Mps (4 per entity) std::vector< CCreatureRawMaterial> _Mps; - /// pointer on the harverting character + /// pointer on the harvesting character TDataSetRow _HarvesterRowId; /// skill used to harvest this creature diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp index 4a9096232..3c72995ea 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -14167,7 +14167,7 @@ void CCharacter::sendCloseTempInventoryImpulsion() BOMB_IF(isRecursing,"CCharacter::sendCloseTempInventoryImpulsion is recursing!",return); // **** Temp Fix 2/4 **** // isRecursing= true; // **** Temp Fix 3/4 **** // - getAllTempInventoryItems(); + getAllTempInventoryItems(false); CMessage msgout( "IMPULSION_ID" ); msgout.serial( _Id ); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.h b/code/ryzom/server/src/entities_game_service/player_manager/character.h index 3f97c6b3e..de6d3f110 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.h @@ -2623,13 +2623,13 @@ public: CGameItemPtr createItemInInventoryFreeSlot(INVENTORIES::TInventory invId, uint16 obtainedQuality, uint32 quantity, const NLMISC::CSheetId & obtainedItem, const NLMISC::CEntityId & creatorId = NLMISC::CEntityId::Unknown, const std::string * phraseId = NULL); /// action on an item in the temp inventory (move it to bag) - void itemTempInventoryToBag(uint32 scrSlot); + void itemTempInventoryToBag(uint32 scrSlot, bool sendCloseTempImpulsion = true); /// clear temp inventory void clearTempInventory(); /// get all items in temp inventory - void getAllTempInventoryItems(); + void getAllTempInventoryItems(bool sendCloseTempImpulsion = true); /// return true if temp inventory is empty bool tempInventoryEmpty(); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp index 2ce09282c..139cf1b4e 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp @@ -1841,7 +1841,7 @@ CGameItemPtr CCharacter::createItemInInventoryFreeSlot(INVENTORIES::TInventory i } // **************************************************************************** -void CCharacter::itemTempInventoryToBag(uint32 srcSlot) +void CCharacter::itemTempInventoryToBag(uint32 srcSlot, bool sendCloseTempImpulsion) { H_AUTO(CCharacter_itemTempInventoryToBag); @@ -2015,7 +2015,7 @@ void CCharacter::itemTempInventoryToBag(uint32 srcSlot) CWorldInstances::instance().msgToAIInstance(getInstanceNumber(), msg); } - endHarvest(); + endHarvest(sendCloseTempImpulsion); leaveTempInventoryMode(); } @@ -2108,12 +2108,12 @@ void CCharacter::itemTempInventoryToBag(uint32 srcSlot) } // **************************************************************************** -void CCharacter::getAllTempInventoryItems() +void CCharacter::getAllTempInventoryItems(bool sendCloseTempImpulsion) { H_AUTO(CCharacter_getAllTempInventoryItems); for (uint i = 0 ; i < INVENTORIES::NbTempInvSlots; ++i) - itemTempInventoryToBag(i); + itemTempInventoryToBag(i, sendCloseTempImpulsion); } // **************************************************************************** From e12d189d51cf44bb148016bd4a6c1f4f7794b3a9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 20 Apr 2014 21:41:57 +0200 Subject: [PATCH 004/240] Refactored input event handling a bit. --HG-- branch : gui-editor --- code/nel/include/nel/gui/widget_manager.h | 8 +- code/nel/src/gui/widget_manager.cpp | 692 +++++++++++----------- 2 files changed, 364 insertions(+), 336 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 5fd75ac8a..6d4f47164 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -332,7 +332,13 @@ namespace NLGUI void drawViews( NL3D::UCamera camera ); bool handleEvent( const CEventDescriptor &evnt ); - + + bool handleSystemEvent( const CEventDescriptor &evnt ); + + bool handleKeyboardEvent( const CEventDescriptor &evnt ); + + bool handleMouseEvent( const CEventDescriptor &evnt ); + bool handleMouseMoveEvent( const CEventDescriptor &eventDesc ); // Relative move of pointer diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 16357d373..2c3f1159e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2096,456 +2096,478 @@ namespace NLGUI if( activeAnims[i]->isDisableButtons() ) return false; + bool handled = false; + + CViewPointer *_Pointer = static_cast< CViewPointer* >( getPointer() ); + if( evnt.getType() == CEventDescriptor::system ) { - const CEventDescriptorSystem &systemEvent = reinterpret_cast< const CEventDescriptorSystem& >( evnt ); - if( systemEvent.getEventTypeExtended() == CEventDescriptorSystem::setfocus ) + handleSystemEvent( evnt ); + } + else + if (evnt.getType() == CEventDescriptor::key) + { + handled = handleKeyboardEvent( evnt ); + } + else if (evnt.getType() == CEventDescriptor::mouse ) + { + handled = handleMouseEvent( evnt ); + } + + CDBManager::getInstance()->flushObserverCalls(); + + return handled; + } + + bool CWidgetManager::handleSystemEvent( const CEventDescriptor &evnt ) + { + const CEventDescriptorSystem &systemEvent = reinterpret_cast< const CEventDescriptorSystem& >( evnt ); + if( systemEvent.getEventTypeExtended() == CEventDescriptorSystem::setfocus ) + { + if( getCapturePointerLeft() != NULL ) { - if( getCapturePointerLeft() != NULL ) - { - getCapturePointerLeft()->handleEvent( evnt ); - setCapturePointerLeft( NULL ); - } + getCapturePointerLeft()->handleEvent( evnt ); + setCapturePointerLeft( NULL ); + } - if( getCapturePointerRight() != NULL ) - { - getCapturePointerRight()->handleEvent( evnt ); - setCapturePointerRight( NULL ); - } + if( getCapturePointerRight() != NULL ) + { + getCapturePointerRight()->handleEvent( evnt ); + setCapturePointerRight( NULL ); + } - if( _CapturedView != NULL ) - { - _CapturedView->handleEvent( evnt ); - _CapturedView = NULL; - } + if( _CapturedView != NULL ) + { + _CapturedView->handleEvent( evnt ); + _CapturedView = NULL; } } - bool handled = false; + return true; + } - CViewPointer *_Pointer = static_cast< CViewPointer* >( getPointer() ); + bool CWidgetManager::handleKeyboardEvent( const CEventDescriptor &evnt ) + { + bool handled = false; + + CEventDescriptorKey &eventDesc = (CEventDescriptorKey&)evnt; - if (evnt.getType() == CEventDescriptor::key) - { - CEventDescriptorKey &eventDesc = (CEventDescriptorKey&)evnt; - //_LastEventKeyDesc = eventDesc; + //_LastEventKeyDesc = eventDesc; - // Any Key event disable the ContextHelp - disableContextHelp(); + // Any Key event disable the ContextHelp + disableContextHelp(); - // Hide menu if the key is pushed - // if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift()) - // Hide menu (or popup menu) is ESCAPE pressed - if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + // Hide menu if the key is pushed +// if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift()) + // Hide menu (or popup menu) is ESCAPE pressed + if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + { + if( hasModal() ) { - if( hasModal() ) - { - SModalWndInfo mwi = getModal(); - if (mwi.ModalExitKeyPushed) - disableModalWindow(); - } + SModalWndInfo mwi = getModal(); + if (mwi.ModalExitKeyPushed) + disableModalWindow(); } + } - // Manage "quit window" If the Key is ESCAPE, no captureKeyboard - if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + // Manage "quit window" If the Key is ESCAPE, no captureKeyboard + if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) + { + // Get the last escapable active top window. NB: this is ergonomically better. + CInterfaceGroup *win= getLastEscapableTopWindow(); + if( win ) { - // Get the last escapable active top window. NB: this is ergonomically better. - CInterfaceGroup *win= getLastEscapableTopWindow(); - if( win ) + // If the window is a modal, must pop it. + if( dynamic_cast(win) ) { - // If the window is a modal, must pop it. - if( dynamic_cast(win) ) - { - if(!win->getAHOnEscape().empty()) - CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); - popModalWindow(); - handled= true; - } - // else just disable it. - // Special case: leave the escape Key to the CaptureKeyboard . - else if( !getCaptureKeyboard() ) - { - if(!win->getAHOnEscape().empty()) - CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); - win->setActive(false); - handled= true; - } + if(!win->getAHOnEscape().empty()) + CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); + popModalWindow(); + handled= true; + } + // else just disable it. + // Special case: leave the escape Key to the CaptureKeyboard . + else if( !getCaptureKeyboard() ) + { + if(!win->getAHOnEscape().empty()) + CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams()); + win->setActive(false); + handled= true; } } + } - // Manage complex "Enter" - if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN) + // Manage complex "Enter" + if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN) + { + // If the top window has Enter AH + CInterfaceGroup *tw= getTopWindow(); + if(tw && !tw->getAHOnEnter().empty()) { - // If the top window has Enter AH - CInterfaceGroup *tw= getTopWindow(); - if(tw && !tw->getAHOnEnter().empty()) + // if the captured keyboard is in this Modal window, then must handle him in priority + if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw) { - // if the captured keyboard is in this Modal window, then must handle him in priority - if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw) - { - bool result = getCaptureKeyboard()->handleEvent(evnt); - CDBManager::getInstance()->flushObserverCalls(); - return result; - } - else - { - // The window or modal control the OnEnter. Execute, and don't go to the chat. - CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams()); - handled= true; - } + bool result = getCaptureKeyboard()->handleEvent(evnt); + CDBManager::getInstance()->flushObserverCalls(); + return result; + } + else + { + // The window or modal control the OnEnter. Execute, and don't go to the chat. + CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams()); + handled= true; } + } - // else the 'return' key bring back to the last edit box (if possible) - CCtrlBase *oldCapture = getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard(); - if ( getCaptureKeyboard() == NULL && oldCapture && !handled) + // else the 'return' key bring back to the last edit box (if possible) + CCtrlBase *oldCapture = getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard(); + if ( getCaptureKeyboard() == NULL && oldCapture && !handled) + { + /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided + through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible + for the default capture (main chat) or the old captured window to not want to recover + (temporary Read Only chat for instance) + */ + if(!dynamic_cast(oldCapture) || + dynamic_cast(oldCapture)->getRecoverFocusOnEnter()) { - /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided - through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible - for the default capture (main chat) or the old captured window to not want to recover - (temporary Read Only chat for instance) - */ - if(!dynamic_cast(oldCapture) || - dynamic_cast(oldCapture)->getRecoverFocusOnEnter()) + setCaptureKeyboard( oldCapture ); + notifyElementCaptured(getCaptureKeyboard() ); + // make sure all parent windows are active + CCtrlBase *cb = getCaptureKeyboard(); + CGroupContainer *lastContainer = NULL; + for(;;) { - setCaptureKeyboard( oldCapture ); - notifyElementCaptured(getCaptureKeyboard() ); - // make sure all parent windows are active - CCtrlBase *cb = getCaptureKeyboard(); - CGroupContainer *lastContainer = NULL; - for(;;) + CGroupContainer *gc = dynamic_cast(cb); + if (gc) lastContainer = gc; + cb->forceOpen(); + if (cb->getParent()) { - CGroupContainer *gc = dynamic_cast(cb); - if (gc) lastContainer = gc; - cb->forceOpen(); - if (cb->getParent()) - { - cb = cb->getParent(); - } - else - { - cb->invalidateCoords(); - break; - } + cb = cb->getParent(); } - if (lastContainer) + else { - setTopWindow(lastContainer); - lastContainer->enableBlink(1); + cb->invalidateCoords(); + break; } - handled= true; } + if (lastContainer) + { + setTopWindow(lastContainer); + lastContainer->enableBlink(1); + } + handled= true; } } + } - // General case: handle it in the Captured keyboard - if ( getCaptureKeyboard() != NULL && !handled) - { - bool result = getCaptureKeyboard()->handleEvent(evnt); - CDBManager::getInstance()->flushObserverCalls(); - return result; - } - - lastKeyEvent = eventDesc; + // General case: handle it in the Captured keyboard + if ( getCaptureKeyboard() != NULL && !handled) + { + bool result = getCaptureKeyboard()->handleEvent(evnt); + CDBManager::getInstance()->flushObserverCalls(); + return result; } - //////////////////////////////////////////////// Keyboard handling ends here //////////////////////////////////// + lastKeyEvent = eventDesc; - else if (evnt.getType() == CEventDescriptor::mouse ) - { - CEventDescriptorMouse &eventDesc = (CEventDescriptorMouse&)evnt; + return handled; + } - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) ); - else - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) ); - else - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) ); - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) - _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) ); + bool CWidgetManager::handleMouseEvent( const CEventDescriptor &evnt ) + { + bool handled = false; - if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove ) - handleMouseMoveEvent( eventDesc ); + CEventDescriptorMouse &eventDesc = (CEventDescriptorMouse&)evnt; - eventDesc.setX( _Pointer->getX() ); - eventDesc.setY( _Pointer->getY() ); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) ); + else + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) ); + else + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) ); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) + _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) ); - if( isMouseHandlingEnabled() ) - { - // First thing to do : Capture handling - if ( getCapturePointerLeft() != NULL) - handled|= getCapturePointerLeft()->handleEvent(evnt); + if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove ) + handleMouseMoveEvent( eventDesc ); - if ( getCapturePointerRight() != NULL && - getCapturePointerLeft() != getCapturePointerRight() ) - handled|= getCapturePointerRight()->handleEvent(evnt); + eventDesc.setX( _Pointer->getX() ); + eventDesc.setY( _Pointer->getY() ); - if( _CapturedView != NULL ) - _CapturedView->handleEvent( evnt ); + if( isMouseHandlingEnabled() ) + { + // First thing to do : Capture handling + if ( getCapturePointerLeft() != NULL) + handled|= getCapturePointerLeft()->handleEvent(evnt); - CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); - setCurrentWindowUnder( ptr ); + if ( getCapturePointerRight() != NULL && + getCapturePointerLeft() != getCapturePointerRight() ) + handled|= getCapturePointerRight()->handleEvent(evnt); - // Any Mouse event but move disable the ContextHelp - if(eventDesc.getEventTypeExtended() != CEventDescriptorMouse::mousemove) - { - disableContextHelp(); - } + if( _CapturedView != NULL ) + _CapturedView->handleEvent( evnt ); - // get the group under the mouse - CInterfaceGroup *pNewCurrentWnd = getCurrentWindowUnder(); - setMouseOverWindow( pNewCurrentWnd != NULL ); + CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); + setCurrentWindowUnder( ptr ); + // Any Mouse event but move disable the ContextHelp + if(eventDesc.getEventTypeExtended() != CEventDescriptorMouse::mousemove) + { + disableContextHelp(); + } - NLMISC::CRefPtr clickedOutModalWindow; + // get the group under the mouse + CInterfaceGroup *pNewCurrentWnd = getCurrentWindowUnder(); + setMouseOverWindow( pNewCurrentWnd != NULL ); - // modal special features - if ( hasModal() ) + + NLMISC::CRefPtr clickedOutModalWindow; + + // modal special features + if ( hasModal() ) + { + CWidgetManager::SModalWndInfo mwi = getModal(); + if(mwi.ModalWindow) { - CWidgetManager::SModalWndInfo mwi = getModal(); - if(mwi.ModalWindow) + // If we are not in "click out" mode so we dont handle controls other than those of the modal + if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut) { - // If we are not in "click out" mode so we dont handle controls other than those of the modal - if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut) - { - pNewCurrentWnd = NULL; - } - else + pNewCurrentWnd = NULL; + } + else + { + // If there is a handler on click out launch it + if (pNewCurrentWnd != mwi.ModalWindow) + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || + (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + if (!mwi.ModalHandlerClickOut.empty()) + CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams); + + // If the current window is not the modal and if must quit on click out + if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut) { - // If there is a handler on click out launch it - if (pNewCurrentWnd != mwi.ModalWindow) - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || - (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) - if (!mwi.ModalHandlerClickOut.empty()) - CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams); - - // If the current window is not the modal and if must quit on click out - if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut) - { - // NB: don't force handle==true because to quit a modal does not avoid other actions + // NB: don't force handle==true because to quit a modal does not avoid other actions - // quit if click outside - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || - (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + // quit if click outside + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown || + (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)) + { + clickedOutModalWindow = dynamic_cast((CInterfaceGroup*)mwi.ModalWindow); + // disable the modal + popModalWindow(); + if ( hasModal() ) { - clickedOutModalWindow = dynamic_cast((CInterfaceGroup*)mwi.ModalWindow); - // disable the modal - popModalWindow(); - if ( hasModal() ) - { - // don't handle event unless it is a previous modal window - if( !isPreviousModal( pNewCurrentWnd ) ) - pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows - } - movePointer (0,0); // Reget controls under pointer + // don't handle event unless it is a previous modal window + if( !isPreviousModal( pNewCurrentWnd ) ) + pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows } + movePointer (0,0); // Reget controls under pointer } } } } + } - // Manage LeftClick. - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) + // Manage LeftClick. + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) + { + if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) { - if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) + CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); + if (pGC != NULL) { - CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); - if (pGC != NULL) - { - if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); - } - else - { - setTopWindow(pNewCurrentWnd); - } + if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); + } + else + { + setTopWindow(pNewCurrentWnd); } + } - bool captured = false; + bool captured = false; - // must not capture a new element if a sheet is currentlty being dragged. - // This may happen when alt-tab has been used => the sheet is dragged but the left button is up - if (!CCtrlDraggable::getDraggedSheet()) + // must not capture a new element if a sheet is currentlty being dragged. + // This may happen when alt-tab has been used => the sheet is dragged but the left button is up + if (!CCtrlDraggable::getDraggedSheet()) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; - } + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; } } + } - if( CInterfaceElement::getEditorMode() && !captured ) + if( CInterfaceElement::getEditorMode() && !captured ) + { + for( sint32 i = _ViewsUnderPointer.size()-1; i >= 0; i-- ) { - for( sint32 i = _ViewsUnderPointer.size()-1; i >= 0; i-- ) + CViewBase *v = _ViewsUnderPointer[i]; + if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) ) { - CViewBase *v = _ViewsUnderPointer[i]; - if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) ) - { - _CapturedView = v; - captured = true; - break; - } + _CapturedView = v; + captured = true; + break; } } - - notifyElementCaptured( getCapturePointerLeft() ); - if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) - { - CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams); - } } - //if found - if ( captured ) - { - // consider clicking on a control implies handling of the event. - handled= true; - // handle the capture - if( getCapturePointerLeft() != NULL ) - getCapturePointerLeft()->handleEvent(evnt); - else - _CapturedView->handleEvent( evnt ); + notifyElementCaptured( getCapturePointerLeft() ); + if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) + { + CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams); } } + //if found + if ( captured ) + { + // consider clicking on a control implies handling of the event. + handled= true; + + // handle the capture + if( getCapturePointerLeft() != NULL ) + getCapturePointerLeft()->handleEvent(evnt); + else + _CapturedView->handleEvent( evnt ); + } + } - // Manage RightClick - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown) + // Manage RightClick + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown) + { + if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) { - if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable())) + CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); + if (pGC != NULL) { - CGroupContainer *pGC = dynamic_cast(pNewCurrentWnd); - if (pGC != NULL) - { - if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); - } - else - { - setTopWindow(pNewCurrentWnd); - } + if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); + } + else + { + setTopWindow(pNewCurrentWnd); } + } - // Take the top most control. + // Take the top most control. + { + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerRight( ctrl ); - } + nMaxDepth = d; + setCapturePointerRight( ctrl ); } } - notifyElementCaptured( getCapturePointerRight() ); - if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) - { - CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams); - } } - //if found - if ( getCapturePointerRight() != NULL) + notifyElementCaptured( getCapturePointerRight() ); + if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) { - // handle the capture - handled |= getCapturePointerRight()->handleEvent(evnt); + CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams); } } + //if found + if ( getCapturePointerRight() != NULL) + { + // handle the capture + handled |= getCapturePointerRight()->handleEvent(evnt); + } + } - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) - { - if (!handled) - if (pNewCurrentWnd != NULL) - pNewCurrentWnd->handleEvent(evnt); - if ( getCapturePointerRight() != NULL) - { - setCapturePointerRight(NULL); - handled= true; - } + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) + { + if (!handled) + if (pNewCurrentWnd != NULL) + pNewCurrentWnd->handleEvent(evnt); + if ( getCapturePointerRight() != NULL) + { + setCapturePointerRight(NULL); + handled= true; } + } - // window handling. if not handled by a control - if (!handled) + // window handling. if not handled by a control + if (!handled) + { + if (((pNewCurrentWnd != NULL) && !hasModal()) || + ((hasModal() && getModal().ModalWindow == pNewCurrentWnd))) { - if (((pNewCurrentWnd != NULL) && !hasModal()) || - ((hasModal() && getModal().ModalWindow == pNewCurrentWnd))) + CEventDescriptorMouse ev2 = eventDesc; + sint32 x= eventDesc.getX(), y = eventDesc.getY(); + if (pNewCurrentWnd) { - CEventDescriptorMouse ev2 = eventDesc; - sint32 x= eventDesc.getX(), y = eventDesc.getY(); - if (pNewCurrentWnd) - { - pNewCurrentWnd->absoluteToRelative (x, y); - ev2.setX (x); ev2.setY (y); - handled|= pNewCurrentWnd->handleEvent (ev2); - } - - // After handle event of a left click, may set window Top if movable (infos etc...) - //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() ) - // setTopWindow(pNewCurrentWnd); + pNewCurrentWnd->absoluteToRelative (x, y); + ev2.setX (x); ev2.setY (y); + handled|= pNewCurrentWnd->handleEvent (ev2); } + + // After handle event of a left click, may set window Top if movable (infos etc...) + //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() ) + // setTopWindow(pNewCurrentWnd); } + } - // Put here to let a chance to the window to handle if the capture dont - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + // Put here to let a chance to the window to handle if the capture dont + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + { + if ( getCapturePointerLeft() != NULL) { - if ( getCapturePointerLeft() != NULL) - { - setCapturePointerLeft(NULL); - handled = true; - } + setCapturePointerLeft(NULL); + handled = true; } + } - // If the current window is the modal, may Modal quit. Do it after standard event handle - if(hasModal() && pNewCurrentWnd == getModal().ModalWindow) + // If the current window is the modal, may Modal quit. Do it after standard event handle + if(hasModal() && pNewCurrentWnd == getModal().ModalWindow) + { + // NB: don't force handle==true because to quit a modal does not avoid other actions + CWidgetManager::SModalWndInfo mwi = getModal(); + // and if must quit on click right + if(mwi.ModalExitClickR) { - // NB: don't force handle==true because to quit a modal does not avoid other actions - CWidgetManager::SModalWndInfo mwi = getModal(); - // and if must quit on click right - if(mwi.ModalExitClickR) - { - // quit if click right - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) - // disable the modal - disableModalWindow(); - } - - // and if must quit on click left - if(mwi.ModalExitClickL) - { - // quit if click right - if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) - // disable the modal - disableModalWindow(); - } + // quit if click right + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup) + // disable the modal + disableModalWindow(); } - // If the mouse is over a window, always consider the event is taken (avoid click behind) - handled|= isMouseOverWindow(); + // and if must quit on click left + if(mwi.ModalExitClickL) + { + // quit if click right + if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup) + // disable the modal + disableModalWindow(); + } } - } - CDBManager::getInstance()->flushObserverCalls(); + // If the mouse is over a window, always consider the event is taken (avoid click behind) + handled|= isMouseOverWindow(); + } return handled; } - bool CWidgetManager::handleMouseMoveEvent( const CEventDescriptor &eventDesc ) { if( getPointer() == NULL ) From 4abf74d6e9738efee8830dcde5029f1c71484062 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 21 Apr 2014 19:30:33 +0200 Subject: [PATCH 005/240] We can now drag elements, they will disappear and whatnot, but at least they can be dragged! --HG-- branch : gui-editor --- code/nel/include/nel/gui/interface_element.h | 3 + code/nel/include/nel/gui/interface_group.h | 3 + code/nel/include/nel/gui/widget_manager.h | 5 ++ code/nel/src/gui/interface_group.cpp | 26 ++++++++ code/nel/src/gui/widget_manager.cpp | 63 ++++++++++++++++++-- 5 files changed, 96 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 764d165ef..db7a499c8 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -233,6 +233,9 @@ namespace NLGUI virtual void setActive (bool state); + void setXReal( sint32 x ){ _XReal = x; } + void setYReal( sint32 y ){ _YReal = y; } + void setX (sint32 x) { _X = x; } void setXAndInvalidateCoords (sint32 x) { _X = x; invalidateCoords(); } diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index f72bc6f1f..ff0efac3b 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -79,6 +79,9 @@ namespace NLGUI bool delElement (const std::string &id, bool noWarning=false); bool delElement (CInterfaceElement *pIE, bool noWarning=false); + // Take the element from the group, but don't delete it! + CInterfaceElement* takeElement( CInterfaceElement *e ); + uint getNumGroup() const { return (uint)_ChildrenGroups.size(); } CInterfaceGroup *getGroup(uint index) const; diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 6d4f47164..5d2468e7a 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -532,6 +532,11 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; + NLMISC::CRefPtr< CInterfaceElement > draggedElement; + + bool startDragging(); + void stopDragging(); + // What is under pointer std::vector< CViewBase* > _ViewsUnderPointer; std::vector< CCtrlBase* > _CtrlsUnderPointer; diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 5fa83e1c5..4d37eda1c 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -1638,6 +1638,32 @@ namespace NLGUI return delView(static_cast(pIE)); } + // ------------------------------------------------------------------------------------------------ + CInterfaceElement* CInterfaceGroup::takeElement( CInterfaceElement *e ) + { + bool ok = false; + + if( e->isGroup() ) + { + ok = delGroup( static_cast< CInterfaceGroup* >( e ), true ); + } + else + if( e->isCtrl() ) + { + ok = delCtrl( static_cast< CCtrlBase* >( e ), true ); + } + else + if( e->isView() ) + { + ok = delView( static_cast< CViewBase* >( e ), true ); + } + + if( ok ) + return e; + else + return NULL; + } + // ------------------------------------------------------------------------------------------------ bool CInterfaceGroup::isWindowUnder (sint32 x, sint32 y) { diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 2c3f1159e..e3f1064fa 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2039,6 +2039,12 @@ namespace NLGUI } } + if( draggedElement != NULL ) + { + CInterfaceElement *e = draggedElement; + static_cast< CViewBase* >( e )->draw(); + } + if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty()) { driver->setMatrixMode2D11(); @@ -2437,11 +2443,11 @@ namespace NLGUI // consider clicking on a control implies handling of the event. handled= true; - // handle the capture if( getCapturePointerLeft() != NULL ) - getCapturePointerLeft()->handleEvent(evnt); - else - _CapturedView->handleEvent( evnt ); + _CapturedView = getCapturePointerLeft(); + + // handle the capture + _CapturedView->handleEvent( evnt ); } } @@ -2534,6 +2540,11 @@ namespace NLGUI setCapturePointerLeft(NULL); handled = true; } + + _CapturedView = NULL; + + if( CInterfaceElement::getEditorMode() ) + stopDragging(); } @@ -2602,8 +2613,52 @@ namespace NLGUI ve.setY( getPointer()->getY() ); } + if( CInterfaceElement::getEditorMode() ) + { + if( ( _CapturedView != NULL ) && ( draggedElement == NULL ) ) + { + startDragging(); + } + else + if( draggedElement != NULL ) + { + draggedElement->setXReal( newX ); + draggedElement->setYReal( newY ); + draggedElement->invalidateCoords(); + } + } + return true; } + + // ------------------------------------------------------------------------------------------------ + bool CWidgetManager::startDragging() + { + CInterfaceElement *e = NULL; + + CInterfaceGroup *g = _CapturedView->getParent(); + if( g != NULL ) + { + e = g->takeElement( _CapturedView ); + if( e == NULL ) + { + nlinfo( "Something went horribly wrong :(" ); + return false; + } + } + else + e = _CapturedView; + + e->setParent( NULL ); + draggedElement = e; + + return true; + } + + void CWidgetManager::stopDragging() + { + draggedElement = NULL; + } // ------------------------------------------------------------------------------------------------ void CWidgetManager::movePointer (sint32 dx, sint32 dy) From f281622d47b58f5a1c12561cb947e63fc367a3c3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 8 Jul 2014 22:21:11 +0200 Subject: [PATCH 006/240] Trash DirectInput --HG-- branch : game-device --- code/nel/include/nel/3d/driver.h | 45 +- code/nel/include/nel/3d/driver_user.h | 15 - code/nel/include/nel/3d/u_driver.h | 30 - code/nel/include/nel/misc/di_event_emitter.h | 204 ------ code/nel/include/nel/misc/event_emitter.h | 13 - .../include/nel/misc/event_emitter_multi.h | 1 - code/nel/include/nel/misc/game_device.h | 114 --- .../nel/include/nel/misc/game_device_events.h | 209 ------ code/nel/include/nel/misc/input_device.h | 84 --- .../include/nel/misc/input_device_manager.h | 69 -- .../include/nel/misc/input_device_server.h | 84 --- code/nel/include/nel/misc/keyboard_device.h | 63 -- code/nel/include/nel/misc/mouse_device.h | 130 ---- code/nel/include/nel/misc/win_event_emitter.h | 2 - .../3d/driver/direct3d/driver_direct3d.cpp | 6 +- .../driver/direct3d/driver_direct3d_index.cpp | 2 - .../direct3d/driver_direct3d_inputs.cpp | 3 - .../driver/direct3d/driver_direct3d_light.cpp | 2 - .../direct3d/driver_direct3d_material.cpp | 6 +- .../direct3d/driver_direct3d_matrix.cpp | 2 - .../direct3d/driver_direct3d_render.cpp | 2 - .../direct3d/driver_direct3d_texture.cpp | 2 - .../direct3d/driver_direct3d_vertex.cpp | 2 - .../src/3d/driver/opengl/driver_opengl.cpp | 6 +- .../3d/driver/opengl/driver_opengl_inputs.cpp | 2 - .../3d/driver/opengl/driver_opengl_window.cpp | 8 +- .../driver/opengl/mac/cocoa_event_emitter.h | 8 +- code/nel/src/3d/driver/opengl/stdopengl.h | 1 - .../3d/driver/opengl/unix_event_emitter.cpp | 55 +- .../src/3d/driver/opengl/unix_event_emitter.h | 6 - code/nel/src/3d/driver_user.cpp | 30 - code/nel/src/misc/di_event_emitter.cpp | 354 --------- code/nel/src/misc/di_game_device.cpp | 523 ------------- code/nel/src/misc/di_game_device.h | 170 ----- code/nel/src/misc/di_keyboard_device.cpp | 686 ------------------ code/nel/src/misc/di_keyboard_device.h | 163 ----- code/nel/src/misc/di_mouse_device.cpp | 507 ------------- code/nel/src/misc/di_mouse_device.h | 167 ----- code/nel/src/misc/event_emitter_multi.cpp | 5 - code/nel/src/misc/game_device.cpp | 28 - code/nel/src/misc/game_device_events.cpp | 33 - code/nel/src/misc/input_device.cpp | 31 - code/nel/src/misc/input_device_server.cpp | 109 --- code/nel/src/misc/keyboard_device.cpp | 36 - code/nel/src/misc/win_event_emitter.cpp | 10 +- .../plugins/object_viewer/graphics_viewport.h | 1 - code/ryzom/client/src/client_cfg.cpp | 23 +- code/ryzom/client/src/client_cfg.h | 4 +- code/ryzom/client/src/connection.cpp | 3 + code/ryzom/client/src/events_listener.cpp | 86 ++- code/ryzom/client/src/init.cpp | 28 - code/ryzom/client/src/init_main_loop.cpp | 3 + code/ryzom/client/src/input.cpp | 169 +---- .../interface_v3/input_handler_manager.cpp | 5 +- code/ryzom/client/src/login.cpp | 11 +- code/ryzom/client/src/main_loop.cpp | 20 +- .../ryzom/client/src/motion/user_controls.cpp | 33 +- code/ryzom/client/src/stdpch.h | 1 - 58 files changed, 162 insertions(+), 4253 deletions(-) delete mode 100644 code/nel/include/nel/misc/di_event_emitter.h delete mode 100644 code/nel/include/nel/misc/game_device.h delete mode 100644 code/nel/include/nel/misc/game_device_events.h delete mode 100644 code/nel/include/nel/misc/input_device.h delete mode 100644 code/nel/include/nel/misc/input_device_manager.h delete mode 100644 code/nel/include/nel/misc/input_device_server.h delete mode 100644 code/nel/include/nel/misc/keyboard_device.h delete mode 100644 code/nel/include/nel/misc/mouse_device.h delete mode 100644 code/nel/src/misc/di_event_emitter.cpp delete mode 100644 code/nel/src/misc/di_game_device.cpp delete mode 100644 code/nel/src/misc/di_game_device.h delete mode 100644 code/nel/src/misc/di_keyboard_device.cpp delete mode 100644 code/nel/src/misc/di_keyboard_device.h delete mode 100644 code/nel/src/misc/di_mouse_device.cpp delete mode 100644 code/nel/src/misc/di_mouse_device.h delete mode 100644 code/nel/src/misc/game_device.cpp delete mode 100644 code/nel/src/misc/game_device_events.cpp delete mode 100644 code/nel/src/misc/input_device.cpp delete mode 100644 code/nel/src/misc/input_device_server.cpp delete mode 100644 code/nel/src/misc/keyboard_device.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 022246838..8c7d0ef1c 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -42,9 +42,6 @@ namespace NLMISC { class IEventEmitter; -struct IMouseDevice; -struct IKeyboardDevice; -struct IInputDeviceManager; class CRect; class CLog; } @@ -259,7 +256,7 @@ public: virtual emptyProc getWindowProc() = 0; virtual NLMISC::IEventEmitter *getEventEmitter() = 0; - + /// Copy a string to system clipboard. virtual bool copyTextToClipboard(const ucstring &text) = 0; @@ -362,7 +359,7 @@ public: virtual void getDepthRange(float &znear, float &zfar) const = 0; // @} - + /// \name Textures // @{ @@ -434,7 +431,7 @@ public: * Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values. */ virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0; - + // [DEPRECATED] Return if this texture is a rectangle texture that requires RECT sampler (OpenGL specific pre-NPOT functionality) virtual bool isTextureRectangle(ITexture *tex) const = 0; @@ -442,7 +439,7 @@ public: virtual bool supportNonPowerOfTwoTextures() const = 0; // @} - + /// \name Texture operations // @{ @@ -536,7 +533,7 @@ public: virtual bool isForceNormalize() const = 0; // @} - + /// \name Vertex Buffer Hard: Features // @{ @@ -737,7 +734,7 @@ public: virtual uint getSwapVBLInterval() = 0; // @} - + @@ -869,25 +866,6 @@ public: /// x and y must be between 0.0 and 1.0 virtual void setMousePos(float x, float y) = 0; - /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) - * It returns a interface to these parameters when it is supported, or NULL otherwise - * The interface pointer is valid as long as the low level mouse is enabled. - * A call to disable the mouse returns NULL, and restore the default mouse behavior - * NB : - In this mode the mouse cursor isn't drawn. - * - Calls to showCursor have no effects - * - Calls to setCapture have no effects - */ - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0; - - /** Enable / disable a low level keyboard. - * Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a - * gamepad with lots of buttons... - * This returns a interface to some parameters when it is supported, or NULL otherwise. - * The interface pointer is valid as long as the low level keyboard is enabled. - * A call to disable the keyboard returns NULL, and restore the default keyboard behavior - */ - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; - /** Get the delay in ms for mouse double clicks. */ virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; @@ -908,11 +886,6 @@ public: // Change default scale for all cursors virtual void setCursorScale(float scale) = 0; - - /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available - * From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...) - */ - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; // @} @@ -1106,7 +1079,7 @@ public: virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const = 0; /** Compile the given vertex program, return if successful. - * If a vertex program was set active before compilation, + * If a vertex program was set active before compilation, * the state of the active vertex program is undefined behaviour afterwards. */ virtual bool compileVertexProgram(CVertexProgram *program) = 0; @@ -1133,7 +1106,7 @@ public: virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0; /** Compile the given pixel program, return if successful. - * If a pixel program was set active before compilation, + * If a pixel program was set active before compilation, * the state of the active pixel program is undefined behaviour afterwards. */ virtual bool compilePixelProgram(CPixelProgram *program) = 0; @@ -1160,7 +1133,7 @@ public: virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const = 0; /** Compile the given pixel program, return if successful. - * If a pixel program was set active before compilation, + * If a pixel program was set active before compilation, * the state of the active pixel program is undefined behaviour afterwards. */ virtual bool compileGeometryProgram(CGeometryProgram *program) = 0; diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index ff9ba8973..30abc518f 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -410,21 +410,6 @@ public: virtual bool fillBuffer (CBitmap &bitmap); // @} - - /// \name Mouse / Keyboards / Game devices - // @{ - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive); - // - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable); - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager(); - - /** - * wrapper for IEventEmitter::emulateMouseRawMode() - */ - virtual void emulateMouseRawMode(bool enable); - - virtual uint getDoubleClickDelay(bool hardwareMouse); - /// show cursor if b is true, or hide it if b is false virtual void showCursor (bool b); /// x and y must be between 0.0 and 1.0 diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index 67e0c30fd..8af6091e3 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -556,36 +556,6 @@ public: /// \name Mouse / Keyboard / Gamedevices // @{ - /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) - * It returns a interface to these parameters when it is supported, or NULL otherwise - * The interface pointer is valid as long as the low level mouse is enabled. - * A call to disable the mouse returns NULL, and restore the default mouse behaviour - * NB : - In this mode the mouse cursor isn't drawn. - * - Calls to showCursor have no effects - * - Calls to setCapture have no effects - */ - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool hardware) = 0; - - /** Enable / disable a low level keyboard. - * This returns a interface to some parameters when it is supported, or NULL otherwise. - * The interface pointer is valid as long as the low level keyboard is enabled. - * A call to disable the keyboard returns NULL, and restore the default keyboard behaviour. - */ - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; - - /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available. - * From this interface you can deal with mouse and keyboard as above, but you can also manage game devices (joysticks, joypads ...) - */ - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; - - /** - * wrapper for IEventEmitter::emulateMouseRawMode() - */ - virtual void emulateMouseRawMode(bool enable) = 0; - - // get delay used for mouse double click - virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; - /** show cursor if b is true, or hide it if b is false * NB: This has no effects if a low level mouse is used. */ diff --git a/code/nel/include/nel/misc/di_event_emitter.h b/code/nel/include/nel/misc/di_event_emitter.h deleted file mode 100644 index 41c7bbf47..000000000 --- a/code/nel/include/nel/misc/di_event_emitter.h +++ /dev/null @@ -1,204 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_DI_EVENT_EMITTER_H -#define NL_DI_EVENT_EMITTER_H - - - -#include "types_nl.h" - - -#ifdef NL_OS_WINDOWS - - -#define DIRECTINPUT_VERSION 0x0800 - -#include "input_device_server.h" -#include "input_device_manager.h" -#include "event_emitter.h" -#include "smart_ptr.h" -#include "events.h" -#include "rect.h" -#include "game_device.h" -#ifndef NL_COMP_MINGW -# define NOMINMAX -#endif -#include -#include - - - -namespace NLMISC -{ - - -class CWinEventEmitter; -class CDIKeyboard; -class CDIMouse; -struct IMouseDevice; -struct IKeyboardDevice; - -// -struct EDirectInput : public EInputDevice -{ - EDirectInput(const char *reason) : EInputDevice(reason) {} -}; -// -struct EDirectInputLibNotFound : public EDirectInput -{ - EDirectInputLibNotFound() : EDirectInput("can't found the direct input dll") {} -}; -// -struct EDirectInputInitFailed : public EDirectInput -{ - EDirectInputInitFailed() : EDirectInput("Direct input initialization failed") {} -}; -// -struct EDirectInputCooperativeLevelFailed : public EDirectInput -{ - EDirectInputCooperativeLevelFailed() : EDirectInput("Direct Input Device Cooperative level couldn't be set") {} -}; - - -// Class to represent Direct Inputs events -struct CDIEvent : public IInputDeviceEvent -{ - virtual bool operator < (const IInputDeviceEvent &ide) const - { - // just compare the dates - return Datas.dwTimeStamp < (safe_cast(&ide))->Datas.dwTimeStamp; - } - DIDEVICEOBJECTDATA Datas; -}; - -/** - * This manage events by using DirectInput8. - * This should be polled regularly. - * This can be mixed with a CWinEmitter (for example, you may have mouse using direct input, and keyboard using standard messages) - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ -class CDIEventEmitter : public IEventEmitter, public IInputDeviceManager -{ -public: - /** Build a Direct Input Event Emitter object. An exception containing the reason is thrown if the initialization failed. - * The obtained object must be released by deleting it. - * \param hinst the instance of the application. - * \param hwnd the main window of the application. - * \param we A windows eventsemitter. Can be NULL. Needed if you want to mix WIN32 events and Direct Input events - * (for example, a Direct Input Mouse and a Win32 Keyboard) - */ - static CDIEventEmitter *create(HINSTANCE hinst, HWND hwnd, CWinEventEmitter *we) throw(EDirectInput); - ~CDIEventEmitter(); -public: - - /// This poll the direct input state, directly storing the result in the given server, or keeping the result in internal server if NULL. - void poll(CEventServer *server = NULL); - - ///\name From IDeviceManager, access to devices - //@{ - // Test if a mouse has been created (by a call to getMouseDeivce) - virtual bool isMouseCreated() { return _Mouse != NULL; } - /** Create the mouse device if needed (one active at a time for that object, repeated calls returns the same pointer) and get an interface on it. An exception if thrown if it couldn't be obtained. - * If this object has a pointer on a win32 emiter, Win32 mouse messages are replaced by this mouse messages. - */ - virtual IMouseDevice *getMouseDevice(bool hardware) throw(EInputDevice); - /// remove the direct input mouse - virtual void releaseMouse(); - /** Create the keyboard device if needed (one active at a time for that object, repeated calls returns the same pointer) and get an interface on it. - * If this object has a pointer on a win32 emiter, Win32 keyboard messages are replaced by this keyboard messages. - * NB: A direct input has no notion of localization or key combinations. See keyboard_device.h for more infos - */ - virtual IKeyboardDevice *getKeyboardDevice() throw(EInputDevice); - /// remove the direct input keyboard - virtual void releaseKeyboard(); - // Enumerates current game devices (gamepads, joystick etc.). The result is stored in the given vector - virtual void enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice); - // Create the given game device from its instance name. It also means that it will begin to sends inputs - virtual IGameDevice *createGameDevice(const std::string &instanceName) throw(EInputDevice); - // Release the given game device - virtual void releaseGameDevice(IGameDevice *); - //@} - - /// from IEventEmitter - virtual void submitEvents(CEventServer &server, bool allWindows); - virtual void emulateMouseRawMode(bool enable); - - // Build a TMouseButton value from the current buttons state - TMouseButton buildButtonsFlags() const; - // Build a TMouseButton value (but with no mouse values) - TMouseButton buildKeyboardButtonFlags() const - { - return (TMouseButton) (buildButtonsFlags() & (ctrlButton|shiftButton|altButton)); - } - -//================================================================ -//================================================================ -//================================================================ -private: - typedef HRESULT (WINAPI * TPDirectInput8Create) (HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter); - // Private internal server message, used to stored all messages internally before to dispatch them, when no server is supplied to poll(... - class CDIEventServer : CEventServer - { - friend class CDIEventEmitter; - public: - void setServer (CEventServer *server) - { - _Server = server; - } - private: - bool pumpEvent(CEvent *event) - { - CEventServer::pumpEvent(event); - _Server->postEvent (event); - return false; - } - private: - CEventServer *_Server; - }; -private: - HWND _hWnd; - TMouseButton _ButtonsFlags; - NLMISC::CRefPtr _WE; - static HMODULE _DirectInputLibHandle; - static TPDirectInput8Create _PDirectInput8Create; - static uint _NumCreatedInterfaces; -private: - static bool loadLib(); - static void unloadLib(); -//==== -private: - CDIEventServer _InternalServer; - CInputDeviceServer _DeviceServer; - IDirectInput8 *_DInput8; - CDIMouse *_Mouse; - CDIKeyboard *_Keyboard; -private: - CDIEventEmitter(HWND hwnd, CWinEventEmitter *we); -}; - - - -} // NLMISC - -#endif // NL_WINDOWS - - -#endif // NL_DX_EVENT_EMITTER_H - -/* End of dx_event_emitter.h */ diff --git a/code/nel/include/nel/misc/event_emitter.h b/code/nel/include/nel/misc/event_emitter.h index 224e5159f..eab005b82 100644 --- a/code/nel/include/nel/misc/event_emitter.h +++ b/code/nel/include/nel/misc/event_emitter.h @@ -49,19 +49,6 @@ public: * \param server */ virtual void submitEvents(CEventServer & server, bool allWindows) = 0; - - /** - * Instruct the event emitter to send CGDMouseMove instead of CEventMouseMove. - * - * On windows, the mouse device can be set into RawMode. Using this mode, - * CGDMouseMove events (only containing the raw movement delta) are emitted - * instead of the normal CEventMouseMove events (containing the mouse position). - * - * On Linux and Mac OS X, there is no MouseDevice implementation, all the - * events are created by the event emitter. So the event emitter has to - * emulate the mouse raw mode. - */ - virtual void emulateMouseRawMode(bool) = 0; }; diff --git a/code/nel/include/nel/misc/event_emitter_multi.h b/code/nel/include/nel/misc/event_emitter_multi.h index 3c6860e53..e41ee2055 100644 --- a/code/nel/include/nel/misc/event_emitter_multi.h +++ b/code/nel/include/nel/misc/event_emitter_multi.h @@ -47,7 +47,6 @@ public: const IEventEmitter *getEmitter(uint index) const; /// From IEventEmitter. This call submitEvents on all the emitters virtual void submitEvents(CEventServer &server, bool allWindows); - virtual void emulateMouseRawMode(bool enable); virtual bool copyTextToClipboard(const ucstring &text); virtual bool pasteTextFromClipboard(ucstring &text); diff --git a/code/nel/include/nel/misc/game_device.h b/code/nel/include/nel/misc/game_device.h deleted file mode 100644 index 605c4fb53..000000000 --- a/code/nel/include/nel/misc/game_device.h +++ /dev/null @@ -1,114 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_GAME_DEVICE_H -#define NL_GAME_DEVICE_H - -#include "types_nl.h" -#include "input_device.h" -#include -#include - - -namespace NLMISC -{ - -/// Describe a game device -struct CGameDeviceDesc -{ - // type of the device - enum TDevType { GamePad, Joystick, DontKnow, DevTypeLast } DevType; - // Friendly name for the instance. For example, "Joystick 1." - std::string InstanceName; - // Friendly name for the product - std::string ProductName; - // Tells whether this device is connected - bool Connected; -}; - -// a list of game device description -typedef std::vector TDeviceDescVect; - -/// for devices comparison. The 'Connected' field is ignored. -inline bool operator == (const CGameDeviceDesc &lhs, const CGameDeviceDesc &rhs) -{ - return lhs.InstanceName == rhs.InstanceName && lhs.ProductName == rhs.ProductName; -} -// -inline bool operator != (const CGameDeviceDesc &lhs, const CGameDeviceDesc &rhs) -{ - return !(lhs == rhs); -} - - -/** - * This abstract a joystick or gamepad - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ -struct IGameDevice : public IInputDevice -{ - enum TAxis { XAxis = 0, YAxis, ZAxis, /* translation */ - RXAxis, RYAxis, RZAxis, /* rotations */ - MaxNumAxis - }; - - /// Get a general description of this device - virtual const CGameDeviceDesc &getDescription() const = 0; - - ///\name Controls presence - //@{ - // returns the number of buttons available on this game device - virtual uint getNumButtons() const = 0; - /** Check if the given axe is present on this game device - * NB : only absolute axis are managed - */ - virtual bool hasAxis(TAxis axis) const = 0; - // Check the number of sliders presents on this game device - virtual uint getNumSliders() const = 0; - // Check the number of point of views controls present on this game device - virtual uint getNumPOV() const = 0; - //@} - - ///\name Controls names. Must ensure that controls are present before calling these methods. - //@{ - virtual const char *getButtonName(uint index) const = 0; - virtual const char *getAxisName(TAxis axis) const = 0; - virtual const char *getSliderName(uint index) const = 0; - virtual const char *getPOVName(uint index) const = 0; - //@} - - ///\name Controls state. Must ensure that controls are present before calling these methods. - //@{ - // Return true if the given button is pushed. - virtual bool getButtonState(uint index) const = 0; - // Return a value in [-1, 1] for a translation axis, or an orientation. - virtual float getAxisValue(TAxis axis) const = 0; - // Return a value in [0, 1] - virtual float getSliderPos(uint index) const = 0; - // Return a CCW angle in degrees - virtual float getPOVAngle(uint index) const = 0; - //@} -}; - - -} // NLMISC - - -#endif // NL_GAME_DEVICE_H - -/* End of GAME_device.h */ diff --git a/code/nel/include/nel/misc/game_device_events.h b/code/nel/include/nel/misc/game_device_events.h deleted file mode 100644 index 6ddee4589..000000000 --- a/code/nel/include/nel/misc/game_device_events.h +++ /dev/null @@ -1,209 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_GAME_DEVICE_EVENT_H -#define NL_GAME_DEVICE_EVENT_H - -#include "types_nl.h" -#include "events.h" -#include "game_device.h" - - - - -namespace NLMISC -{ - -struct IMouseDevice; -struct IGameDevice; - -const CClassId EventGDMouseMove(0x12142bc4, 0x43c73e74); -const CClassId EventGDButtonDownId(0x57141957, 0x3efb143a); -const CClassId EventGDButtonUpId(0x16105e06, 0x302536b2); -const CClassId EventGDAxisMovedId(0x073306, 0x41173626); -const CClassId EventGDSliderMovedId(0x68776586, 0x394a6916); -const CClassId EventGDPOVChanged(0x362851b9, 0x395c4d61); - - -//========================================================================================== -/// A raw mouse move message, expressed in mickeys (relative values) -class CGDMouseMove : public CEvent -{ -public: - IMouseDevice *MD; - sint X, Y; -public: - CGDMouseMove(IEventEmitter *emitter, IMouseDevice *md, sint x, sint y) : CEvent(emitter, EventGDMouseMove), MD(md), X(x), Y(y) - {} - - virtual CEvent *clone() const {return new CGDMouseMove(*this);} -}; - - -//========================================================================================== -/** - * An event from a game device (joystick, joypad ...) - */ -class CGameDeviceEvent : public CEvent -{ -public: - /// the game device this event come from - IGameDevice *GameDevice; -public: - CGameDeviceEvent( - IGameDevice *gameDevice, - IEventEmitter *emitter, - const CClassId &classId - ) - : CEvent(emitter, classId), - GameDevice(gameDevice) - {} -}; - - -//========================================================================================== -/** A button state has changed - */ -class CGDButton : public CGameDeviceEvent -{ -public: - // index of the buttons that has been pushed - uint ButtonIndex; - bool Pushed; -public: - /// - CGDButton( - uint buttonIndex, - bool pushed, - IGameDevice *gameDevice, - IEventEmitter *emitter, - const CClassId &classId - ) - : CGameDeviceEvent(gameDevice, emitter, classId), - ButtonIndex(buttonIndex), - Pushed(pushed) - {} -}; - - -//========================================================================================== -/** A button has been pushed - */ -class CGDButtonDown : public CGDButton -{ -public: - /// - CGDButtonDown(uint buttonIndex, IGameDevice *gameDevice, IEventEmitter *emitter) - : CGDButton(buttonIndex, true, gameDevice, emitter, EventGDButtonDownId) - {} - - virtual CEvent *clone() const {return new CGDButtonDown(*this);} -}; - -//========================================================================================== -/** A button has been released - */ -class CGDButtonUp : public CGDButton -{ -public: - /// - CGDButtonUp(uint buttonIndex, IGameDevice *gameDevice, IEventEmitter *emitter) - : CGDButton(buttonIndex, false, gameDevice, emitter, EventGDButtonUpId) - {} - - virtual CEvent *clone() const {return new CGDButtonUp(*this);} -}; - -//========================================================================================== -/// An axis has moved -class CGDAxisMoved : public CGameDeviceEvent -{ -public: - IGameDevice::TAxis Axis; - // current position of the axis, ranges from -1.f to 1.f - float Value; -public: - CGDAxisMoved( - IGameDevice::TAxis axis, - float value, - IGameDevice *gameDevice, - IEventEmitter *emitter - ) - : CGameDeviceEvent(gameDevice, emitter, EventGDAxisMovedId), - Axis(axis), - Value(value) - {} - - virtual CEvent *clone() const {return new CGDAxisMoved(*this);} -}; - - -//========================================================================================== -/// A slider position has changed -class CGDSliderMoved : public CGameDeviceEvent -{ -public: - uint SliderIndex; - // current position of the slider, ranges from 0.f to 1.f - float SliderPos; -public: - CGDSliderMoved( - float sliderPos, - uint sliderIndex, - IGameDevice *gameDevice, - IEventEmitter *emitter - ) - : CGameDeviceEvent(gameDevice, emitter, EventGDSliderMovedId), - SliderIndex(sliderIndex), - SliderPos(sliderPos) - {} - - virtual CEvent *clone() const {return new CGDSliderMoved(*this);} -}; - -//========================================================================================== -/// A point of view control changed -class CGDPOVChanged : public CGameDeviceEvent -{ -public: - uint POVIndex; - bool Centered; - // The POV angle, in degrees (CW) - float POVAngle; -public: - CGDPOVChanged( - bool centered, - float povAngle, - uint povIndex, - IGameDevice *gameDevice, - IEventEmitter *emitter - ) - : CGameDeviceEvent(gameDevice, emitter, EventGDPOVChanged), - POVIndex(povIndex), - Centered(centered), - POVAngle(povAngle) - {} - - virtual CEvent *clone() const {return new CGDPOVChanged(*this);} -}; - - -} // NLMISC - - -#endif // NL_GAME_DEVICE_EVENT_H - -/* End of game_device_event.h */ diff --git a/code/nel/include/nel/misc/input_device.h b/code/nel/include/nel/misc/input_device.h deleted file mode 100644 index b07a0128e..000000000 --- a/code/nel/include/nel/misc/input_device.h +++ /dev/null @@ -1,84 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_INPUT_DEVICE_H -#define NL_INPUT_DEVICE_H - -#include "types_nl.h" - - -namespace NLMISC -{ - - -class CEventServer; -class CInputDeviceServer; -struct IInputDeviceEvent; - - -/** - * Base class that wrap to a device - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ - -struct IInputDevice -{ - /** Set the buffer size for this device (the number of samples it can retains). - * This return true if the size could be set - */ - virtual bool setBufferSize(uint size) = 0; - /// Get the buffer size for this device - virtual uint getBufferSize() const = 0; - - ///\name Device server specifics. You usually don't want to call these - //@{ - /** For device server usage : - * Called at the beginning of each events retrieval. - * If a device doesn't support buffered datas, the state changes can be directly send to the event server. - * The default does nothing. - */ - virtual void begin(CEventServer * /* server */) {} - - /** For device server usage : - * Poll all events from that device, and notify them to the given device server, so that they can be sorted between devices. - * This retrieves messages, but do not process them. - */ - virtual void poll(CInputDeviceServer *dev) = 0; - /** For device server usage : - * Process an event (eventually update this device state), and translate the message to a IEventServerMessage - */ - virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server) = 0; - /** For device server usage : - * Says that the next message is for another device, or that it is the last message that will be received. - * This allow to pack several messages in one (for example, to sum up mouse moves until a click occurs) - * The default does nothing. - * The next message can be used to get a time stamp for example. It may be NULL is no next message is available - */ - virtual void transitionOccured(CEventServer * /* server */, const IInputDeviceEvent * /* nextMessage */) {} - //@} - - // dtor - virtual ~IInputDevice() {} -}; - -} // NLMISC - - -#endif // NL_INPUT_DEVICE_H - -/* End of input_device.h */ diff --git a/code/nel/include/nel/misc/input_device_manager.h b/code/nel/include/nel/misc/input_device_manager.h deleted file mode 100644 index a23437696..000000000 --- a/code/nel/include/nel/misc/input_device_manager.h +++ /dev/null @@ -1,69 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_INPUT_DEVICE_MANAGER_H -#define NL_INPUT_DEVICE_MANAGER_H - -#include "types_nl.h" -#include "game_device.h" -#include "common.h" - -namespace NLMISC -{ - - -struct IMouseDevice; -struct IKeyboardDevice; - - - -struct EInputDevice : public Exception -{ - EInputDevice(const char *reason) : Exception(reason) {} -}; - - -/** Interface for objects that give low level access to devices (mouse, keyboard, joypads and joysticks). - * Generally an object implementing this interface will send the appropriate events when a device is 'created'. - * (Example of implementation : a direct input event emitter) - */ -struct IInputDeviceManager -{ - // Test if a mouse has been created (by a call to getMouseDeivce) - virtual bool isMouseCreated() = 0; - /// Create the low level mouse device if needed (one active at a time for that object, repeated calls returns the same pointer). An exception if thrown if it couldn't be obtained. - virtual IMouseDevice *getMouseDevice(bool hardware) throw(EInputDevice) = 0; - /// remove the low level mouse - virtual void releaseMouse() = 0; - /// Create the low level keyboard device if needed (one active at a time for that object, repeated calls returns the same pointer). An exception if thrown if it couldn't be obtained. - virtual IKeyboardDevice *getKeyboardDevice() throw(EInputDevice) = 0; - /// remove the low level keyboard - virtual void releaseKeyboard() = 0; - // Enumerates current game devices (gamepads, joystick etc.). The result is stored in the given vector - virtual void enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice) = 0; - // Create the given game device interface from its instance name. It also means that it will begin to sends events. - virtual IGameDevice *createGameDevice(const std::string &instanceName) throw(EInputDevice) = 0; - // Release the given game device. - virtual void releaseGameDevice(IGameDevice *gd) = 0; -}; - - -} // NLMISC - - -#endif // NL_INPUT_DEVICE_MANAGER_H - -/* End of device_manager.h */ diff --git a/code/nel/include/nel/misc/input_device_server.h b/code/nel/include/nel/misc/input_device_server.h deleted file mode 100644 index 45c3db77d..000000000 --- a/code/nel/include/nel/misc/input_device_server.h +++ /dev/null @@ -1,84 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_INPUT_DEVICE_SERVER_H -#define NL_INPUT_DEVICE_SERVER_H - -#include "types_nl.h" -#include - - -namespace NLMISC -{ - -class CEventServer; -struct IInputDevice; -struct IInputDeviceEvent; - - -/** Base class for an input device server. Unlike an event server, it manages several devices, and can sort their events (by date for example). - * It keeps a list of active devices. - * It can poll datas from every active device. - * It can sort devices messages to submit them in correct order to a CEventServer. - */ - -class CInputDeviceServer -{ -public: - /// register a device into this device server. - void registerDevice(IInputDevice *device); - /// remove a device from this server (but does not delete it). - void removeDevice(IInputDevice *device); - // returns the number of registered devices - uint getNumDevices() const { return (uint)_Devices.size(); } - // return a device - IInputDevice *getDevice(uint index) { return _Devices[index]; } - /// Test whether the given device is handled by this server. - bool isDevice(IInputDevice *device) const; - /// Retrieve datas from the devices, and submit them to the given CEventServer. - void poll(CEventServer *server); - /// Allow an input device to register an event. The event will then be deleted by this server - void submitEvent(IInputDeviceEvent *deviceEvent); - // dtor - virtual ~CInputDeviceServer() {} -private: - typedef std::vector TDeviceCont; - typedef std::vector TEventCont; -private: - TDeviceCont _Devices; - TEventCont _Events; -}; - - - - -/** An event from an input device. - */ -struct IInputDeviceEvent -{ - IInputDevice *Emitter; // the input device that emitted that event - // Used to sort events by time stamp. - virtual bool operator < (const IInputDeviceEvent &IInputDeviceEvent) const = 0; - virtual ~IInputDeviceEvent() {} -}; - - -} // NLMISC - - -#endif // NL_INPUT_DEVICE_SERVER_H - -/* End of input_device_server.h */ diff --git a/code/nel/include/nel/misc/keyboard_device.h b/code/nel/include/nel/misc/keyboard_device.h deleted file mode 100644 index bf3b2af8d..000000000 --- a/code/nel/include/nel/misc/keyboard_device.h +++ /dev/null @@ -1,63 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_KEYBOARD_DEVICE_H -#define NL_KEYBOARD_DEVICE_H - -#include "types_nl.h" -#include "events.h" -#include "input_device.h" - - - -namespace NLMISC -{ - -/** Gives access to low level keyboard parameters - * - 'Shift' messages are replaced by RShift and LShift msg. - * - 'Control' messages are replaced by 'RControl' and 'LControl' msg. - * - 'Menu' (alternate) messages are replaced by 'RMenu' and 'LMenu' msg. - */ -struct IKeyboardDevice : public IInputDevice -{ - /// Max number of supported keys - enum { NumKeys = 256 }; - /// Get the delay before key repeat, in milliseconds - virtual uint getKeyRepeatDelay() const = 0; - /// Get the delay before key repeat, in milliseconds - virtual void setKeyRepeatDelay(uint delay) = 0; - /// Get the period before key repeat, in milliseconds - virtual uint getKeyRepeatPeriod() const = 0; - /// Get the period before key repeat, in milliseconds - virtual void setKeyRepeatPeriod(uint period) = 0; - /// Set a set of keys for which repetition is disabled - virtual void disableRepetition(const TKey *keyTab, uint numKey) = 0; - /// Get the number of disabled keys - virtual uint getNumDisabledRepetition() const = 0; - /** Get the disabled keys and stores in the given tab. - * NB: must ensure the destination table has the right size - * \see getNumDisabledKeys() - */ - virtual void getDisabledRepetitions(TKey *destTab) const = 0; -}; - - -} // NLMISC - - -#endif // NL_KEYBOARD_DEVICE_H - -/* End of keyboard_device.h */ diff --git a/code/nel/include/nel/misc/mouse_device.h b/code/nel/include/nel/misc/mouse_device.h deleted file mode 100644 index 8ae181cdd..000000000 --- a/code/nel/include/nel/misc/mouse_device.h +++ /dev/null @@ -1,130 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_MOUSE_DEVICE_H -#define NL_MOUSE_DEVICE_H - -#include "types_nl.h" -#include "input_device.h" - - - -namespace NLMISC -{ - -class CRect; - -/// An interface to a low level mouse device -struct IMouseDevice : public IInputDevice -{ - enum TAxisMode { Raw, Clamped, AxisModeLast }; - enum TAxis { XAxis = 0, YAxis = 1, AxisLast }; - enum TMessageMode { NormalMode, RawMode, MessageModeLast }; - - ///\name Messages - //@{ - /** Tells what messages should be sent : - * DEFAULT is 'raw' messages - * Raw messages : - no clamping nor frames applied - * - no speed applied - * - no factor applied - * - CGDMouseMove messages are sent - * - Move expressed in mickeys - * Normal messages : - CEventMouseMove messages are sent - * - A frame may clamp one or both axis - * - The mouse speed can be changed - */ - virtual void setMessagesMode(TMessageMode mode) = 0; - /// retrieve what kinds of messages are sent - virtual TMessageMode getMessagesMode() const = 0; - //@} - - ///\name Mouse MOVE, valid only - //@{ - /** Set the mode of axis of the mouse. This can be raw, or clamped. In clamped mode, a frame is used to limit the move. - * NB : invalid in raw message mode - * \see setMouseFrame(const CRect &rect) - */ - virtual void setMouseMode(TAxis axis, TAxisMode axisMode) = 0; - /** returns the mode of the mouse for the given axis. - * NB : invalid in raw message mode - */ - virtual TAxisMode getMouseMode(TAxis axis) const = 0; - /** Set the mouse speed. It must be in the ]0, +inf] range, 1 gives the natural mouse speed. - * NB : invalid in raw message mode - */ - virtual void setMouseSpeed(float speed) = 0; - /** Get the mouse speed. - * NB : invalid in raw message mode - */ - virtual float getMouseSpeed() const = 0; - /** Set the mouse acceleration. It is the threshold in mickey, when start the acceleration. 0 means not acceleration. - */ - virtual void setMouseAcceleration(uint speed) = 0; - /** Get the mouse acceleration. - */ - virtual uint getMouseAcceleration() const = 0; - /** Set the current frame in which the mouse can move, expressed in pixels. - * NB do not forget to call setMouseFactors if you want the results to be reported in the 0-1 range. - * NB : invalid in raw message mode. - * \see setMouseFactors - */ - virtual void setMouseFrame(const CRect &rect) = 0; - /** Gives factor by which the mouse coordinates must be multiplied before an event is sent. - * The default factor is 1. - * NB : invalid in raw message mode. - * - * Example : this set a frame of 800x600 and reports event in the [0, 1] range. - * \code - * mouse->setMouseFrame(800, 600); - * mouse->setMouseMode(XAxis, IMouseDevice::Clamped); - * mouse->setMouseMode(YAxis, IMouseDevice::Clamped); - * mouse->setFactors(1.f / 800, 1.f / 600); - * \endcode - */ - virtual void setFactors(float xFactor, float yFactor) = 0; - /** Get the x factor, use to multiply the mouse position before an event is sent. - * NB : invalid in raw message mode. - * \see setFactors() - */ - virtual float getXFactor() const = 0; - /** Get the y factor, use to multiply the mouse position before an event is sent. - * NB : invalid in raw message mode. - * \see setFactors() - */ - virtual float getYFactor() const = 0; - //@} - - // Get the current frame used for limiting mouse movements - virtual const CRect &getMouseFrame() const = 0; - // Set the maximum delay for a double click to be taken in account (in ms). - virtual void setDoubleClickDelay(uint ms) = 0; - // Get the maximum delay for double click (in ms) - virtual uint getDoubleClickDelay() const = 0; - // Force the position of the mouse, expressed in pixels - virtual void setMousePos(float x, float y) = 0; - - /// From a delta of a mouse position input (eg from CEventMouseMove), deduce delta in mickeys (eg: like received from a CGDMouseMove) - virtual void convertStdMouseMoveInMickeys(float &dx, float &dy) const = 0; -}; - - -} // NLMISC - - -#endif // NL_MOUSE_DEVICE_H - -/* End of u_mouse_device.h */ diff --git a/code/nel/include/nel/misc/win_event_emitter.h b/code/nel/include/nel/misc/win_event_emitter.h index 756dfbaee..1b361485f 100644 --- a/code/nel/include/nel/misc/win_event_emitter.h +++ b/code/nel/include/nel/misc/win_event_emitter.h @@ -100,8 +100,6 @@ public: */ bool processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPARAM lParam, CEventServer *server=NULL); - void emulateMouseRawMode(bool enable); - private: CWinEventServer _InternalServer; HWND _HWnd; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 2316119a2..96937fa94 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -25,8 +25,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/misc/dynloadlib.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" @@ -1478,7 +1476,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r D3DADAPTER_IDENTIFIER9 Identifier; HRESULT Res; Res = _D3D->GetAdapterIdentifier(gAdapter,0,&Identifier); - + if (strstr(Identifier.Description,"PerfHUD") != 0) { nlinfo ("Setting up with PerfHUD"); @@ -1512,7 +1510,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r } - + // _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶meters, &_DeviceInterface); // Check some caps diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_index.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_index.cpp index 20d59725c..b75a21d9d 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_index.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_index.cpp @@ -19,8 +19,6 @@ #include "nel/3d/index_buffer.h" #include "nel/3d/light.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp index 4949e2fd8..dbfcd155a 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp @@ -17,9 +17,6 @@ #include "stddirect3d.h" #include "driver_direct3d.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" - using namespace std; using namespace NLMISC; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_light.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_light.cpp index 4ad5b46c0..d3bb62e64 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_light.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_light.cpp @@ -20,8 +20,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index 40d01039b..f22cba111 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -21,8 +21,6 @@ #include "nel/3d/index_buffer.h" #include "nel/3d/texture_bump.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" @@ -648,7 +646,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader == CMaterial::Normal + if (matShader == CMaterial::Normal || ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages)) ) { @@ -670,7 +668,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) // Don't do it also for Specular because the EnvFunction and the TexGen may be special. { H_AUTO_D3D(CDriverD3D_setupMaterial_normalShaderActivateTextures) - if (matShader == CMaterial::Normal + if (matShader == CMaterial::Normal || ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages)) ) { diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_matrix.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_matrix.cpp index 87b047476..c5b479de0 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_matrix.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_matrix.cpp @@ -20,8 +20,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_render.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_render.cpp index 313fb2344..939dc1dc9 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_render.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_render.cpp @@ -20,8 +20,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/misc/fast_mem.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp index 2995c5b4c..ad5de53c1 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp @@ -20,8 +20,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex.cpp index b798acb26..d37c272a2 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex.cpp @@ -20,8 +20,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/3d/viewport.h" #include "nel/3d/scissor.h" #include "nel/3d/u_driver.h" diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index eb59f2205..a6e3ad7b7 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -28,8 +28,6 @@ #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" #include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/mouse_device.h" #include "nel/misc/hierarchical_timer.h" #include "nel/misc/dynloadlib.h" #include "driver_opengl_vertex_buffer_hard.h" @@ -483,7 +481,7 @@ bool CDriverGL::setupDisplay() glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT); #endif } - + if (_Extensions.ARBFragmentShader) { _ForceNativeFragmentPrograms = false; @@ -1509,7 +1507,7 @@ void CDriverGL::enableUsedTextureMemorySum (bool enable) H_AUTO_OGL(CDriverGL_enableUsedTextureMemorySum ) if (enable) - { + { nlinfo ("3D: PERFORMANCE INFO: enableUsedTextureMemorySum has been set to true in CDriverGL"); _TextureUsed.reserve(512); } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp index d1cd1fb60..92b25baf4 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp @@ -27,8 +27,6 @@ # endif // HAVE_XCURSOR #endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC) -#include "nel/misc/mouse_device.h" -#include "nel/misc/di_event_emitter.h" #include "nel/3d/u_driver.h" #include "nel/misc/file.h" diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 2fea530cf..e377554d0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -38,8 +38,6 @@ # define _NET_WM_STATE_ADD 1 #endif // NL_OS_UNIX -#include "nel/misc/mouse_device.h" -#include "nel/misc/di_event_emitter.h" #include "nel/3d/u_driver.h" #include "nel/misc/file.h" @@ -255,7 +253,7 @@ bool GlWndProc(CDriverGL *driver, XEvent &e) unsigned long nitems_return = 0; unsigned long bytes_after_return = 0; long *data = NULL; - + int status = XGetWindowProperty(driver->_dpy, driver->_win, XA_FRAME_EXTENTS, 0, 4, False, XA_CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, (unsigned char**)&data); // succeeded to retrieve decoration size @@ -270,7 +268,7 @@ bool GlWndProc(CDriverGL *driver, XEvent &e) driver->_DecorationWidth = e.xconfigure.x - driver->_WindowX; driver->_DecorationHeight = e.xconfigure.y - driver->_WindowY; } - + // don't allow negative decoration sizes if (driver->_DecorationWidth < 0) driver->_DecorationWidth = 0; if (driver->_DecorationHeight < 0) driver->_DecorationHeight = 0; @@ -2469,7 +2467,7 @@ bool CDriverGL::createContext() if (_EglContext == EGL_NO_CONTEXT) { return false; - } + } // Make the context current if (!eglMakeCurrent(_EglDisplay, _EglSurface, _EglSurface, _EglContext)) diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h index 7e46fc6de..aa7d591fd 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h @@ -20,14 +20,13 @@ #include "nel/misc/event_emitter.h" #include "nel/misc/event_server.h" #include "nel/misc/events.h" -#include "nel/misc/game_device_events.h" #include "nel/3d/driver.h" #import "cocoa_opengl_view.h" #include #import -namespace NLMISC +namespace NLMISC { class CCocoaEventEmitter : public IEventEmitter @@ -42,8 +41,8 @@ class CCocoaEventEmitter : public IEventEmitter CEventServer* _server; public: - CCocoaEventEmitter() : - _emulateRawMode(false), + CCocoaEventEmitter() : + _emulateRawMode(false), _setToEmulateRawMode(false), _driver(NULL), _glView(nil), @@ -52,7 +51,6 @@ public: void init(NL3D::IDriver*, CocoaOpenGLView*, bool eventLoop); bool processMessage(NSEvent* event, CEventServer* server = NULL); virtual void submitEvents(CEventServer& server, bool allWindows); - virtual void emulateMouseRawMode(bool enable); bool handleQuitRequest(); virtual bool copyTextToClipboard(const ucstring &text); diff --git a/code/nel/src/3d/driver/opengl/stdopengl.h b/code/nel/src/3d/driver/opengl/stdopengl.h index 9773b0048..ab4eb8316 100644 --- a/code/nel/src/3d/driver/opengl/stdopengl.h +++ b/code/nel/src/3d/driver/opengl/stdopengl.h @@ -83,7 +83,6 @@ #include "nel/misc/event_emitter_multi.h" #include "nel/misc/time_nl.h" #include "nel/misc/rect.h" -#include "nel/misc/mouse_device.h" #include "nel/misc/dynloadlib.h" #include "nel/misc/file.h" diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp index c3a8552ac..be0736bae 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "nel/misc/debug.h" @@ -37,7 +37,7 @@ static Atom XA_WM_DELETE_WINDOW = 0; namespace NLMISC { -CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _emulateRawMode(false), _driver(NULL) +CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _driver(NULL) { _im = 0; _ic = 0; @@ -158,25 +158,6 @@ static Bool isMouseMoveEvent(Display *display, XEvent *event, XPointer arg) return (event->type == MotionNotify); } -void CUnixEventEmitter::emulateMouseRawMode(bool enable) -{ - _emulateRawMode = enable; - - if(_emulateRawMode) - { - XWindowAttributes xwa; - XGetWindowAttributes(_dpy, _win, &xwa); - XWarpPointer(_dpy, None, _win, None, None, None, None, - (xwa.width / 2), (xwa.height / 2)); - - // remove all outstanding mouse move events, they happened before the mouse - // was pulled back to 0.5 / 0.5, so a wrong movement delta would be - // reported otherwise - XEvent event; - while(XCheckIfEvent(_dpy, &event, &isMouseMoveEvent, NULL)) { }; - } -} - #ifndef AltMask # ifdef NL_OS_MAC # define AltMask (8192) @@ -512,33 +493,13 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server) { TMouseButton button=getMouseButton (event.xbutton.state); - // if raw mode should be emulated - if(_emulateRawMode) - { - // when we just wrapped back the pointer to 0.5 / 0.5, ignore event - if(event.xbutton.x == xwa.width / 2 && event.xbutton.y == xwa.height / 2) - break; - - // post a CGDMouseMove with the movement delta to the event server - server->postEvent( - new CGDMouseMove(this, NULL /* no mouse device */, - event.xbutton.x - (xwa.width / 2), - (xwa.height / 2) - event.xbutton.y)); - - // move the pointer back to the center of the window - XWarpPointer(_dpy, None, _win, None, None, None, None, - (xwa.width / 2), (xwa.height / 2)); - } - // if in normal mouse mode - else - { - // get the relative mouse position - float fX = (float) event.xbutton.x / (float) xwa.width; - float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height; + // get the relative mouse position + float fX = (float) event.xbutton.x / (float) xwa.width; + float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height; + + // post a normal mouse move event to the event server + server->postEvent (new CEventMouseMove (fX, fY, button, this)); - // post a normal mouse move event to the event server - server->postEvent (new CEventMouseMove (fX, fY, button, this)); - } break; } case KeyPress: diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.h b/code/nel/src/3d/driver/opengl/unix_event_emitter.h index 362ed2086..7eeef970e 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.h @@ -20,7 +20,6 @@ #include "nel/misc/types_nl.h" #include "nel/misc/event_emitter.h" #include "nel/misc/events.h" -#include "nel/misc/game_device_events.h" #include "nel/3d/driver.h" @@ -56,11 +55,6 @@ public: */ virtual void submitEvents(CEventServer & server, bool allWindows); - /** - * enable or disable mouse raw mode - */ - virtual void emulateMouseRawMode(bool emulate); - /** * process input-related events (mouse and keyboard) */ diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 7ccf4cfce..a10357722 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -1609,36 +1609,6 @@ bool CDriverUser::fillBuffer (CBitmap &bitmap) // *************************************************************************** // *************************************************************************** -NLMISC::IMouseDevice *CDriverUser::enableLowLevelMouse(bool enable, bool exclusive) -{ - NL3D_HAUTO_UI_DRIVER; - - return _Driver->enableLowLevelMouse(enable, exclusive); -} -NLMISC::IKeyboardDevice *CDriverUser::enableLowLevelKeyboard(bool enable) -{ - NL3D_HAUTO_UI_DRIVER; - - return _Driver->enableLowLevelKeyboard(enable); -} - -void CDriverUser::emulateMouseRawMode(bool enable) -{ - _Driver->getEventEmitter()->emulateMouseRawMode(enable); -} - -uint CDriverUser::getDoubleClickDelay(bool hardwareMouse) -{ - NL3D_HAUTO_UI_DRIVER; - return _Driver->getDoubleClickDelay(hardwareMouse); -} - -NLMISC::IInputDeviceManager *CDriverUser::getLowLevelInputDeviceManager() -{ - NL3D_HAUTO_UI_DRIVER; - - return _Driver->getLowLevelInputDeviceManager(); -} void CDriverUser::showCursor (bool b) { NL3D_HAUTO_UI_DRIVER; diff --git a/code/nel/src/misc/di_event_emitter.cpp b/code/nel/src/misc/di_event_emitter.cpp deleted file mode 100644 index 8f41f6453..000000000 --- a/code/nel/src/misc/di_event_emitter.cpp +++ /dev/null @@ -1,354 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - -#include "stdmisc.h" - -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/events.h" -#include "nel/misc/win_event_emitter.h" -// -#include "di_mouse_device.h" -#include "di_keyboard_device.h" -#include "di_game_device.h" - - -#ifdef NL_OS_WINDOWS - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ - -static const char DirectInputLibName[] = "dinput8.dll"; - -///////////////////////////////// -// CDIEventEmitter statics // -///////////////////////////////// - -HMODULE CDIEventEmitter::_DirectInputLibHandle = 0; -CDIEventEmitter::TPDirectInput8Create CDIEventEmitter::_PDirectInput8Create = NULL; -uint CDIEventEmitter::_NumCreatedInterfaces = 0; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////// -// CDIEventEmitter implementation // -//////////////////////////////////// - - -//====================================================== -CDIEventEmitter::CDIEventEmitter(HWND hwnd, CWinEventEmitter *we) -: - _hWnd(hwnd), - _WE(we), - _DInput8(NULL), - _Keyboard(NULL), - _Mouse(NULL), - _ButtonsFlags(noButton) -{ -} -//====================================================== -CDIEventEmitter::~CDIEventEmitter() -{ - releaseMouse(); - releaseKeyboard(); - // release all devices - while (_DeviceServer.getNumDevices() != 0) - { - IInputDevice *dev = _DeviceServer.getDevice(0); - _DeviceServer.removeDevice(dev); - delete dev; - } - if (_DInput8) _DInput8->Release(); - -- _NumCreatedInterfaces; - if (_NumCreatedInterfaces == 0) unloadLib(); -} - -//====================================================== -CDIEventEmitter *CDIEventEmitter::create(HINSTANCE hinst, HWND hwnd, CWinEventEmitter *we) throw(EDirectInput) -{ - if (!loadLib()) throw EDirectInputLibNotFound(); - std::auto_ptr dxee(new CDIEventEmitter(hwnd, we)); - HRESULT result = _PDirectInput8Create(hinst, - DIRECTINPUT_VERSION, - IID_IDirectInput8A, - (void **) &dxee->_DInput8, - NULL); - if (result != DI_OK) throw EDirectInputInitFailed(); - - // ok, everything's fine, commit changes - ++_NumCreatedInterfaces; - return dxee.release(); -} - - -//====================================================== -bool CDIEventEmitter::loadLib() -{ - if (_DirectInputLibHandle != 0) return true; // library already loaded ? - HMODULE handle = ::LoadLibrary(DirectInputLibName); - if (handle == 0) return false; - // try to get the creation function - TPDirectInput8Create cf = (TPDirectInput8Create) ::GetProcAddress(handle, "DirectInput8Create"); - if (!cf) - { - ::FreeLibrary(handle); - return false; - } - // commit changes - _DirectInputLibHandle = handle; - _PDirectInput8Create = cf; - return true; -} - - -//====================================================== -void CDIEventEmitter::unloadLib() -{ - nlassert(_DirectInputLibHandle != 0); - ::FreeLibrary(_DirectInputLibHandle); - _DirectInputLibHandle = 0; - _PDirectInput8Create = NULL; -} - -//====================================================== -void CDIEventEmitter::poll(CEventServer *server) -{ - if (_WE) _ButtonsFlags = _WE->buildFlags(); - if (!server) - server=&_InternalServer; - _DeviceServer.poll(server); -} - - -//====================================================== -TMouseButton CDIEventEmitter::buildButtonsFlags() const -{ - uint mouseFlags; - uint keybFlags; - // - if (_Mouse) // takes the flags from the direct input mouse - { - mouseFlags = (_Mouse->getButton(0) ? leftButton : 0) - | (_Mouse->getButton(1) ? rightButton : 0) - | (_Mouse->getButton(2) ? middleButton : 0); - } - else // takes the flags from the system mouse - { - mouseFlags = _ButtonsFlags & (leftButton | rightButton | middleButton); - } - // - if (_Keyboard) // takes the flags from the direct input keyboard - { - keybFlags = (_Keyboard->ShiftPressed ? shiftButton : 0) - | (_Keyboard->AltPressed ? altButton : 0) - | (_Keyboard->CtrlPressed ? ctrlButton : 0); - } - else // takes the flags from the system keyboard - { - keybFlags = _ButtonsFlags & (shiftButton | altButton | ctrlButton); - } - return (TMouseButton) (keybFlags | mouseFlags); -} - -//====================================================== -IMouseDevice *CDIEventEmitter::getMouseDevice(bool hardware) throw(EInputDevice) -{ - if (_Mouse) return _Mouse; // already created ? - try - { - // Create a mouse - std::auto_ptr mouse(CDIMouse::createMouseDevice(_DInput8, _hWnd, this, hardware, _WE)); - // register to the device server - _DeviceServer.registerDevice(mouse.get()); - _Mouse = mouse.get(); - return mouse.release(); - } - catch (...) - { - if (_WE) _WE->enableMouseEvents(true); - throw; - } -} - -//====================================================== -void CDIEventEmitter::releaseMouse() -{ - if (!_Mouse) return; - // reupdate the system keyboard flags - if (_WE) - { - _WE->resetButtonFlagState(); - _WE->enableMouseEvents(true); - } - // remove the device - _DeviceServer.removeDevice(_Mouse); - delete _Mouse; - _Mouse = NULL; -} - -//=========================================================================== -IKeyboardDevice *CDIEventEmitter::getKeyboardDevice() throw(EInputDevice) -{ - if (_Keyboard) return _Keyboard; - try - { - // create a keyboard - std::auto_ptr keyboard(CDIKeyboard::createKeyboardDevice(_DInput8, _hWnd, this, _WE)); - // register to the device server - _DeviceServer.registerDevice(keyboard.get()); - _Keyboard = keyboard.get(); - return keyboard.release(); - } - catch (...) - { - if (_WE) _WE->enableKeyboardEvents(true); - throw; - } -} - -//========================================================================== -void CDIEventEmitter::releaseKeyboard() -{ - if (!_Keyboard) return; - // reupdate the system keyboard flags - if (_WE) - { - _WE->resetButtonFlagState(); - _WE->enableKeyboardEvents(true); - } - // - _DeviceServer.removeDevice(_Keyboard); - delete _Keyboard; - _Keyboard = NULL; -} - - -//========================================================================== -void CDIEventEmitter::submitEvents(CEventServer &server, bool allWindows) -{ - _InternalServer.setServer(&server); - _InternalServer.pump(allWindows); -} - -//========================================================================== -void CDIEventEmitter::emulateMouseRawMode(bool enable) -{ - nlerror("no raw mode emulation on windows, the CDIMouse has a real raw mode"); -} - -//========================================================================== -/// Tool fct to retrieve the game devices. -static BOOL CALLBACK DIEnumDevicesDescCallback -( - LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef -) -{ - CGameDeviceDesc desc; - desc.InstanceName = lpddi->tszInstanceName; - desc.ProductName = lpddi->tszProductName; - switch (lpddi->wUsage & 0xff) - { - case DI8DEVTYPE_JOYSTICK: desc.DevType = CGameDeviceDesc::Joystick; break; - case DI8DEVTYPE_GAMEPAD: desc.DevType = CGameDeviceDesc::GamePad; break; - default: desc.DevType = CGameDeviceDesc::DontKnow; break; - } - TDeviceDescVect *dv = (TDeviceDescVect *) pvRef; - dv->push_back(desc); - return DIENUM_CONTINUE; -} - - -//========================================================================== -/// Tool fct to retrieve the game devices GUID -static BOOL CALLBACK DIEnumDevicesGUIDCallback -( - LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef -) -{ - std::vector *gv = (std::vector *) pvRef; - gv->push_back(lpddi->guidInstance); - return DIENUM_CONTINUE; -} - - -//========================================================================== -void CDIEventEmitter::enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice) -{ - uint k; - nlassert(_DInput8); - descs.clear(); - // enum all devices of interest - _DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesDescCallback, (LPVOID) &descs, DIEDFL_ALLDEVICES); - for (k = 0; k < descs.size(); ++k) descs[k].Connected = false; - // enum all connected devices - static TDeviceDescVect connecteds; - _DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesDescCallback, (LPVOID) &connecteds, DIEDFL_ATTACHEDONLY); - // see which devices are connected - for (k = 0; k < connecteds.size(); ++k) - { - TDeviceDescVect::iterator it = std::find(descs.begin(), descs.end(), connecteds[k]); - it->Connected = true; - } -} - -//========================================================================== -IGameDevice *CDIEventEmitter::createGameDevice(const std::string &instanceName) throw(EInputDevice) -{ - static TDeviceDescVect deviceDescs; - static std::vector deviceGUID; - - nlassert(_DInput8); - enumerateGameDevice(deviceDescs); - // get the ID for each device - deviceGUID.clear(); - HRESULT r = _DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesGUIDCallback, (LPVOID) &deviceGUID, DIEDFL_ALLDEVICES); - nlassert(r == DI_OK); - nlassert(deviceDescs.size() == deviceGUID.size()); - - // search the device that match the instance name - for (uint k = 0; k < deviceDescs.size(); ++k) - { - if (deviceDescs[k].InstanceName == instanceName) - { - std::auto_ptr gd(CDIGameDevice::createGameDevice(_DInput8, _hWnd, this, deviceDescs[k], deviceGUID[k])); - // insert in the device server - _DeviceServer.registerDevice(gd.get()); - return gd.release(); - } - } - return NULL; -} - -//========================================================================== -void CDIEventEmitter::releaseGameDevice(IGameDevice *gd) -{ - nlassert(gd); - CDIGameDevice *digd = safe_cast(gd); - _DeviceServer.removeDevice(digd); - delete gd; -} - - -} // NLMISC - -#endif // NL_OS_WINDOWS diff --git a/code/nel/src/misc/di_game_device.cpp b/code/nel/src/misc/di_game_device.cpp deleted file mode 100644 index 5adfb4b9b..000000000 --- a/code/nel/src/misc/di_game_device.cpp +++ /dev/null @@ -1,523 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - -#include "stdmisc.h" -#include "di_game_device.h" -#include "nel/misc/game_device_events.h" - -#ifdef NL_OS_WINDOWS - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ - -//============================================================================ -CDIGameDevice::CDIGameDevice() : _Device(NULL) -{ - ::memset(&_CurrentState, 0, sizeof(_CurrentState)); -} - -//============================================================================ -CDIGameDevice::~CDIGameDevice() -{ - if (_Device) - { - _Device->Unacquire(); - _Device->Release(); - } -} - -//============================================================================ -CDIGameDevice *CDIGameDevice::createGameDevice(IDirectInput8 *di8, - HWND hwnd, - CDIEventEmitter *diEventEmitter, - const CGameDeviceDesc &desc, - REFGUID rguid) throw(EDirectInput) -{ - nlassert(diEventEmitter); - nlassert(di8); - std::auto_ptr dev(new CDIGameDevice); - // - - HRESULT r = di8->CreateDevice(rguid, &dev->_Device, NULL); - if (r != DI_OK) throw EDirectInputGameDeviceNotCreated(); - - r = dev->_Device->SetDataFormat(pJoyDataFormat); - nlassert(r == DI_OK); - // - r = dev->_Device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); - if (r != DI_OK) throw EDirectInputCooperativeLevelFailed(); - // - // - dev->_Desc = desc; - dev->_EventEmitter = diEventEmitter; - dev->querryControls(); - return dev.release(); -} - -//============================================================================ -void CDIGameDevice::begin(CEventServer *server) -{ - nlassert(_Device); - HRESULT r; - r = _Device->Poll(); - if (r == DIERR_INPUTLOST || r == DIERR_NOTACQUIRED) - { - r = _Device->Acquire(); - if (r != DI_OK) return; - r = _Device->Poll(); - if (r != DI_OK) return; - } - - CDIJoyState newState; - r = _Device->GetDeviceState(sizeof(CDIJoyState), &newState); - if (r != DI_OK) return; - - uint k; - ////////// - // Axis // - ////////// - for (k = 0; k < MaxNumAxis; ++k) - { - CAxis &axis = _Axis[k]; - if (axis.Present) - { - - if (((LONG *) &newState)[k] != ((LONG *) &_CurrentState)[k]) // state changed ? - { - // update position - axis.Value = 2.f * (((LONG *) &newState)[k] - axis.Min) / (float) (axis.Max - axis.Min) - 1.f; - // create event - CGDAxisMoved *event = new CGDAxisMoved((IGameDevice::TAxis) k, axis.Value, this, _EventEmitter); - // update state - ((LONG *) &_CurrentState)[k] = ((LONG *) &newState)[k]; - // - server->postEvent(event); - // - } - } - } - - - ///////////// - // Buttons // - ///////////// - for (k = 0; k < _Buttons.size(); ++k) - { - CButton &bt = _Buttons[k]; - if ((newState.rgbButtons[k] & 0x80) != (_CurrentState.rgbButtons[k] & 0x80)) - { - bool pushed = (newState.rgbButtons[k] & 0x80) != 0; - // update the state of the button - bt.Pushed = pushed; - CGDButton *event; - if (pushed) event = new CGDButtonDown(k, this, _EventEmitter); - else event = new CGDButtonUp(k, this, _EventEmitter); - // update state - _CurrentState.rgbButtons[k] = newState.rgbButtons[k]; - server->postEvent(event); - } - } - - ///////////// - // Sliders // - ///////////// - for (k = 0; k < _Sliders.size(); ++k) - { - CSlider &sl = _Sliders[k]; - if (newState.rglSlider[k] != _CurrentState.rglSlider[k]) // state changed ? - { - // update position - sl.Pos = ( newState.rglSlider[k] - sl.Min) / (float) (sl.Max - sl.Min); - // create event - CGDSliderMoved *event = new CGDSliderMoved(sl.Pos, k, this, _EventEmitter); - // update state - _CurrentState.rglSlider[k] = newState.rglSlider[k]; - // - server->postEvent(event); - } - } - - ////////// - // POVs // - ////////// - for (k = 0; k < _POVs.size(); ++k) - { - CPOV &pov = _POVs[k]; - if (newState.rgdwPOV[k] != _CurrentState.rgdwPOV[k]) // state changed ? - { - DWORD value = newState.rgdwPOV[k]; - - pov.Centered = (LOWORD(value) == 0xFFFF); - if (!pov.Centered) - { - // update position - pov.Angle = value / 100.f; - } - // create event - CGDPOVChanged *event = new CGDPOVChanged(pov.Centered, pov.Angle, k, this, _EventEmitter); - // update state - _CurrentState.rgdwPOV[k] = newState.rgdwPOV[k]; - // - server->postEvent(event); - } - } - -} - -//============================================================================ -void CDIGameDevice::poll(CInputDeviceServer *dev) -{ - // buffered datas not supported -} - -//============================================================================ -void CDIGameDevice::submit(IInputDeviceEvent *deviceEvent, CEventServer *server) -{ - // should never be called, buffered datas not supported - nlassert(0); -} - - -//============================================================================ -/** Tool fct : tests whether a DIDEVICEOBJECTINSTANCE contains a controls name and return it, - * or build a default one - */ -static void BuildCtrlName(LPCDIDEVICEOBJECTINSTANCE lpddoi, - std::string &destName, - const char *defaultName) -{ - if (lpddoi->dwSize >= offsetof(DIDEVICEOBJECTINSTANCE, tszName) + sizeof(TCHAR[MAX_PATH])) - { - destName = (::strcmp("N/A", lpddoi->tszName) == 0) ? defaultName - : lpddoi->tszName; - } - else - { - destName = defaultName; - } -} - -//============================================================================ -// A callback to enumerate the controls of a device -BOOL CALLBACK DIEnumDeviceObjectsCallback -( - LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef -) -{ - - CDIGameDevice *gd = (CDIGameDevice *) pvRef; - return gd->processEnumObject(lpddoi); -} - - - -//======================================================================= -// get range for an axis -static HRESULT GetDIAxisRange(LPDIRECTINPUTDEVICE8 device, uint offset, DWORD type, sint &min, sint &max) -{ - DIPROPRANGE diprg; - diprg.diph.dwSize = sizeof(DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.diph.dwObj = offset; - - // Set the range for the axis - HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph); - - if (r == DIERR_OBJECTNOTFOUND) - { - // try from its ID - diprg.diph.dwHow = DIPH_BYID; - diprg.diph.dwObj = type; - - // Set the range for the axis - HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph); - if (r != DI_OK) - { - // setup default values ... - min = 0; - max = 65535; - return r; - } - } - else if (r != DI_OK) - { - min = 0; - max = 65535; - return r; - } - - -/* switch (r) - { - default: - nlinfo("ok"); - break; - case DIERR_INVALIDPARAM: - nlinfo("invalid param"); - break; - case DIERR_NOTEXCLUSIVEACQUIRED: - nlinfo("DIERR_NOTEXCLUSIVEACQUIRED"); - break; - case DIERR_NOTINITIALIZED: - nlinfo("DIERR_NOTINITIALIZED"); - break; - case DIERR_OBJECTNOTFOUND: - nlinfo("DIERR_OBJECTNOTFOUND"); - break; - case DIERR_UNSUPPORTED: - nlinfo("DIERR_UNSUPPORTED"); - break; - }*/ - - - min = (sint) diprg.lMin; - max = (sint) diprg.lMax; - - return r; -} - -//============================================================================ -BOOL CDIGameDevice::processEnumObject(LPCDIDEVICEOBJECTINSTANCE lpddoi) -{ - // the dwSize field gives us the size of the objects, and the available fields - // has this object the field guidType and dwOfs ? - if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwOfs) + sizeof(DWORD)) return DIENUM_CONTINUE; - - uint ctrlType = (uint) lpddoi->dwType; - - /////////////////////////////////////////// - // axis, we only support absolute ones // - /////////////////////////////////////////// - - if (lpddoi->guidType == GUID_XAxis && (ctrlType & DIDFT_ABSAXIS) ) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[XAxis].Min, _Axis[XAxis].Max); - BuildCtrlName(lpddoi, _Axis[XAxis].Name, "X Axis"); - _Axis[XAxis].Present = true; - return DIENUM_CONTINUE; - } - if (lpddoi->guidType == GUID_YAxis && (ctrlType & DIDFT_ABSAXIS)) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[YAxis].Min, _Axis[YAxis].Max); - BuildCtrlName(lpddoi, _Axis[YAxis].Name, "Y Axis"); - _Axis[YAxis].Present = true; - return DIENUM_CONTINUE; - } - - if (lpddoi->guidType == GUID_ZAxis && (ctrlType & DIDFT_ABSAXIS)) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[ZAxis].Min, _Axis[ZAxis].Max); - BuildCtrlName(lpddoi, _Axis[ZAxis].Name, "Z Axis"); - _Axis[ZAxis].Present = true; - return DIENUM_CONTINUE; - } - if (lpddoi->guidType == GUID_RxAxis && (ctrlType & DIDFT_ABSAXIS)) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RXAxis].Min, _Axis[RXAxis].Max); - BuildCtrlName(lpddoi, _Axis[RXAxis].Name, "RX Axis"); - _Axis[RXAxis].Present = true; - return DIENUM_CONTINUE; - } - if (lpddoi->guidType == GUID_RyAxis && (ctrlType & DIDFT_ABSAXIS)) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RYAxis].Min, _Axis[RYAxis].Max); - BuildCtrlName(lpddoi, _Axis[RYAxis].Name, "RY Axis"); - _Axis[RYAxis].Present = true; - return DIENUM_CONTINUE; - } - if (lpddoi->guidType == GUID_RzAxis && (ctrlType & DIDFT_ABSAXIS)) - { - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RZAxis].Min, _Axis[RZAxis].Max); - BuildCtrlName(lpddoi, _Axis[RZAxis].Name, "RZ Axis"); - _Axis[RZAxis].Present = true; - return DIENUM_CONTINUE; - } - - - // has this object the field dwType ? - if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwType) + sizeof(DWORD)) return DIENUM_CONTINUE; - - - uint type = lpddoi->dwType; - ///////////// - // Buttons // - ///////////// - if (type & DIDFT_BUTTON) - { - if (_Buttons.size() < MaxNumButtons) - { - _Buttons.push_back(CButton()); - uint buttonIndex = (uint)_Buttons.size() - 1; - char defaultButtonName[32]; - smprintf(defaultButtonName, 32, "BUTTON %d", buttonIndex + 1); - BuildCtrlName(lpddoi, _Buttons[buttonIndex].Name, defaultButtonName); - return DIENUM_CONTINUE; - } - } - - ///////////// - // Sliders // - ///////////// - if (type & DIDFT_ABSAXIS) - { - if (_Sliders.size() < MaxNumSliders) - { - _Sliders.push_back(CSlider()); - uint sliderIndex = (uint)_Sliders.size() - 1; - GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Sliders[sliderIndex].Min, _Sliders[sliderIndex].Max); - char defaultSliderName[32]; - smprintf(defaultSliderName, 32, "SLIDER %d", sliderIndex + 1); - BuildCtrlName(lpddoi, _Sliders[sliderIndex].Name, defaultSliderName); - } - return DIENUM_CONTINUE; - } - - - ////////// - // POVs // - ////////// - if (type & DIDFT_POV) - { - if (_POVs.size() < MaxNumPOVs) - { - _POVs.push_back(CPOV()); - uint povIndex = (uint)_POVs.size() - 1; - char defaultPOVName[16]; - smprintf(defaultPOVName, 16, "POV %d", povIndex + 1); - BuildCtrlName(lpddoi, _POVs[povIndex].Name, defaultPOVName); - } - return DIENUM_CONTINUE; - } - - return DIENUM_CONTINUE; -} - -//============================================================================ -void CDIGameDevice::querryControls() -{ - HRESULT r = _Device->EnumObjects(&DIEnumDeviceObjectsCallback, (LPVOID) this, DIDFT_ALL); - nlassert(r == DI_OK); -} - -//============================================================================ -bool CDIGameDevice::setBufferSize(uint size) -{ - // uisually not supported by this kind of devices - return false; -} - -//============================================================================ -uint CDIGameDevice::getBufferSize() const -{ - // uisually not supported by this kind of devices - return 0; -} - -//============================================================================ -uint CDIGameDevice::getNumButtons() const -{ - return (uint)_Buttons.size(); -} - -//============================================================================ -bool CDIGameDevice::hasAxis(TAxis axis) const -{ - nlassert(axis < MaxNumAxis); - return _Axis[axis].Present; -} - -//============================================================================ -uint CDIGameDevice::getNumSliders() const -{ - return (uint)_Sliders.size(); -} - -//============================================================================ -uint CDIGameDevice::getNumPOV() const -{ - return (uint)_POVs.size(); -} -//============================================================================ -const char *CDIGameDevice::getButtonName(uint index) const -{ - nlassert(index < _Buttons.size()); - return _Buttons[index].Name.c_str(); -} - -//============================================================================ -const char *CDIGameDevice::getAxisName(TAxis axis) const -{ - nlassert(axis < MaxNumAxis); - nlassert(hasAxis(axis)); // ! Not an axis of this device - return _Axis[axis].Name.c_str(); -} - -//============================================================================ -const char *CDIGameDevice::getSliderName(uint index) const -{ - nlassert(index < _Sliders.size()); - return _Sliders[index].Name.c_str(); -} - -//============================================================================ -const char *CDIGameDevice::getPOVName(uint index) const -{ - nlassert(index < _POVs.size()); - return _POVs[index].Name.c_str(); -} - -//============================================================================ -bool CDIGameDevice::getButtonState(uint index) const -{ - nlassert(index < _Buttons.size()); - return _Buttons[index].Pushed; -} - -//============================================================================ -float CDIGameDevice::getAxisValue(TAxis axis) const -{ - nlassert(axis < MaxNumAxis); - nlassert(hasAxis(axis)); // ! Not an axis of this device - return _Axis[axis].Value; -} - -//============================================================================ -float CDIGameDevice::getSliderPos(uint index) const -{ - nlassert(index < _Sliders.size()); - return _Sliders[index].Pos; -} - -//============================================================================ -float CDIGameDevice::getPOVAngle(uint index) const -{ - nlassert(index < _POVs.size()); - return _POVs[index].Angle; -} - - - -} // NLMISC - - -#endif // NL_OS_WINDOWS diff --git a/code/nel/src/misc/di_game_device.h b/code/nel/src/misc/di_game_device.h deleted file mode 100644 index cc44aaf4c..000000000 --- a/code/nel/src/misc/di_game_device.h +++ /dev/null @@ -1,170 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_DI_GAME_DEVICE_H -#define NL_DI_GAME_DEVICE_H - -#include "nel/misc/types_nl.h" - -#ifdef NL_OS_WINDOWS - -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/game_device.h" - -namespace NLMISC -{ - -// -typedef DIJOYSTATE2 CDIJoyState; -const DIDATAFORMAT * const pJoyDataFormat = &c_dfDIJoystick2; -const uint MaxNumSliders = 2; -const uint MaxNumPOVs = 4; -const uint MaxNumButtons = 128; -// - -struct EDirectInputGameDeviceNotCreated : EDirectInput -{ - EDirectInputGameDeviceNotCreated() : EDirectInput("Unable to create a game device") {} -}; - - -/** - * Direct input implementation of a game device. - */ - -class CDIGameDevice : public IGameDevice -{ -public: - /// Create a direct input game device from the given RGUID. Destroy it with delete - static CDIGameDevice *createGameDevice(IDirectInput8 *di8, - HWND hwnd, - CDIEventEmitter *diEventEmitter, - const CGameDeviceDesc &desc, - REFGUID rguid) throw(EDirectInput); - ~CDIGameDevice(); - - ///\name From IInputDevice - //@{ - virtual bool setBufferSize(uint size); - virtual uint getBufferSize() const; - //@} - - ///\name From IGameDevice - //@{ - virtual const CGameDeviceDesc &getDescription() const { return _Desc; } - // - virtual uint getNumButtons() const; - virtual bool hasAxis(TAxis axis) const; - virtual uint getNumSliders() const; - virtual uint getNumPOV() const; - // - virtual const char *getButtonName(uint index) const; - virtual const char *getAxisName(TAxis axis) const; - virtual const char *getSliderName(uint index) const; - virtual const char *getPOVName(uint index) const; - // - virtual bool getButtonState(uint index) const; - virtual float getAxisValue(TAxis axis) const; - virtual float getSliderPos(uint index) const; - virtual float getPOVAngle(uint index) const; - //@} - - -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -private: - - // base class for controls - struct CCtrl - { - std::string Name; - }; - - // a button - struct CButton : public CCtrl - { - bool Pushed; - CButton() : Pushed(false) {} - }; - - // an axis. Its value either gives its position (-1 .. 1) or its angle (CCW in radians) - struct CAxis : public CCtrl - { - bool Present; // is this axis used ? - // min and max values from Direct Input - sint Min, Max; - float Value; - CAxis() : Value(0.f), Present(false) {} - }; - - // a slider - struct CSlider : public CCtrl - { - sint Min, Max; - float Pos; - CSlider() : Pos(0.f) {} - }; - - // a POV - struct CPOV : public CCtrl - { - bool Centered; - float Angle; - CPOV() : Angle(0.f), Centered(true) {} - }; - - -private: - // ctor - CDIGameDevice(); - ///\name From IInputDevice - //@{ - virtual void begin(CEventServer *server); - virtual void poll(CInputDeviceServer *dev); - virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server); - //@} - /** Get the controls (buttons, slider..) of this device from the Direct Input interface to build this object infos. - */ - void querryControls(); - - /// Called during EnumObject - BOOL processEnumObject(LPCDIDEVICEOBJECTINSTANCE lpddoi); - friend BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); -private: - LPDIRECTINPUTDEVICE8 _Device; - CGameDeviceDesc _Desc; - CDIEventEmitter *_EventEmitter; - - ///\name Device infos - //@{ - CAxis _Axis[MaxNumAxis]; - std::vector _Buttons; - std::vector _Sliders; - std::vector _POVs; - //@} - CDIJoyState _CurrentState; - -}; - - -} // NLMISC - -#endif // NL_OS_WINDOWS - - -#endif // NL_DI_GAME_DEVICE_H - -/* End of di_play_device.h */ diff --git a/code/nel/src/misc/di_keyboard_device.cpp b/code/nel/src/misc/di_keyboard_device.cpp deleted file mode 100644 index 8b5d9c6e1..000000000 --- a/code/nel/src/misc/di_keyboard_device.cpp +++ /dev/null @@ -1,686 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - - -#include "stdmisc.h" -#include "di_keyboard_device.h" - -#ifdef NL_OS_WINDOWS - -#include "nel/misc/win_event_emitter.h" -#include -#include - -#include "Mmsystem.h" - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ - -// used to do a conversion from DX key code to Nel keys enums -struct CKeyConv -{ - uint DIKey; - TKey NelKey; - const char *KeyName; - bool Repeatable; -}; - -// this is used to build a conversion table -static const CKeyConv DIToNel[] = -{ - // - {DIK_F1, KeyF1, "F1", true}, - {DIK_F2, KeyF2, "F2", true}, - {DIK_F3, KeyF3, "F3", true}, - {DIK_F4, KeyF4, "F4", true}, - {DIK_F5, KeyF5, "F5", true}, - {DIK_F6, KeyF6, "F6", true}, - {DIK_F7, KeyF7, "F7", true}, - {DIK_F8, KeyF8, "F8", true}, - {DIK_F9, KeyF9, "F9", true}, - {DIK_F10, KeyF10, "F10", true}, - {DIK_F11, KeyF11, "F11", true}, - {DIK_F12, KeyF12, "F12", true}, - {DIK_F13, KeyF13, "F13", true}, - {DIK_F14, KeyF14, "F14", true}, - {DIK_F15, KeyF15, "F15", true}, - // - {DIK_NUMPAD0, KeyNUMPAD0, "NUMPAD0", true}, - {DIK_NUMPAD1, KeyNUMPAD1, "NUMPAD1", true}, - {DIK_NUMPAD2, KeyNUMPAD2, "NUMPAD2", true}, - {DIK_NUMPAD3, KeyNUMPAD3, "NUMPAD3", true}, - {DIK_NUMPAD4, KeyNUMPAD4, "NUMPAD4", true}, - {DIK_NUMPAD5, KeyNUMPAD5, "NUMPAD5", true}, - {DIK_NUMPAD6, KeyNUMPAD6, "NUMPAD6", true}, - {DIK_NUMPAD7, KeyNUMPAD7, "NUMPAD7", true}, - {DIK_NUMPAD8, KeyNUMPAD8, "NUMPAD8", true}, - {DIK_NUMPAD9, KeyNUMPAD9, "NUMPAD9", true}, - // - {DIK_DIVIDE, KeyDIVIDE, "/", true}, - {DIK_DECIMAL, KeyDECIMAL, "NUMPAD .", true}, - // - {DIK_LSHIFT, KeyLSHIFT, "LEFT SHIFT", false}, - {DIK_RSHIFT, KeyRSHIFT, "RIGHT SHIFT", false}, - // - {DIK_LCONTROL, KeyLCONTROL, "LEFT CONTROL", false}, - {DIK_RCONTROL, KeyRCONTROL, "RIGHT CONTROL", false}, - // - {DIK_LMENU, KeyLMENU, "ALT", false}, - {DIK_RMENU, KeyRMENU, "ALT GR", false}, - // - {DIK_UP, KeyUP, "UP", true}, - {DIK_PRIOR, KeyPRIOR, "PRIOR", true}, - {DIK_LEFT, KeyLEFT, "LEFT", true}, - {DIK_RIGHT, KeyRIGHT, "RIGHT", true}, - {DIK_END, KeyEND, "END", true}, - {DIK_DOWN, KeyDOWN, "DOWN", true}, - {DIK_NEXT, KeyNEXT, "NEXT", true}, - {DIK_INSERT, KeyINSERT, "INSERT", true}, - {DIK_DELETE, KeyDELETE, "DELETE", true}, - {DIK_HOME, KeyHOME, "HOME", true}, - {DIK_LWIN, KeyLWIN, "LEFT WIN", false}, - {DIK_RWIN, KeyRWIN, "RIGHT WIN", false}, - {DIK_APPS, KeyAPPS, "APPS", false}, - {DIK_BACK, KeyBACK, "BACK", true}, - // - {DIK_SYSRQ, KeySNAPSHOT, "SNAPSHOT", false}, - {DIK_SCROLL, KeySCROLL, "SCROLL", false}, - {DIK_PAUSE, KeyPAUSE, "PAUSE", false}, - // - {DIK_NUMLOCK, KeyNUMLOCK, "NUMLOCK", false}, - // - {DIK_NUMPADENTER, KeyRETURN, "RETURN", true}, - //{DIK_NUMPADENTER, KeyRETURN, "ENTER", true}, - // - {DIK_CONVERT, KeyCONVERT, "CONVERT", false}, - {DIK_NOCONVERT, KeyNONCONVERT, "NOCONVERT", true}, - // - {DIK_KANA, KeyKANA, "KANA", false}, - {DIK_KANJI, KeyKANJI, "KANJI", false}, -}; - - -///======================================================================== -const CKeyConv *CDIKeyboard::DIKeyToNelKeyTab[CDIKeyboard::NumKeys]; - -///======================================================================== -CDIKeyboard::CDIKeyboard(CWinEventEmitter *we, HWND hwnd) -: _Keyboard(NULL), - _WE(we), - ShiftPressed(false), - CtrlPressed(false), - AltPressed(false), - _CapsLockToggle(true), - _hWnd(hwnd), - _RepeatDelay(250), - _RepeatPeriod(200), - _FirstPressDate(-1), - _LastDIKeyPressed(0) -{ - if (::GetKeyboardState((PBYTE) _VKKeyState) == FALSE) - { - std::fill(_VKKeyState, _VKKeyState + NumKeys, 0); - } - // test whether the user toggle its keyboard with shift or not.. - HKEY hKey; - if (::RegOpenKeyEx(HKEY_CURRENT_USER, "Keyboard Layout", 0, KEY_READ, &hKey) == ERROR_SUCCESS) - { - DWORD type = REG_DWORD; - DWORD value; - DWORD size = sizeof(DWORD); - if (::RegQueryValueEx(hKey, "Attributes", NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS) - { - _CapsLockToggle = (value & (1 << 16)) == 0; - } - ::RegCloseKey(hKey); - } - // get repeat delay and period - int keybDelay; - if (::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &keybDelay, 0) != 0) - { - _RepeatDelay = 250 + 250 * keybDelay; - } - DWORD keybSpeed; - if (::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &keybSpeed, 0) != 0) - { - _RepeatPeriod = (uint) (1000.f / (keybSpeed * (27.5f / 31.f) + 2.5f)); - } - // get keyboard layout - _KBLayout = ::GetKeyboardLayout(0); - - _RepetitionDisabled.resize(NumKeys); - _RepetitionDisabled.clearAll(); -} - -///======================================================================== -void CDIKeyboard::updateVKKeyState(uint diKey, bool pressed, TKey &keyValue, TKey &charValue) -{ - bool extKey; - bool repeatable; - keyValue = DIKeyToNelKey(diKey, extKey, repeatable); - // - if (keyValue == 0) - { - charValue = keyValue; - return; - } - // - if (pressed) - { - // check for toggle key - switch (keyValue) - { - case KeyPAUSE: - case KeyKANA: - case KeyKANJI: - _VKKeyState[keyValue] ^= 0x01; // toggle first bit - break; - case KeyCAPITAL: - if (_CapsLockToggle) - { - _VKKeyState[keyValue] ^= 0x01; - //toggleCapsLock(false); - } - else - { - if ((_VKKeyState[keyValue] & 0x01) == 0) - { - _VKKeyState[keyValue] |= 0x01; - //toggleCapsLock(false); - } - } - break; - case KeyNUMLOCK: - _VKKeyState[keyValue] ^= 0x01; - //setNumLock((_VKKeyState[keyValue] & 0x01) != 0); - break; - case KeySCROLL: - _VKKeyState[keyValue] ^= 0x01; - //toggleScrollLock(); - break; - - } - - _VKKeyState[keyValue] |= 0x80; - } - else - { - _VKKeyState[keyValue] &= ~0x80; - } - // - switch (keyValue) - { - case KeyLSHIFT: charValue = KeySHIFT; break; - case KeyRSHIFT: charValue = KeySHIFT; break; - case KeyLCONTROL: charValue = KeyCONTROL; break; - case KeyRCONTROL: charValue = KeyCONTROL; break; - case KeyLMENU: charValue = KeyMENU; break; - case KeyRMENU: charValue = KeyMENU; break; - default: charValue = keyValue; break; - } - // - if (charValue == KeySHIFT && !_CapsLockToggle) - { - if (_VKKeyState[KeyCAPITAL] & 0x01) - { - _VKKeyState[KeyCAPITAL] &= ~0x01; - //toggleCapsLock(true); - } - } - // - if (charValue != keyValue) - { - _VKKeyState[charValue] = _VKKeyState[keyValue]; - } - // - updateCtrlAltShiftValues(); -} - -///======================================================================== -void CDIKeyboard::updateCtrlAltShiftValues() -{ - ShiftPressed = (_VKKeyState[KeySHIFT] & 0x80) != 0; - CtrlPressed = (_VKKeyState[KeyCONTROL] & 0x80) != 0; - AltPressed = (_VKKeyState[KeyMENU] & 0x80) != 0; -} - -///======================================================================== -CDIKeyboard::~CDIKeyboard() -{ - if (_Keyboard) - { - _Keyboard->Unacquire(); - _Keyboard->Release(); - } -} - -///======================================================================== -CDIKeyboard *CDIKeyboard::createKeyboardDevice(IDirectInput8 *di8, - HWND hwnd, - CDIEventEmitter *diEventEmitter, - CWinEventEmitter *we - ) throw(EDirectInput) -{ - std::auto_ptr kb(new CDIKeyboard(we, hwnd)); - kb->_DIEventEmitter = diEventEmitter; - HRESULT result = di8->CreateDevice(GUID_SysKeyboard, &kb->_Keyboard, NULL); - if (result != DI_OK) throw EDirectInputNoKeyboard(); - result = kb->_Keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); - if (result != DI_OK) throw EDirectInputCooperativeLevelFailed(); - result = kb->_Keyboard->SetDataFormat(&c_dfDIKeyboard); - kb->setBufferSize(16); - kb->_Keyboard->Acquire(); - - // Enable win32 keyboard messages only if hardware mouse in normal mode - if (kb->_WE) - kb->_WE->enableKeyboardEvents(false); - - return kb.release(); -} - -///======================================================================== -void CDIKeyboard::poll(CInputDeviceServer *dev) -{ - nlassert(_Keyboard); - nlassert(_KeyboardBufferSize > 0); - static std::vector datas; - datas.resize(_KeyboardBufferSize); - DWORD numElements = _KeyboardBufferSize; - HRESULT result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0); - if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST) - { - result = _Keyboard->Acquire(); - if (result != DI_OK) return; - // get device state - ::GetKeyboardState((unsigned char *) _VKKeyState); - _LastDIKeyPressed = 0; - updateCtrlAltShiftValues(); - result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0); - if (result != DI_OK) return; - } - else if (result != DI_OK) - { - return; - } - - _PollTime = (uint32) CTime::getLocalTime(); - - - // process each message in the list - for (uint k = 0; k < numElements; ++k) - { - CDIEvent *die = new CDIEvent; - die->Emitter = this; - die->Datas = datas[k]; - dev->submitEvent(die); - } -} - -///======================================================================== -void CDIKeyboard::transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage) -{ - repeatKey(buildDateFromEvent(nextMessage), server); -} - -///======================================================================== -TKeyButton CDIKeyboard::buildKeyButtonsFlags() const -{ - return (TKeyButton) ( (ShiftPressed ? shiftKeyButton : 0) - | (CtrlPressed ? ctrlKeyButton : 0) - | (AltPressed ? altKeyButton : 0) - ); -} - -///======================================================================== -void CDIKeyboard::keyTriggered(bool pressed, uint dikey, CEventServer *server, uint32 date) -{ - #if 0 - const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv); - for (uint k = 0; k < numPairs; ++k) - { - if (DIToNel[k].DIKey == key) - { - nlinfo(DIToNel[k].KeyName); - } - } - #endif - - - TKey keyValue, charValue; - updateVKKeyState(dikey, pressed, keyValue, charValue); - if (keyValue == 0) return; - - CEventKey *ek; - if (pressed ) - { - ek = new CEventKeyDown(keyValue, buildKeyButtonsFlags(), true, _DIEventEmitter); - } - else - { - ek = new CEventKeyUp(keyValue, buildKeyButtonsFlags(), _DIEventEmitter); - } - server->postEvent(ek); - - if (pressed) - { - if (_RepetitionDisabled[(uint) keyValue] == false) - { - _LastEmitDate = _FirstPressDate = date; - _LastDIKeyPressed = dikey; - } - else // not a repeatable key - { - _LastDIKeyPressed = 0; - return; - } - } - else - { - // key released ? - if (dikey == _LastDIKeyPressed) - { - _LastDIKeyPressed = 0; - } - - if (_RepetitionDisabled[(uint) keyValue] == true) - { - return; - } - } - - // first char event (if repetition not disabled) - if (keyValue >= KeyNUMPAD0 && keyValue <= KeyNUMPAD9 || keyValue == KeyDECIMAL) - { - if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0) - { - sendUnicode(charValue, dikey, server, pressed); - } - } - else - { - sendUnicode(charValue, dikey, server, pressed); - } - - _FirstPressDate = (uint32) NLMISC::CTime::getLocalTime(); // can't use the time stamp, because we can't not sure it matches the local time. - // time stamp is used for evenrts sorting only -} - -///======================================================================== -void CDIKeyboard::submit(IInputDeviceEvent *deviceEvent, CEventServer *server) -{ - CDIEvent *die = safe_cast(deviceEvent); - bool pressed = (die->Datas.dwData & 0x80) != 0; - keyTriggered(pressed, (uint) die->Datas.dwOfs, server, die->Datas.dwTimeStamp); -} - -///======================================================================== -TMouseButton CDIKeyboard::buildKeyboardButtonFlags() const -{ - nlassert(_Keyboard); - return _DIEventEmitter->buildKeyboardButtonFlags(); -} - -///======================================================================== -bool CDIKeyboard::setBufferSize(uint size) -{ - nlassert(size > 0); - nlassert(_Keyboard); - _Keyboard->Unacquire(); - DIPROPDWORD dipdw; - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = size; - HRESULT r = _Keyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ); - if (r != DI_OK) return false; - _KeyboardBufferSize = size; - return true; -} - -///======================================================================== -uint CDIKeyboard::getBufferSize() const -{ - return _KeyboardBufferSize; -} - -///======================================================================== -TKey CDIKeyboard::DIKeyToNelKey(uint diKey, bool &extKey, bool &repeatable) -{ - // some key are not handled by MapVirtualKeyEx so we need to convert them ourselves - static bool tableBuilt = false; - - if (!tableBuilt) - { - uint k; - for (k = 0; k < NumKeys; ++k) - { - DIKeyToNelKeyTab[k] = NULL; // set as not a valid key by default - } - const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv); - for (k = 0; k < numPairs; ++k) - { - DIKeyToNelKeyTab[DIToNel[k].DIKey] = &DIToNel[k]; - } - tableBuilt = true; - } - - - // - if (DIKeyToNelKeyTab[diKey] != NULL) - { - const CKeyConv &keyConv = *DIKeyToNelKeyTab[diKey]; - extKey = true; - repeatable = keyConv.Repeatable; - return keyConv.NelKey; - } - - - - // try doing the conversion using MapVirtualKey - TKey key = (TKey) ::MapVirtualKeyEx(diKey, 1, _KBLayout); - extKey = false; - return key; -} - -///======================================================================== -void CDIKeyboard::sendUnicode(TKey vkey, uint dikey, CEventServer *server, bool pressed) -{ - uint8 oldShift = _VKKeyState[KeySHIFT]; - /// If caps lock is off when pressing shift, we must disable shift, to get no minuscule letters when it is pressed and capslocks is on. - if (!_CapsLockToggle && _VKKeyState[KeyCAPITAL] & 0x01) - { - _VKKeyState[KeySHIFT] = 0; - } - // 'ToUnicode??' is supported since NT4.0 only - // Check if there's support - - - static bool init = false; - static bool toUnicodeSupported = false; - if (!init) - { - init = true; - OSVERSIONINFO osvi; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (::GetVersionEx (&osvi)) - { - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - if (osvi.dwMajorVersion >= 4) - { - toUnicodeSupported = true; - } - } - } - } - - - if (toUnicodeSupported) - { - const uint maxNumKeys = 8; - WCHAR keyUnicodes[maxNumKeys]; - int res = ::ToUnicodeEx(vkey, dikey | (pressed ? 0 : (1 << 15)), (unsigned char *) _VKKeyState, keyUnicodes, maxNumKeys, 0, _KBLayout); - // - _VKKeyState[KeySHIFT] = oldShift; - // - for (sint k = 0; k < res; ++k) - { - CEventChar *evc = new CEventChar((ucchar) keyUnicodes[k], buildKeyButtonsFlags(), _DIEventEmitter); - server->postEvent(evc); - } - } - else - { - unsigned char buf[2]; - int res = ::ToAsciiEx(vkey, dikey | (pressed ? 0 : (1 << 15)), (unsigned char *) _VKKeyState, (LPWORD) buf, 0, _KBLayout); - for (sint k = 0; k < res; ++k) - { - CEventChar *evc = new CEventChar((ucchar) buf[k], buildKeyButtonsFlags(), _DIEventEmitter); - server->postEvent(evc); - } - } -} - -///======================================================================== -void CDIKeyboard::repeatKey(uint32 currentDate, CEventServer *server) -{ - if (_LastDIKeyPressed == 0 || _LastDIKeyPressed == DIK_INSERT) return; - bool extKey; - bool repeatable; - TKey vkey = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable); - if (vkey == 0) return; - if (currentDate - _FirstPressDate < _RepeatDelay) return; - - sint32 firstDate = _LastEmitDate - (_FirstPressDate + _RepeatDelay); - sint32 lastDate = currentDate - (_FirstPressDate + _RepeatDelay); - if (firstDate < 0) firstDate = 0; - - if (lastDate < firstDate) return; - - uint numRep = (uint) ((lastDate + _RepeatPeriod - 1) / _RepeatPeriod - (firstDate + _RepeatPeriod - 1) / _RepeatPeriod); - //numRep = std::min(16u, numRep); // too much repetitions don't make sense... - if ((sint) numRep < 0) return; // 50 days loop.. - numRep = 1; // fix : for now it seems better to limit the number of repetition to 1 per frame (it can be greater than 1 only if framerate is slow, but its not very useable) - - - // numpad case - if (vkey >= KeyNUMPAD0 && vkey <= KeyNUMPAD9 || vkey == KeyDECIMAL) - { - // check whether numlock is activated - if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0) - { - for (uint k = 0; k < numRep; ++k) - { - sendUnicode(vkey, _LastDIKeyPressed, server, true); - } - } - else - { - // arrow, home, end.. events - for (uint k = 0; k < numRep; ++k) - { - CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), false, _DIEventEmitter); - server->postEvent(ek); - } - } - } - else - { - for (uint k = 0; k < numRep; ++k) - { - // if it is an extended key, repetition won't be managed by sendUnicode - if (extKey && repeatable) - { - CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), false, _DIEventEmitter); - server->postEvent(ek); - } - else - { - sendUnicode(vkey, _LastDIKeyPressed, server, true); - } - } - } - - _LastEmitDate = currentDate; -} - -///======================================================================== -uint32 CDIKeyboard::buildDateFromEvent(const IInputDeviceEvent *deviceEvent) -{ - if (deviceEvent) - { - const CDIEvent *die = safe_cast(deviceEvent); - return (uint32) die->Datas.dwData; - } - else - { - return _PollTime; - } -} - -///======================================================================== -void CDIKeyboard::disableRepetition(const TKey *keyTab, uint numKey) -{ - _RepetitionDisabled.clearAll(); - for (uint k = 0; k < numKey; ++k) - { - _RepetitionDisabled.set((sint) keyTab[k]); - } - - if (_LastDIKeyPressed != 0) - { - bool extKey; - bool repeatable; - TKey key = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable); - if (_RepetitionDisabled[(uint) key]) - { - // disable this key repetition - _LastDIKeyPressed = 0; - } - } -} - -///======================================================================== -uint CDIKeyboard::getNumDisabledRepetition() const -{ - uint numKey = 0; - for (uint k = 0; k < NumKeys; ++k) - { - if (_RepetitionDisabled[k]) ++numKey; - } - return numKey; -} - -///======================================================================== -void CDIKeyboard::getDisabledRepetitions(TKey *destTab) const -{ - for (uint k = 0; k < NumKeys; ++k) - { - if (_RepetitionDisabled[k]) *destTab++ = (TKey) k; - } -} - - - -} // NLMISC - -#endif // NL_OS_WINDOWS diff --git a/code/nel/src/misc/di_keyboard_device.h b/code/nel/src/misc/di_keyboard_device.h deleted file mode 100644 index d28285894..000000000 --- a/code/nel/src/misc/di_keyboard_device.h +++ /dev/null @@ -1,163 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_DI_KEYBOARD_H -#define NL_DI_KEYBOARD_H - -#include "nel/misc/types_nl.h" - -#ifdef NL_OS_WINDOWS - -#include "nel/misc/input_device_server.h" -#include "nel/misc/keyboard_device.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/bit_set.h" - - - - - -namespace NLMISC -{ - -class CWinEventEmitter; - -// -struct EDirectInputNoKeyboard : public EDirectInput -{ - EDirectInputNoKeyboard() : EDirectInput("No keyboard found") {} -}; - - -struct CKeyConv; - -/** - * Direct Input implementation of a keyboard. - * \see CDIEventEmitter - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ -class CDIKeyboard : public IKeyboardDevice -{ -public: - bool ShiftPressed, CtrlPressed, AltPressed; -public: - ///\name Object - //@{ - /** Create a keyboard device, that must then be deleted by the caller - * An optional WinEventEmiter can be provided, so that its flags can be in sync - * with a win32 keyboard flags (shift, ctrl, and alt) - */ - static CDIKeyboard *createKeyboardDevice(IDirectInput8 *di8, - HWND hwnd, - CDIEventEmitter *diEventEmitter, - CWinEventEmitter *we = NULL - ) throw(EDirectInput); - // dtor - virtual ~CDIKeyboard(); - //@} - - ///\name From IInputDevice - //@{ - virtual bool setBufferSize(uint size); - virtual uint getBufferSize() const; - //@} - - ///\name From IInputDevice - //@{ - uint getKeyRepeatDelay() const { return _RepeatDelay; } - void setKeyRepeatDelay(uint delay) { nlassert(delay > 0); _RepeatDelay = delay; } - uint getKeyRepeatPeriod() const { return _RepeatPeriod; } - void setKeyRepeatPeriod(uint period) { nlassert(period > 0); _RepeatPeriod = period; } - void disableRepetition(const TKey *keyTab, uint numKey); - uint getNumDisabledRepetition() const; - void getDisabledRepetitions(TKey *destTab) const; - //@} - - TMouseButton buildKeyboardFlags() const; -/////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////// -private: - // - bool _CapsLockToggle; // true if caps lock off is triggered by caps lock, false if it toggled by shift - uint _RepeatDelay; // the delay before a key is repeated (in ms) - uint _RepeatPeriod; // The period for key repetitions (in ms) - // - LPDIRECTINPUTDEVICE8 _Keyboard; - uint _KeyboardBufferSize; - // virtual code state - uint8 _VKKeyState[NumKeys]; - // tells for which keys repetition is disabled - CBitSet _RepetitionDisabled; - // The date at which the last key pressed has been pressed (not using 64 bits since note handled by Direct Input) - uint32 _FirstPressDate; - // The last date at which key repetition occured (not using 64 bits since note handled by Direct Input) - uint32 _LastEmitDate; - // The system date at which the last polling occured (not using 64 bits since note handled by Direct Input) - uint32 _PollTime; - uint _LastDIKeyPressed; - CWinEventEmitter *_WE; - HWND _hWnd; - HKL _KBLayout; - // - CDIEventEmitter *_DIEventEmitter; - // - static const CKeyConv *DIKeyToNelKeyTab[NumKeys]; -private: - /// ctor - CDIKeyboard(CWinEventEmitter *we, HWND hwnd); - /** Convert a direct input scancode to a virtual key. Note that DirectInput scancodes do not always match system scan codes. - * Repeatable has a meaning only for extended keys - */ - TKey DIKeyToNelKey(uint diKey, bool &extKey, bool &repeatable); - /** This update virtual key state table. - * \param keyValue contains the value to send to a EventKeyDown or EventKeyUp message. - * \param charValue contains the value that must be used for Unicode conversion (which generate EventChar messages) - */ - void updateVKKeyState(uint diKey, bool pressed, TKey &keyValue, TKey &charValue); - // Use the given virtual key code and the current keyb state to produce Unicode - void sendUnicode(TKey vkey, uint dikey, CEventServer *server, bool pressed); - // Build a TKeyButton value from the state of shift, ctrl and alt - TKeyButton buildKeyButtonsFlags() const; - // Update the state of this object and send the appropriate message when a direct / input key has been pressed / released - void keyTriggered(bool pressed, uint key, CEventServer *server, uint32 date); - // The same as buildKeyButtonsFlags(), but the return is a TMouseButtonValue (with no mouse value setupped) - TMouseButton buildKeyboardButtonFlags() const; - // setup the state of the Ctrl, Alt and Shift key from the state in the _VKKeyState buffer - void updateCtrlAltShiftValues(); - /// Repeat the current key, and create events - void repeatKey(uint32 currentDate, CEventServer *server); - /// Build a date by using an event time stamp, or generate one if NULL - uint32 buildDateFromEvent(const IInputDeviceEvent *deviceEvent); - - ///\name From IInputDevice - //@{ - virtual void poll(CInputDeviceServer *dev); - virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server); - virtual void transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage); - //@} -}; - - -} // NLMISC - - -#endif // NL_OS_WINDOWS - -#endif // NL_DI_KEYBOARD_H - -/* End of di_keyboard.h */ diff --git a/code/nel/src/misc/di_mouse_device.cpp b/code/nel/src/misc/di_mouse_device.cpp deleted file mode 100644 index 273725c5c..000000000 --- a/code/nel/src/misc/di_mouse_device.cpp +++ /dev/null @@ -1,507 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" - -#include "di_mouse_device.h" -#include "nel/misc/game_device_events.h" -#include "nel/misc/win_event_emitter.h" - - -#ifdef NL_OS_WINDOWS - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -#ifdef NL_COMP_MINGW -# undef FIELD_OFFSET -# define FIELD_OFFSET(t,f) offsetof(t,f) -#endif - - -namespace NLMISC -{ - -//====================================================== -CDIMouse::CDIMouse() : _MessageMode(RawMode), - _MouseSpeed(1.0f), - _MouseAccel(10000), - _Mouse(NULL), - _XAcc(0), - _YAcc(0), - _XMousePos(0), - _YMousePos(0), - _LastMouseButtonClicked(-1), - _DoubleClickDelay(300), - _XFactor(1.f), - _YFactor(1.f), - OldDIXPos(0), - OldDIYPos(0), - OldDIZPos(0), - _FirstX(true), - _FirstY(true), - _SwapButton(false) - -{ - std::fill(_MouseButtons, _MouseButtons + MaxNumMouseButtons, false); - std::fill(_MouseAxisMode, _MouseAxisMode + NumMouseAxis, Raw); - _MouseFrame.setWH(0, 0, 640, 480); -} - -//====================================================== -CDIMouse::~CDIMouse() -{ - if (_Mouse) - { - _Mouse->Unacquire(); - _Mouse->Release(); - } -} - -//====================================================== -void CDIMouse::setMouseMode(TAxis axis, TAxisMode axisMode) -{ - nlassert(axisMode < AxisModeLast); - nlassert(axis < AxisLast); - _MouseAxisMode[axis] = axisMode; - clampMouseAxis(); -} - -//====================================================== -CDIMouse::TAxisMode CDIMouse::getMouseMode(TAxis axis) const -{ - nlassert((int)axis < (int)NumMouseAxis); - return _MouseAxisMode[axis]; -} - -//====================================================== -void CDIMouse::setMouseSpeed(float speed) -{ - nlassert(_MessageMode == NormalMode); - nlassert(speed > 0); - _MouseSpeed = speed; -} - -//====================================================== -void CDIMouse::setMouseAcceleration(uint accel) -{ - _MouseAccel = accel; -} - -//====================================================== -uint CDIMouse::getMouseAcceleration() const -{ - return _MouseAccel; -} - -//====================================================== -bool CDIMouse::setBufferSize(uint size) -{ - nlassert(size > 0); - nlassert(_Mouse); - _Mouse->Unacquire(); - DIPROPDWORD dipdw; - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = size; - HRESULT r = _Mouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ); - if (r != DI_OK) return false; - _MouseBufferSize = size; - return true; -} - -//====================================================== -uint CDIMouse::getBufferSize() const { return _MouseBufferSize; } - -//====================================================== -void CDIMouse::setMousePos(float x, float y) -{ - nlassert(_MessageMode == NormalMode); - _XMousePos = (sint64) ((double) x * ((sint64) 1 << 32)); - _YMousePos = (sint64) ((double) y * ((sint64) 1 << 32)); -} - -//====================================================== -CDIMouse *CDIMouse::createMouseDevice(IDirectInput8 *di8, HWND hwnd, CDIEventEmitter *diEventEmitter, bool hardware, CWinEventEmitter *we) throw(EDirectInput) -{ - std::auto_ptr mouse(new CDIMouse); - mouse->_DIEventEmitter = diEventEmitter; - mouse->_Hardware = hardware; - HRESULT result = di8->CreateDevice(GUID_SysMouse, &(mouse->_Mouse), NULL); - if (result != DI_OK) throw EDirectInputNoMouse(); - result = mouse->_Mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | (!hardware ? DISCL_EXCLUSIVE:DISCL_NONEXCLUSIVE)); - if (result != DI_OK) throw EDirectInputCooperativeLevelFailed(); - mouse->_Mouse->SetDataFormat(&c_dfDIMouse2); - mouse->setBufferSize(64); - mouse->_WE = we; - mouse->setDoubleClickDelay(::GetDoubleClickTime()); - - /** we want an absolute mouse mode, so that, if the event buffer get full, we can retrieve the right position - */ - DIPROPDWORD prop; - prop.diph.dwSize = sizeof(DIPROPDWORD); - prop.diph.dwHeaderSize = sizeof(DIPROPHEADER); - prop.diph.dwHow = DIPH_DEVICE; - prop.diph.dwObj = 0; - prop.dwData = DIPROPAXISMODE_ABS; - HRESULT r = mouse->_Mouse->SetProperty(DIPROP_AXISMODE, &prop.diph); - nlassert(r == DI_OK); // should always succeed... - // - mouse->_Mouse->Acquire(); - mouse->_hWnd = hwnd; - - // Enable win32 mouse message only if hardware mouse in normal mode - if (mouse->_WE) - mouse->_WE->enableMouseEvents(mouse->_Hardware && (mouse->_MessageMode == IMouseDevice::NormalMode)); - - mouse->_SwapButton = GetSystemMetrics(SM_SWAPBUTTON) != 0; - - return mouse.release(); -} - -//====================================================== -float CDIMouse::getMouseSpeed() const -{ - nlassert(_MessageMode == NormalMode); - return _MouseSpeed; -} - -//====================================================== -const CRect &CDIMouse::getMouseFrame() const -{ - nlassert(_MessageMode == NormalMode); - return _MouseFrame; -} - -//====================================================== -uint CDIMouse::getDoubleClickDelay() const { return _DoubleClickDelay; } - -//====================================================== -inline void CDIMouse::clampMouseAxis() -{ - if (_MouseAxisMode[XAxis] == Clamped) clamp(_XMousePos, (sint64) _MouseFrame.X << 32, (sint64) (_MouseFrame.X + _MouseFrame.Width - 1) << 32); - if (_MouseAxisMode[YAxis] == Clamped) clamp(_YMousePos, (sint64) _MouseFrame.Y << 32, (sint64) (_MouseFrame.X + _MouseFrame.Height - 1) << 32); -} - -//====================================================== -void CDIMouse::poll(CInputDeviceServer *dev) -{ - nlassert(_Mouse); - nlassert(_MouseBufferSize > 0); - static std::vector datas; - datas.resize(_MouseBufferSize); - DWORD numElements = _MouseBufferSize; - HRESULT result = _Mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0); - if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST) - { - result = _Mouse->Acquire(); - HRESULT result = _Mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0); - if (result != DI_OK) return; - } - else if (result != DI_OK) return; - - if (::IsWindowEnabled(_hWnd) && ::IsWindowVisible(_hWnd)) - { - for(uint k = 0; k < numElements; ++k) - { - CDIEvent *die = new CDIEvent; - die->Emitter = this; - die->Datas = datas[k]; - dev->submitEvent(die); - } - } -} - - -//====================================================================== -TMouseButton CDIMouse::buildMouseButtonFlags() const -{ - if (_SwapButton) - return (TMouseButton) ( - _DIEventEmitter->buildKeyboardButtonFlags() - | (_MouseButtons[0] ? rightButton : 0) - | (_MouseButtons[1] ? leftButton : 0) - | (_MouseButtons[2] ? middleButton : 0) - ); - else - return (TMouseButton) ( - _DIEventEmitter->buildKeyboardButtonFlags() - | (_MouseButtons[0] ? leftButton : 0) - | (_MouseButtons[1] ? rightButton : 0) - | (_MouseButtons[2] ? middleButton : 0) - ); -} - -//====================================================== -TMouseButton CDIMouse::buildMouseSingleButtonFlags(uint button) -{ - static const TMouseButton mb[] = { leftButton, rightButton, middleButton }; - static const TMouseButton mbswap[] = { rightButton, leftButton, middleButton }; - nlassert(button < MaxNumMouseButtons); - if (_SwapButton) - return (TMouseButton) (_DIEventEmitter->buildKeyboardButtonFlags() | mbswap[button]); - else - return (TMouseButton) (_DIEventEmitter->buildKeyboardButtonFlags() | mb[button]); -} - -//====================================================== -void CDIMouse::onButtonClicked(uint button, CEventServer *server, uint32 date) -{ - // check for double click - if (_LastMouseButtonClicked == (sint) button) - { - if (date - _MouseButtonsLastClickDate < _DoubleClickDelay) - { - CEventMouseDblClk *emdc - = new CEventMouseDblClk((float) (_XMousePos >> 32), - (float) (_YMousePos >> 32), - buildMouseSingleButtonFlags(button), - _DIEventEmitter); - server->postEvent(emdc); - _LastMouseButtonClicked = -1; - } - else - { - _MouseButtonsLastClickDate = date; - } - } - else - { - _LastMouseButtonClicked = button; - _MouseButtonsLastClickDate = date; - } -} - -//====================================================== -void CDIMouse::processButton(uint button, bool pressed, CEventServer *server, uint32 date) -{ - updateMove(server); - float mx = (float) (_XFactor * (double) _XMousePos / ((double) 65536 * (double) 65536)); - float my = (float) (_YFactor * (double) _YMousePos / ((double) 65536 * (double) 65536)); - if (pressed) - { - CEventMouseDown *emd = - new CEventMouseDown(mx, my, buildMouseSingleButtonFlags(button), - _DIEventEmitter); - server->postEvent(emd); - } - else - { - CEventMouseUp *emu = - new CEventMouseUp(mx, my, buildMouseSingleButtonFlags(button), _DIEventEmitter); - server->postEvent(emu); - onButtonClicked(button, server, date); - } - _MouseButtons[button] = pressed; -} - -//====================================================== -void CDIMouse::submit(IInputDeviceEvent *deviceEvent, CEventServer *server) -{ - if (!_Hardware || (_MessageMode == RawMode)) - { - CDIEvent *die = safe_cast(deviceEvent); - bool pressed; - switch(die->Datas.dwOfs) - { - case DIMOFS_X: - { - if (!_FirstX) - { - sint dep = (sint32) die->Datas.dwData - OldDIXPos; - - // Acceleration - if (_MouseAccel) - { - sint accelFactor = abs (dep) / (sint)_MouseAccel; - dep <<= accelFactor; - } - - _XAcc += dep; - } - else - { - _FirstX = false; - } - OldDIXPos = (sint32) die->Datas.dwData; - } - break; - case DIMOFS_Y: - { - if (!_FirstY) - { - sint dep = (sint32) die->Datas.dwData - OldDIYPos; - - // Acceleration - if (_MouseAccel) - { - sint accelFactor = abs (dep) / (sint)_MouseAccel; - dep <<= accelFactor; - } - - _YAcc -= dep; - } - else - { - _FirstY = false; - } - OldDIYPos = (sint32) die->Datas.dwData; - } - break; - case DIMOFS_Z: - { - updateMove(server); - sint dep = die->Datas.dwData - OldDIZPos; - OldDIZPos = (sint32) die->Datas.dwData; - CEventMouseWheel *emw = - new CEventMouseWheel((float) (_XMousePos >> 32), - (float) (_XMousePos >> 32), - buildMouseButtonFlags(), - dep > 0, - _DIEventEmitter); - server->postEvent(emw); - } - break; - case DIMOFS_BUTTON0: /* left button */ - pressed = (die->Datas.dwData & 0x80) != 0; - processButton(0, pressed, server, die->Datas.dwTimeStamp); - break; - case DIMOFS_BUTTON1: /* right button */ - pressed = (die->Datas.dwData & 0x80) != 0; - processButton(1, pressed, server, die->Datas.dwTimeStamp); - break; - case DIMOFS_BUTTON2: /* middle button */ - pressed = (die->Datas.dwData & 0x80) != 0; - processButton(2, pressed, server, die->Datas.dwTimeStamp); - break; - default: - return; - break; - } - } -} - -//====================================================== -void CDIMouse::updateMove(CEventServer *server) -{ - if (_XAcc != 0 || _YAcc != 0) - { - if (_MessageMode == NormalMode) - { - _XMousePos += (sint64) ((double) _MouseSpeed * (sint64) _XAcc * ((sint64) 1 << 32)); - _YMousePos += (sint64) ((double) _MouseSpeed * (sint64) _YAcc * ((sint64) 1 << 32)); - clampMouseAxis(); - CEventMouseMove *emm = new CEventMouseMove((float) (_XFactor * (double) _XMousePos / ((double) 65536 * (double) 65536)), (float) (_YFactor * (double) _YMousePos / ((double) 65536 * (double) 65536)), buildMouseButtonFlags(), _DIEventEmitter); - server->postEvent(emm); - } - else - { - CGDMouseMove *emm = new CGDMouseMove(_DIEventEmitter, this, _XAcc, _YAcc); - server->postEvent(emm); - } - _XAcc = _YAcc = 0; - } -} - - -//====================================================== -void CDIMouse::convertStdMouseMoveInMickeys(float &dx, float &dy) const -{ - // get in same scale as _XAcc and _YAcc - double xacc= ((double)dx/_XFactor) / _MouseSpeed; - double yacc= ((double)dy/_YFactor) / _MouseSpeed; - - dx= float(xacc); - dy =float(yacc); -} - - -//====================================================== -void CDIMouse::transitionOccured(CEventServer *server, const IInputDeviceEvent *) -{ - updateMove(server); -} - -//====================================================== -void CDIMouse::setButton(uint button, bool pushed) -{ - nlassert(button < MaxNumMouseButtons); - _MouseButtons[button] = pushed; -} - -//====================================================== -bool CDIMouse::getButton(uint button) const -{ - nlassert(button < MaxNumMouseButtons); - return _MouseButtons[button]; -} - -//====================================================== -void CDIMouse::setDoubleClickDelay(uint ms) -{ - nlassert(ms > 0); - _DoubleClickDelay = ms; -} - -//====================================================== -void CDIMouse::setMouseFrame(const CRect &rect) -{ - nlassert(_MessageMode == NormalMode); - _MouseFrame = rect; -} - -//====================================================== -void CDIMouse::setMessagesMode(TMessageMode mode) -{ - nlassert(mode < MessageModeLast); - _MessageMode = mode; - _FirstX = _FirstY = true; - - // Enable win32 mouse message only if hardware mouse in normal mode - if (_WE) - _WE->enableMouseEvents(_Hardware && (_MessageMode == NormalMode)); -} - - -} // NLMISC - -#endif // NL_OS_WINDOWS - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/nel/src/misc/di_mouse_device.h b/code/nel/src/misc/di_mouse_device.h deleted file mode 100644 index aab678ffc..000000000 --- a/code/nel/src/misc/di_mouse_device.h +++ /dev/null @@ -1,167 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_DI_MOUSE_DEVICE_H -#define NL_DI_MOUSE_DEVICE_H - -#include "nel/misc/types_nl.h" - -#ifdef NL_OS_WINDOWS - - -#include "nel/misc/rect.h" -#include "nel/misc/di_event_emitter.h" -#include "nel/misc/input_device_server.h" -#include "nel/misc/mouse_device.h" -#include - - -namespace NLMISC -{ - - -// -struct EDirectInputNoMouse : public EDirectInput -{ - EDirectInputNoMouse() : EDirectInput("No mouse found") {} -}; - - -class CDXEventEmitter; - - -/** - * Direct Input implementation of a mouse - * \see CDIEventEmitter - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2002 - */ -class CDIMouse : public IMouseDevice -{ -public: - enum { MaxNumMouseButtons = 3, NumMouseAxis = 3}; -public: - ///\name Object - //@{ - virtual ~CDIMouse(); - /** Create a mouse device from a valid DirectInput8 pointer. This must then be deleted by the caller. - * \return the interface or throw an exception if the creation failed - */ - static CDIMouse *createMouseDevice(IDirectInput8 *di8, HWND hwnd, CDIEventEmitter *diEventEmitter, bool hardware, class CWinEventEmitter *we) throw(EDirectInput); - //@} - - ///\name Mouse params, inherited from IMouseDevice - //@{ - void setMessagesMode(TMessageMode mode); - TMessageMode getMessagesMode() const { return _MessageMode; } - void setMouseMode(TAxis axis, TAxisMode axisMode); - TAxisMode getMouseMode(TAxis axis) const; - void setMouseSpeed(float speed); - float getMouseSpeed() const; - void setMouseAcceleration(uint speed); - uint getMouseAcceleration() const; - void setMouseFrame(const CRect &rect); - const CRect &getMouseFrame() const; - void setDoubleClickDelay(uint ms); - uint getDoubleClickDelay() const; - void setMousePos(float x, float y); - void setFactors(float xFactor, float yFactor) - { - nlassert(_MessageMode == NormalMode); - _XFactor = xFactor; - _YFactor = yFactor; - } - float getXFactor() const { nlassert(_MessageMode == NormalMode); return _XFactor; } - float getYFactor() const { nlassert(_MessageMode == NormalMode); return _YFactor; } - void convertStdMouseMoveInMickeys(float &dx, float &dy) const; - //@} - - ///\name From IInputDevice - //@{ - - virtual bool setBufferSize(uint size); - virtual uint getBufferSize() const; - //@} - - ///\name From IInputDevice - //@{ - void setButton(uint button, bool pushed); - bool getButton(uint button) const; - //@} - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// - -private: - LPDIRECTINPUTDEVICE8 _Mouse; - // - bool _Hardware; - // - TMessageMode _MessageMode; - // - TAxisMode _MouseAxisMode[NumMouseAxis]; - sint64 _XMousePos, _YMousePos; // position encoded in fixed point 32 : 32. This allow wrapping and no loss of precision, when not in clamped mode - // NB: this is sint64 because of max range reached with 16:16 when looping around x with great mouse speed - bool _FirstX, _FirstY; - float _MouseSpeed; - uint _MouseAccel; - CRect _MouseFrame; - // - bool _MouseButtons[MaxNumMouseButtons]; - uint32 _MouseButtonsLastClickDate; - sint _LastMouseButtonClicked; - uint _DoubleClickDelay; - uint _MouseBufferSize; - HWND _hWnd; - // - sint32 OldDIXPos, OldDIYPos, OldDIZPos; // old positions reported by direct input - sint _XAcc, _YAcc; // accumulate move (needed because they are generated on a single axis for each DI event) - float _XFactor, _YFactor; - // - CDIEventEmitter *_DIEventEmitter; - // The windows emitter to enable / disble win32 mouse messages - NLMISC::CRefPtr _WE; - // Does the button left and right are swapped ? - bool _SwapButton; -private: - /// ctor - CDIMouse(); - /// Clamp the mouse axis that need to be. - void clampMouseAxis(); - /// Sum the mouse move and produce an event - void updateMove(CEventServer *server); - void processButton(uint button, bool pressed, CEventServer *server, uint32 date); - TMouseButton buildMouseButtonFlags() const; - TMouseButton buildMouseSingleButtonFlags(uint button); - void onButtonClicked(uint button, CEventServer *server, uint32 date); - ///\name From IInputDevice - //@{ - virtual void poll(CInputDeviceServer *dev); - virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server); - virtual void transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage); - //@} -}; - - -} // NL3D - - -#endif // NL_OS_WINDOWS - -#endif // NL_DI_MOUSE_H - -/* End of di_mouse.h */ diff --git a/code/nel/src/misc/event_emitter_multi.cpp b/code/nel/src/misc/event_emitter_multi.cpp index 52bc235cd..45559ebc4 100644 --- a/code/nel/src/misc/event_emitter_multi.cpp +++ b/code/nel/src/misc/event_emitter_multi.cpp @@ -84,11 +84,6 @@ void CEventEmitterMulti::submitEvents(CEventServer &server, bool allWindows) } } -///============================================================ -void CEventEmitterMulti::emulateMouseRawMode(bool enable) -{ -} - ///============================================================ IEventEmitter *CEventEmitterMulti::getEmitter(uint index) { diff --git a/code/nel/src/misc/game_device.cpp b/code/nel/src/misc/game_device.cpp deleted file mode 100644 index 2ba49367f..000000000 --- a/code/nel/src/misc/game_device.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" -#include "nel/misc/game_device.h" - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC { - - - -} // NLMISC diff --git a/code/nel/src/misc/game_device_events.cpp b/code/nel/src/misc/game_device_events.cpp deleted file mode 100644 index bf64a1c4b..000000000 --- a/code/nel/src/misc/game_device_events.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" -#include "nel/misc/game_device_events.h" - - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ - -void dummyToAvoidStupidCompilerWarning_game_device_events_cpp() -{ - -} - -} // NLMISC diff --git a/code/nel/src/misc/input_device.cpp b/code/nel/src/misc/input_device.cpp deleted file mode 100644 index 3825935a6..000000000 --- a/code/nel/src/misc/input_device.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" -#include "nel/misc/input_device.h" - -// remove stupid VC6 warnings -void foo_input_device_cpp() {} - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ - - -} // NLMISC diff --git a/code/nel/src/misc/input_device_server.cpp b/code/nel/src/misc/input_device_server.cpp deleted file mode 100644 index 253b68e71..000000000 --- a/code/nel/src/misc/input_device_server.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" - -#include "nel/misc/input_device_server.h" -#include "nel/misc/input_device.h" -#include "nel/misc/debug.h" - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC -{ -//======================================================================= -void CInputDeviceServer::registerDevice(IInputDevice *device) -{ - nlassert(!isDevice(device)); - _Devices.push_back(device); -} - -//======================================================================= -void CInputDeviceServer::removeDevice(IInputDevice *device) -{ - TDeviceCont::iterator it = std::find(_Devices.begin(), _Devices.end(), device); - nlassert(it != _Devices.end()); - _Devices.erase(it); -} - -//======================================================================= -bool CInputDeviceServer::isDevice(IInputDevice *device) const -{ - TDeviceCont::const_iterator it = std::find(_Devices.begin(), _Devices.end(), device); - return it != _Devices.end(); -} - -//======================================================================= -// Predicate to compare vents dates -struct CInputDeviceEventLess -{ - bool operator()(const IInputDeviceEvent *lhs, const IInputDeviceEvent *rhs) const - { - return *lhs < *rhs; - } -}; - -//======================================================================= -void CInputDeviceServer::poll(CEventServer *server) -{ - nlassert(_Events.empty()); - TDeviceCont::iterator deviceIt; - for (deviceIt = _Devices.begin(); deviceIt != _Devices.end(); ++deviceIt) - { - (*deviceIt)->begin(server); - (*deviceIt)->poll(this); - } - // Sort the messages to get the right dates. - std::sort(_Events.begin(), _Events.end(), CInputDeviceEventLess()); - // submit the result to the server - IInputDevice *lastVisitedDevice = NULL; - TEventCont::iterator eventIt; - for (eventIt = _Events.begin(); eventIt != _Events.end(); ++eventIt) - { - // see if this message is from a previous device then the last we visited. - if (lastVisitedDevice && (*eventIt)->Emitter != lastVisitedDevice) - { - // yes, tells that a transition occured - lastVisitedDevice->transitionOccured(server, *eventIt); - lastVisitedDevice = (*eventIt)->Emitter; - } - nlassert((*eventIt)->Emitter != NULL); - (*eventIt)->Emitter->submit(*eventIt, server); - } - // - for (deviceIt = _Devices.begin(); deviceIt != _Devices.end(); ++deviceIt) - { - (*deviceIt)->transitionOccured(server, NULL); - } - // delete the messages - for (eventIt = _Events.begin(); eventIt != _Events.end(); ++eventIt) - { - delete *eventIt; - } - // - _Events.clear(); -} - -//======================================================================= -void CInputDeviceServer::submitEvent(IInputDeviceEvent *deviceEvent) -{ - _Events.push_back(deviceEvent); -} - - -} // NLMISC diff --git a/code/nel/src/misc/keyboard_device.cpp b/code/nel/src/misc/keyboard_device.cpp deleted file mode 100644 index 4c7f353bc..000000000 --- a/code/nel/src/misc/keyboard_device.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" - -//#include "nel/3d/u_keyboard_device.h" - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NL3D { - - -/* - * Constructor - */ -/*UKeyboardDevice::UKeyboardDevice() -{ -}*/ - - -} // NL3D diff --git a/code/nel/src/misc/win_event_emitter.cpp b/code/nel/src/misc/win_event_emitter.cpp index 3c74d9241..01da89564 100644 --- a/code/nel/src/misc/win_event_emitter.cpp +++ b/code/nel/src/misc/win_event_emitter.cpp @@ -57,14 +57,6 @@ void CWinEventEmitter::submitEvents(CEventServer & server, bool allWindows) _InternalServer.pump (allWindows); } -/*------------------------------------------------------------------*\ - emulateMouseRawMode() -\*------------------------------------------------------------------*/ -void CWinEventEmitter::emulateMouseRawMode(bool enable) -{ - nlerror("no raw mode emulation on windows, the CDIMouse has a real raw mode"); -} - /*------------------------------------------------------------------*\ processMessage() \*------------------------------------------------------------------*/ @@ -320,7 +312,7 @@ bool CWinEventEmitter::processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPA case WM_INPUTLANGCHANGE: if ( _IMEEventsEnabled ) { - // wParam = Specifies the character set of the new locale. + // wParam = Specifies the character set of the new locale. // lParam = Input locale identifier. server->postEvent( new CEventIME( msg, (uint32)wParam, (uint32)lParam, this ) ); return true; // trap message diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h index 0c01fa1ad..8c439f601 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/graphics_viewport.h @@ -75,7 +75,6 @@ private Q_SLOTS: void setBackgroundColor(); void submitEvents(NLMISC::CEventServer &server, bool allWindows) { } - void emulateMouseRawMode(bool) { } protected: virtual void resizeEvent(QResizeEvent *resizeEvent); diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index a42c7988b..1f42ad360 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -349,13 +349,6 @@ CClientConfig::CClientConfig() ForceDeltaTime = 0; // Default ForceDeltaTime, disabled by default -#ifdef NL_OS_WINDOWS - DisableDirectInput = false; // Default DisableDirectInput -#else - DisableDirectInput = true; // no direct input on linux -#endif - - DisableDirectInputKeyboard = true; // Default DisableDirectInput fort he keyboard only HardwareCursor = true; // Default HardwareCursor HardwareCursorScale = 0.85f; CursorSpeed = 1.f; // Default CursorSpeed @@ -857,8 +850,6 @@ void CClientConfig::setValues() //////////// // INPUTS // - READ_BOOL_FV(DisableDirectInput) - READ_BOOL_FV(DisableDirectInputKeyboard) READ_BOOL_FV(HardwareCursor) READ_FLOAT_FV(HardwareCursorScale) READ_FLOAT_FV(CursorSpeed) @@ -1969,16 +1960,16 @@ void CClientConfig::init(const string &configFileName) size_t endOfLine = contentUtf8.find("\n", pos); contentUtf8.erase(pos, (endOfLine - pos) + 1); } - + // get current location of the root config file (client_default.cfg) std::string defaultConfigLocation; if(!getDefaultConfigLocation(defaultConfigLocation)) nlerror("cannot find client_default.cfg"); - + // and store it in the RootConfigFilename value in the very first line - contentUtf8.insert(0, std::string("RootConfigFilename = \"") + + contentUtf8.insert(0, std::string("RootConfigFilename = \"") + defaultConfigLocation + "\";\n"); - + // save the updated config file NLMISC::COFile configFile(configFileName, false, true, false); configFile.serialBuffer((uint8*)contentUtf8.c_str(), (uint)contentUtf8.size()); @@ -2206,13 +2197,13 @@ ucstring CClientConfig::buildLoadingString( const ucstring& ucstr ) const } // *************************************************************************** -bool CClientConfig::getDefaultConfigLocation(std::string& p_name) const +bool CClientConfig::getDefaultConfigLocation(std::string& p_name) const { std::string defaultConfigFileName = "client_default.cfg"; std::string defaultConfigPath; - + p_name.clear(); - + #ifdef NL_OS_MAC // on mac, client_default.cfg should be searched in .app/Contents/Resources/ defaultConfigPath = CPath::standardizePath(getAppBundlePath() + "/Contents/Resources/"); diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index 44ddf3891..2b2b47c23 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -78,7 +78,7 @@ struct CClientConfig sint SelectCharacter; /// Selected slot in select char interface uint8 SelectedSlot; - + /// Textures for interface login std::vector TexturesLoginInterface; std::vector TexturesLoginInterfaceDXTC; @@ -190,8 +190,6 @@ struct CClientConfig /// \name Inputs /// Use a hardware cursor - bool DisableDirectInput; - bool DisableDirectInputKeyboard; bool HardwareCursor; float HardwareCursorScale; // scale for hardware cursor bitmap (in ]0, 1]) float CursorSpeed; diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 92b3acbe8..777b6a29c 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -116,6 +116,8 @@ extern void saveMovieShooting(); extern void displaySpecialTextProgress(const char *text); extern bool InitMouseWithCursor(bool hardware); +extern bool SetMousePosFirstTime; + ///////////// // Globals // initialization occurs in the function : connection ///////////// @@ -544,6 +546,7 @@ bool reconnection() if (ClientCfg.SelectCharacter == -1) { // Re-initialise the mouse (will be now in hardware mode, if required) + SetMousePosFirstTime = true; InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup // no ui init if character selection is automatic diff --git a/code/ryzom/client/src/events_listener.cpp b/code/ryzom/client/src/events_listener.cpp index 1d05f8a4e..a35fdbcb7 100644 --- a/code/ryzom/client/src/events_listener.cpp +++ b/code/ryzom/client/src/events_listener.cpp @@ -21,7 +21,6 @@ #include "events_listener.h" #include "nel/misc/events.h" -#include "nel/misc/game_device_events.h" #include "nel/misc/event_server.h" #include "release.h" #include "actions.h" @@ -29,11 +28,13 @@ #include "time_client.h" #include "input.h" #include "interface_v3/interface_manager.h" +#include "global.h" using namespace NLMISC; extern CActionsManager Actions; // Actions Manager. +extern bool MouseFreeLook; //--------------------------------------------------- // CEventsListener : @@ -82,7 +83,6 @@ CEventsListener::~CEventsListener() //--------------------------------------------------- void CEventsListener::addToServer(CEventServer& server) { - server.addListener(EventGDMouseMove, this); server.addListener(EventMouseMoveId, this); server.addListener(EventMouseDownId, this); server.addListener(EventMouseUpId, this); @@ -101,7 +101,6 @@ void CEventsListener::addToServer(CEventServer& server) //--------------------------------------------------- void CEventsListener::removeFromServer (CEventServer& server) { - server.removeListener(EventGDMouseMove, this); server.removeListener(EventMouseMoveId, this); server.removeListener(EventMouseDownId, this); server.removeListener(EventMouseUpId, this); @@ -113,6 +112,12 @@ void CEventsListener::removeFromServer (CEventServer& server) server.removeListener(EventSetFocusId, this); }// removeFromServer // +static bool s_MouseFreeLookReady = false; +static sint s_MouseFreeLookLastX; +static sint s_MouseFreeLookLastY; +static sint s_MouseFreeLookFrameX = 0; +static sint s_MouseFreeLookFrameY = 0; +static bool s_MouseFreeLookWaitCenter; //--------------------------------------------------- // operator() : @@ -148,20 +153,61 @@ void CEventsListener::operator()(const CEvent& event) { CAHManager::getInstance()->runActionHandler("enter_modal", NULL, "group=ui:interface:quit_dialog"); } - // Event from the Mouse (ANGLE) - if(event == EventGDMouseMove) - { - CGDMouseMove* mouseEvent=(CGDMouseMove*)&event; - // Mouse acceleration - sint dX = mouseEvent->X; - sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y; - updateFreeLookPos((float) dX, (float) dY); - } // Event from the Mouse (MOVE) else if(event == EventMouseMoveId) { CEventMouseMove* mouseEvent=(CEventMouseMove*)&event; - updateCursorPos(mouseEvent->X, mouseEvent->Y); + if (!MouseFreeLook) + { + updateCursorPos(mouseEvent->X, mouseEvent->Y); + s_MouseFreeLookReady = false; + } + else + { + // Get in pixel space, centered + uint32 drW, drH; + Driver->getWindowSize(drW, drH); + float fX = mouseEvent->X; // from 0 to 1.0 + float fY = (ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y); + sint scX = (sint32)(fX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered + sint scY = (sint32)(fY * (float)drH) - ((sint32)drH >> 1); + if (!s_MouseFreeLookReady) + { + float pfX = _MouseX; + float pfY = (ClientCfg.FreeLookInverted ? -_MouseY : _MouseY); + sint pscX = (sint32)(pfX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered + sint pscY = (sint32)(pfY * (float)drH) - ((sint32)drH >> 1); + s_MouseFreeLookReady = true; + s_MouseFreeLookLastX = pscX; + s_MouseFreeLookLastY = pscY; + s_MouseFreeLookWaitCenter = false; + } + if (s_MouseFreeLookWaitCenter && scX == 0 && scY == 0) + { + // Centered, ignore + s_MouseFreeLookLastX = 0; + s_MouseFreeLookLastY = 0; + } + else + { + // Get delta since last center + sint scXd = scX - s_MouseFreeLookLastX; + sint scYd = scY - s_MouseFreeLookLastY; + s_MouseFreeLookLastX = scX; + s_MouseFreeLookLastY = scY; + + s_MouseFreeLookFrameX += scXd; + s_MouseFreeLookFrameY += scYd; + // updateFreeLookPos is called in updateMouseSmoothing per frame + + // Center cursor + if (abs(scX) > (drW >> 3) || abs(scY) > (drH >> 3)) + { + s_MouseFreeLookWaitCenter = true; + Driver->setMousePos(0.5f, 0.5f); + } + } + } } // Event from the Mouse (DOWN BUTTONS) else if(event == EventMouseDownId) @@ -233,16 +279,9 @@ void CEventsListener::updateMouseSmoothing() { if (_LastFreeLookUpdateDate != TimeInSec) { - if (ClientCfg.FreeLookSmoothingPeriod != 0.f && _MouseSmoothingOn) - { - // free look hasn't been updated that frame because there was no - // mouse move msg. - // mouse pos must be updated however because of smoothing - updateFreeLookPos(0, 0); - - - - } + updateFreeLookPos((float)s_MouseFreeLookFrameX, (float)s_MouseFreeLookFrameY); + s_MouseFreeLookFrameX = 0; + s_MouseFreeLookFrameY = 0; } } @@ -267,7 +306,6 @@ void CEventsListener::enableMouseSmoothing(bool on) // *************************************************************** void CEventsListener::updateFreeLookPos(float x, float y) { - if (ClientCfg.FreeLookSmoothingPeriod == 0 || !_MouseSmoothingOn) { _MouseDeltaAX = x * ClientCfg.FreeLookSpeed; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 809232983..e985c958f 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1069,34 +1069,6 @@ void prelogInit() FPU_CHECKER_ONCE - // Test mouse & keyboard low-level mode, if DisableDirectInput not set. - // In case of failure, exit the client. - // In case of success, set it back to normal mode, to provide for the user - // the ability to manually set the firewall's permissions when the client connects. - // The low-level mode will actually be set when "launching" (after loading). - if (!ClientCfg.DisableDirectInput) - { - // Test mouse and set back to normal mode - if (!Driver->enableLowLevelMouse (true, ClientCfg.HardwareCursor)) - { - ExitClientError (CI18N::get ("can_t_initialise_the_mouse").toUtf8 ().c_str ()); - // ExitClientError() call exit() so the code after is never called - return; - } - Driver->enableLowLevelMouse (false, ClientCfg.HardwareCursor); - - // Test keyboard and set back to normal mode - // NB : keyboard will be initialized later now - /*if (!Driver->enableLowLevelKeyboard (true)) - { - ExitClientError (CI18N::get ("can_t_initialise_the_keyboard").toUtf8 ().c_str ()); - // ExitClientError() call exit() so the code after is never called - return; - } - Driver->enableLowLevelKeyboard (false); - */ - } - // Set the monitor color properties CMonitorColorProperties monitorColor; for ( uint i=0; i<3; i++) diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index b251689ea..c0da76a32 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -125,6 +125,8 @@ namespace R2 extern bool ReloadUIFlag; } +extern bool SetMousePosFirstTime; + extern EGSPD::CSeason::TSeason ManualSeasonValue; UTextureFile *LoadingBitmap = NULL; UTextureFile *LoadingBitmapFull = NULL; @@ -1253,6 +1255,7 @@ void initMainLoop() // NLMEMORY::CheckHeap (true); // Re-initialise the mouse (will be now in hardware mode, if required) + SetMousePosFirstTime = true; InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup // Re-initialise the keyboard, now in low-level mode, if required diff --git a/code/ryzom/client/src/input.cpp b/code/ryzom/client/src/input.cpp index eff4e2bc9..888d202bd 100644 --- a/code/ryzom/client/src/input.cpp +++ b/code/ryzom/client/src/input.cpp @@ -30,7 +30,6 @@ // 3D #include "nel/3d/u_driver.h" // Misc -#include "nel/misc/mouse_device.h" #include "nel/misc/mouse_smoother.h" #include "nel/misc/system_utils.h" // Game Share @@ -54,7 +53,6 @@ extern CActionsManager Actions; // Actions Manager. //////////// // GLOBAL // //////////// -IMouseDevice *MouseDevice = NULL; bool MouseHardware = false; bool MouseFreeLook = false; float MouseCursorSpeed = 1.f; @@ -81,93 +79,40 @@ bool InitMouseWithCursor (bool hardware) { Driver->showCursor(false); - // First init ? - if (MouseDevice) - { - // No.. change soft to hard or hard to soft ? - if (hardware ^ MouseHardware) - { - // Ok, reinit the mouse - Driver->enableLowLevelMouse (false, false); - MouseDevice = NULL; - MouseHardware = false; - } - } - // Get the new mouse state MouseHardware = hardware; CViewPointer::setHWMouse( hardware ); - // Reinit ? - if (MouseDevice == NULL) - { - if (!ClientCfg.DisableDirectInput) - { - // mouse capture not taken in account for hardware mouse - MouseDevice = Driver->enableLowLevelMouse(true, hardware); - if (!MouseDevice) - return false; - } - - // Update mouse information - UpdateMouse (); + // Update mouse information + UpdateMouse (); - if (InitMouseFirstTime) - { - InitMouseFirstTime = false; - } - else + if (InitMouseFirstTime) + { + InitMouseFirstTime = false; + } + else + { + if (!MouseFreeLook) { - if (!MouseFreeLook) + // Get the current mouse position + CInterfaceManager *pIm = CInterfaceManager::getInstance(); + CViewPointer *vp = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() ); + Driver->showCursor(hardware); + if (vp) { - // Get the current mouse position - if (hardware) + float x = (float) vp->getX(); + float y = (float) vp->getY(); + // First, hide the hardware mouse + uint width = Driver->getWindowWidth(); + uint height = Driver->getWindowHeight(); + if (SetMousePosFirstTime) { - Driver->showCursor(true); - - CViewPointer *pointer = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() ); - if (pointer) - { - float x = (float)pointer->getX()/(float)Driver->getWindowWidth(); - float y = (float)pointer->getY()/(float)Driver->getWindowHeight(); - - if (SetMousePosFirstTime) - { - SetMousePosFirstTime = false; - } - else - { - Driver->setMousePos(x, y); - nlwarning("mouse pos %f,%f", x, y); - } - - } + SetMousePosFirstTime = false; } - else + else if (width != 0 && height != 0) { - CInterfaceManager *pIm = CInterfaceManager::getInstance(); - CViewPointer *vp = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() ); - Driver->showCursor(false); - SetMousePosFirstTime = false; - if (vp) - { - float x = (float) vp->getX(); - float y = (float) vp->getY(); - // First, hide the hardware mouse - if (MouseDevice) - { - MouseDevice->setMousePos(x, y); - } - else - { - uint width = Driver->getWindowWidth(); - uint height = Driver->getWindowHeight(); - if (width != 0 && height != 0) - { - Driver->setMousePos(x / width, y / height); - } - } - } + nlwarning("mouse pos %u, %u", x, y); + Driver->setMousePos(x / width, y / height); } } } @@ -187,45 +132,6 @@ bool IsMouseCursorHardware () // Set the mouse mode. Call this method once per frame to update window size void UpdateMouse () { - // Freelook ? - if (MouseFreeLook) - { - // Raw mode - if (MouseDevice) - { - MouseDevice->setMessagesMode(IMouseDevice::RawMode); - MouseDevice->setMouseAcceleration(ClientCfg.FreeLookAcceleration); - } - else - { - // no mouse device implementation on X11 and Cocoa, emulate raw mode - Driver->emulateMouseRawMode(true); - } - } - else - { - // Set the mouse properties - if (MouseDevice) - { - // Get the driver size - uint32 width, height; - Driver->getWindowSize(width, height); - - MouseDevice->setMessagesMode(IMouseDevice::NormalMode); - MouseDevice->setMouseMode(IMouseDevice::XAxis, IMouseDevice::Clamped); - MouseDevice->setMouseMode(IMouseDevice::YAxis, IMouseDevice::Clamped); - CRect window (0, 0, width, height); - MouseDevice->setMouseFrame(window); - MouseDevice->setFactors(1.f/std::max((float)width, 1.0f), 1.f/std::max((float)height, 1.0f)); - MouseDevice->setMouseSpeed(MouseCursorSpeed); - MouseDevice->setMouseAcceleration(MouseCursorAcceleration); - } - else - { - // no mouse device implementation on X11 and Cocoa, emulate raw mode - Driver->emulateMouseRawMode(false); - } - } if (!Driver->isSystemCursorCaptured()) { DownMouseButtons = 0; @@ -303,19 +209,7 @@ void SetMouseCursor (bool updatePos) if (updatePos) { - if (MouseDevice) - { - MouseDevice->setMousePos((float)ix, (float)iy); - } - else - { - Driver->setMousePos(x, y); - } - - if (MouseHardware) - { - Driver->setMousePos(x, y); - } + Driver->setMousePos(x, y); } // Update the interface pointer @@ -404,25 +298,18 @@ CNiceInputAuto::CNiceInputAuto() { if (_Count == 0) { - - Driver->enableLowLevelMouse(false, false); // but ignore direct input (win 32 msg only) - - Driver->setCursor("curs_default.tga", CRGBA::White, 0, 0x15, 0x18); Driver->showCursor(true); // keep cursor visible in windowed mode - MouseDevice = NULL; - Driver->enableLowLevelKeyboard (false); } - ++ _Count; + ++_Count; } CNiceInputAuto::~CNiceInputAuto() { - -- _Count; + --_Count; nlassert(_Count >= 0); if (_Count == 0) { - InitMouseWithCursor (ClientCfg.HardwareCursor); - Driver->enableLowLevelKeyboard (!ClientCfg.DisableDirectInputKeyboard); // the return value has already been tested at startup + InitMouseWithCursor(ClientCfg.HardwareCursor); } } diff --git a/code/ryzom/client/src/interface_v3/input_handler_manager.cpp b/code/ryzom/client/src/interface_v3/input_handler_manager.cpp index 62eac876c..48582652a 100644 --- a/code/ryzom/client/src/interface_v3/input_handler_manager.cpp +++ b/code/ryzom/client/src/interface_v3/input_handler_manager.cpp @@ -20,7 +20,6 @@ #include "nel/misc/i_xml.h" #include "nel/misc/file.h" -#include "nel/misc/game_device_events.h" #include "nel/misc/xml_auto_ptr.h" @@ -92,7 +91,6 @@ void CInputHandlerManager::addToServer(NLMISC::CEventServer * server) _EventServer = server; // System - server->addListener(EventGDMouseMove, this); server->addListener(EventDestroyWindowId, this); server->addListener(EventCloseWindowId, this); server->addListener(EventSetFocusId, this); @@ -117,7 +115,6 @@ void CInputHandlerManager::addToServer(NLMISC::CEventServer * server) void CInputHandlerManager::release() { // System - _EventServer->removeListener(EventGDMouseMove, this); _EventServer->removeListener(EventDestroyWindowId, this); _EventServer->removeListener(EventCloseWindowId, this); _EventServer->removeListener(EventSetFocusId, this); @@ -304,7 +301,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event) handled |= R2::getEditor().handleEvent(eventDesc); } } - handled |= inputHandler.handleMouseButtonDownEvent( event ); + handled |= inputHandler.handleMouseButtonDownEvent( event ); } // button up ? else if (event==EventMouseUpId) diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 45e3fea51..ff199eace 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -73,6 +73,8 @@ using namespace std; // *************************************************************************** +extern bool SetMousePosFirstTime; + vector Shards; string LoginLogin, LoginPassword, ClientApp, Salt; @@ -114,7 +116,7 @@ vector R2PatchURLs; #define CTRL_EDITBOX_CREATEACCOUNT_LOGIN "ui:login:create_account:content:submit_gr:eb_login:eb" #define CTRL_EDITBOX_CREATEACCOUNT_PASSWORD "ui:login:create_account:content:submit_gr:eb_password:eb" #define CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD "ui:login:create_account:content:submit_gr:eb_confirm_password:eb" -#define CTRL_EDITBOX_CREATEACCOUNT_EMAIL "ui:login:create_account:content:submit_gr:eb_email:eb" +#define CTRL_EDITBOX_CREATEACCOUNT_EMAIL "ui:login:create_account:content:submit_gr:eb_email:eb" #define UI_VARIABLES_SCREEN_CHECKPASS 0 #define UI_VARIABLES_SCREEN_SHARDDISP 1 @@ -857,16 +859,15 @@ bool login() IngameDbMngr.flushObserverCalls(); NLGUI::CDBManager::getInstance()->flushObserverCalls(); - bool tmpDI = ClientCfg.DisableDirectInput; - ClientCfg.DisableDirectInput = true; + SetMousePosFirstTime = true; InitMouseWithCursor(false); Driver->showCursor (false); SetMouseFreeLook (); SetMouseCursor (false); SetMouseSpeed (ClientCfg.CursorSpeed); SetMouseAcceleration (ClientCfg.CursorAcceleration); + SetMousePosFirstTime = true; InitMouseWithCursor (ClientCfg.HardwareCursor); - ClientCfg.DisableDirectInput = tmpDI; // if (ClientCfg.TestBrowser) // { @@ -2410,7 +2411,7 @@ bool initCreateAccount() rulesGr->setActive(false); // must be done after hide rules - CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_CREATEACCOUNT_LOGIN "|select_all=false"); + CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_CREATEACCOUNT_LOGIN "|select_all=false"); } diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index bd5112f99..695f87bf8 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -661,7 +661,7 @@ void updateWeather() updateClouds(); } #endif - + ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), MainFogState); // TODO: ZBuffer clear was originally before this, but should not be necessary normally. @@ -687,7 +687,7 @@ void updateWeather() Driver->setPolygonMode(oldMode); } #endif - + // FIXME: temporary fix for teleportation crash // Update new sky if (ContinentMngr.cur() && Driver->getPolygonMode() == UDriver::Filled && Filter3D[FilterSky]) @@ -1392,7 +1392,7 @@ bool mainLoop() MainCam.setPos(mat.getPos()); MainCam.setRotQuat(mat.getRot()); } - if (StereoDisplay) + if (StereoDisplay) { StereoDisplay->updateCamera(0, &MainCam); if (SceneRoot) @@ -1591,12 +1591,12 @@ bool mainLoop() { // Update water env map (happens when continent changed etc) updateWaterEnvMap(); - + // Update weather updateWeather(); } } - + uint i = 0; uint bloomStage = 0; while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) @@ -1630,13 +1630,13 @@ bool mainLoop() // Commit camera changes commitCamera(); - + ////////////////////////// // RENDER THE FRAME 3D // ////////////////////////// bool stereoRenderTarget = (StereoDisplay != NULL) && StereoDisplay->beginRenderTarget(); - + if (!StereoDisplay || StereoDisplay->wantClear()) { if (Render) @@ -1672,7 +1672,7 @@ bool mainLoop() s_ForceFullDetail.backup(); s_ForceFullDetail.set(); } - + // Render scene renderScene(); @@ -2441,7 +2441,7 @@ bool mainLoop() connectionState = NetMngr.getConnectionState(); CLuaManager::getInstance().executeLuaScript("game:onFarTpEnd()"); - } + } /////////////// // <- FAR_TP // /////////////// @@ -3179,7 +3179,7 @@ NLMISC_COMMAND(debugUI, "Debug the ui : show/hide quads of bboxs and hotspots", else fromString(args[0], on); } - + CGroupCell::setDebugUICell( on ); DebugUIView = on; DebugUICtrl = on; diff --git a/code/ryzom/client/src/motion/user_controls.cpp b/code/ryzom/client/src/motion/user_controls.cpp index 527bfb5d4..285848120 100644 --- a/code/ryzom/client/src/motion/user_controls.cpp +++ b/code/ryzom/client/src/motion/user_controls.cpp @@ -414,7 +414,6 @@ void CUserControls::keyboardRotationCameraLR (bool left, bool right) _RotateCameraLRVelocity = 0; } - //----------------------------------------------- // getMouseAngleMove //----------------------------------------------- @@ -424,13 +423,9 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy) dy = 0.0f; // The mouse may still "StandardMove" ie through a CEventMouseMove - // This can happens cause DirectInputDisabled, or because of the - // "Rotation Anti-Lag system" which start to rotate before the mouse is hid - // and message mode passed to RawMode - // - // On X11 and Cocoa, there is no MouseDevice, do it without. - - extern IMouseDevice *MouseDevice; + // This can happen because of the "Rotation Anti-Lag system" which + // start to rotate before the mouse is hid and message mode passed + // to updateFreeLookPos // if the mouse position changed if( EventsListener.getMousePosX() != _LastFrameMousePosX || @@ -441,28 +436,23 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy) float dmpy= EventsListener.getMousePosY() - _LastFrameMousePosY; // simulate mickeys mode if there is a mouse device - if (MouseDevice) - MouseDevice->convertStdMouseMoveInMickeys(dmpx, dmpy); - else - { - dmpx *= (float)Driver->getWindowWidth(); - dmpy *= (float)Driver->getWindowHeight(); - } + dmpx *= (float)Driver->getWindowWidth(); + dmpy *= (float)Driver->getWindowHeight(); // handle inverted mouse, if enabled - if(ClientCfg.FreeLookInverted) dmpy = -dmpy; - + if (ClientCfg.FreeLookInverted) dmpy = -dmpy; + // update free look EventsListener.updateFreeLookPos(dmpx, dmpy); } // If the mouse move on the axis X, with a CGDMouseMove - if(EventsListener.isMouseAngleX()) - dx = -EventsListener.getMouseAngleX (); + if (EventsListener.isMouseAngleX()) + dx = -EventsListener.getMouseAngleX(); // If the mouse move on the axis Y, with a CGDMouseMove - if(EventsListener.isMouseAngleY()) - dy = EventsListener.getMouseAngleY (); + if (EventsListener.isMouseAngleY()) + dy = EventsListener.getMouseAngleY(); } @@ -1294,7 +1284,6 @@ void CUserControls::commonSetView() } } - //----------------------------------------------- // startFreeLook() //----------------------------------------------- diff --git a/code/ryzom/client/src/stdpch.h b/code/ryzom/client/src/stdpch.h index 5f046fcfe..96a509e0f 100644 --- a/code/ryzom/client/src/stdpch.h +++ b/code/ryzom/client/src/stdpch.h @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include From 496f7f268cfe3246b25f46e16676bd488acceccb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 12 Jul 2014 17:17:24 +0200 Subject: [PATCH 007/240] Trash DirectInput --HG-- branch : game-device --- code/nel/include/nel/3d/driver.h | 4 - code/nel/include/nel/3d/u_driver.h | 3 - .../3d/driver/direct3d/driver_direct3d.cpp | 21 --- .../src/3d/driver/direct3d/driver_direct3d.h | 5 - .../direct3d/driver_direct3d_inputs.cpp | 115 -------------- .../src/3d/driver/opengl/driver_opengl.cpp | 8 - code/nel/src/3d/driver/opengl/driver_opengl.h | 8 - .../3d/driver/opengl/driver_opengl_inputs.cpp | 143 ------------------ .../3d/driver/opengl/driver_opengl_window.cpp | 14 -- code/ryzom/client/src/main_loop.cpp | 1 - 10 files changed, 322 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 8c7d0ef1c..cb6ec349c 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -866,10 +866,6 @@ public: /// x and y must be between 0.0 and 1.0 virtual void setMousePos(float x, float y) = 0; - /** Get the delay in ms for mouse double clicks. - */ - virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; - /** If true, capture the mouse to force it to stay under the window. * NB : this has no effects if a low level mouse is used */ diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index 8af6091e3..9e385a2f7 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -35,9 +35,6 @@ namespace NLMISC { - struct IMouseDevice; - struct IKeyboardDevice; - struct IInputDeviceManager; class CLog; } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 96937fa94..4da016135 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1637,20 +1637,6 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r // Setup the event emitter, and try to retrieve a direct input interface _EventEmitter.addEmitter(we, true /*must delete*/); // the main emitter - // Try to get direct input - try - { - NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _HWnd, we); - if (diee) - { - _EventEmitter.addEmitter(diee, true); - } - } - catch(const EDirectInput &e) - { - nlinfo(e.what()); - } - // Init some variables _ForceDXTCCompression = false; _AnisotropicFilter = 0; @@ -2010,13 +1996,6 @@ bool CDriverD3D::swapBuffers() // todo hulud volatile //_DeviceInterface->SetStreamSource(0, _VolatileVertexBufferRAM[1]->VertexBuffer, 0, 12); - // Is direct input running ? - if (_EventEmitter.getNumEmitters() > 1) - { - // flush direct input messages if any - NLMISC::safe_cast(_EventEmitter.getEmitter(1))->poll(); - } - // End now if (!endScene()) { diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 254b21871..8b8ac62df 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1033,11 +1033,6 @@ public: // Change default scale for all cursors virtual void setCursorScale(float scale); - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive); - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable); - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager(); - virtual uint getDoubleClickDelay(bool hardwareMouse); - // Lights virtual uint getMaxLight () const; virtual void setLight (uint8 num, const CLight& light); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp index dbfcd155a..f754b6357 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_inputs.cpp @@ -463,121 +463,6 @@ bool CDriverD3D::isSystemCursorCaptured() return GetCapture() == _HWnd; } -// *************************************************************************** -NLMISC::IMouseDevice* CDriverD3D::enableLowLevelMouse(bool enable, bool exclusive) -{ - H_AUTO_D3D(CDriverD3D_enableLowLevelMouse); - - NLMISC::IMouseDevice *res = NULL; - - NLMISC::CDIEventEmitter *diee = NULL; - - if (_EventEmitter.getNumEmitters() > 1) - diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - - if (enable) - { - try - { - if (diee) - res = diee->getMouseDevice(exclusive); - } - catch (const EDirectInput &) - { - } - } - else - { - if (diee) - diee->releaseMouse(); - } - - return res; -} - -// *************************************************************************** -NLMISC::IKeyboardDevice* CDriverD3D::enableLowLevelKeyboard(bool enable) -{ - H_AUTO_D3D(CDriverD3D_enableLowLevelKeyboard); - - NLMISC::IKeyboardDevice *res = NULL; - - NLMISC::CDIEventEmitter *diee = NULL; - - if (_EventEmitter.getNumEmitters() > 1) - diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - - if (enable) - { - try - { - if (diee) - res = diee->getKeyboardDevice(); - } - catch (const EDirectInput &) - { - } - } - else - { - if (diee) - diee->releaseKeyboard(); - } - - return res; -} - -// *************************************************************************** -NLMISC::IInputDeviceManager* CDriverD3D::getLowLevelInputDeviceManager() -{ - H_AUTO_D3D(CDriverD3D_getLowLevelInputDeviceManager); - - NLMISC::IInputDeviceManager *res = NULL; - - if (_EventEmitter.getNumEmitters() > 1) - res = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - - return res; -} - -// *************************************************************************** -uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse) -{ - H_AUTO_D3D(CDriverD3D_getDoubleClickDelay); - - uint res = 250; - - NLMISC::IMouseDevice *md = NULL; - - if (_EventEmitter.getNumEmitters() >= 2) - { - NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - if (diee->isMouseCreated()) - { - try - { - md = diee->getMouseDevice(hardwareMouse); - } - catch (const EDirectInput &) - { - // could not get device .. - } - } - } - - if (md) - { - res = md->getDoubleClickDelay(); - } - else - { - // try to read the good value from windows - res = ::GetDoubleClickTime(); - } - - return res; -} - bool CDriverD3D::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY) { return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index a6e3ad7b7..da047ad20 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -934,14 +934,6 @@ bool CDriverGL::swapBuffers() } #endif -#ifdef NL_OS_WINDOWS - if (_EventEmitter.getNumEmitters() > 1) // is direct input running ? - { - // flush direct input messages if any - NLMISC::safe_cast(_EventEmitter.getEmitter(1))->poll(); - } -#endif - if (!_WndActive) { if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 241b3bb95..ffefafdee 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -527,14 +527,6 @@ public: // Change default scale for all cursors virtual void setCursorScale(float scale); - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive); - - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable); - - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager(); - - virtual uint getDoubleClickDelay(bool hardwareMouse); - virtual void getWindowSize (uint32 &width, uint32 &height); virtual void getWindowPos (sint32 &x, sint32 &y); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp index 92b25baf4..cbd1bcd9a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp @@ -664,149 +664,6 @@ bool CDriverGL::isSystemCursorCaptured() #endif } -// *************************************************************************** -NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive) -{ - H_AUTO_OGL(CDriverGL_enableLowLevelMouse); - - NLMISC::IMouseDevice *res = NULL; - -#ifdef NL_OS_WINDOWS - - NLMISC::CDIEventEmitter *diee = NULL; - - if (_EventEmitter.getNumEmitters() > 1) - diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - - if (enable) - { - try - { - if (diee) - res = diee->getMouseDevice(exclusive); - } - catch (const EDirectInput &) - { - } - } - else - { - if (diee) - diee->releaseMouse(); - } - -#elif defined(NL_OS_MAC) -#elif defined (NL_OS_UNIX) -#endif - - return res; -} - -// *************************************************************************** -NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable) -{ - H_AUTO_OGL(CDriverGL_enableLowLevelKeyboard); - - NLMISC::IKeyboardDevice *res = NULL; - -#ifdef NL_OS_WINDOWS - - NLMISC::CDIEventEmitter *diee = NULL; - - if (_EventEmitter.getNumEmitters() > 1) - diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - - if (enable) - { - try - { - if (diee) - res = diee->getKeyboardDevice(); - } - catch (const EDirectInput &) - { - } - } - else - { - if (diee) - diee->releaseKeyboard(); - } - -#elif defined(NL_OS_MAC) -#elif defined (NL_OS_UNIX) -#endif - - return res; -} - -// *************************************************************************** -NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager() -{ - H_AUTO_OGL(CDriverGL_getLowLevelInputDeviceManager); - - NLMISC::IInputDeviceManager *res = NULL; - -#ifdef NL_OS_WINDOWS - - if (_EventEmitter.getNumEmitters() > 1) - res = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - -#elif defined(NL_OS_MAC) -#elif defined (NL_OS_UNIX) -#endif - - return res; -} - -// *************************************************************************** -uint CDriverGL::getDoubleClickDelay(bool hardwareMouse) -{ - H_AUTO_OGL(CDriverGL_getDoubleClickDelay); - - uint res = 250; - -#ifdef NL_OS_WINDOWS - - NLMISC::IMouseDevice *md = NULL; - - if (_EventEmitter.getNumEmitters() >= 2) - { - NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); - if (diee->isMouseCreated()) - { - try - { - md = diee->getMouseDevice(hardwareMouse); - } - catch (const EDirectInput &) - { - // could not get device .. - } - } - } - - if (md) - { - res = md->getDoubleClickDelay(); - } - else - { - // try to read the good value from windows - res = ::GetDoubleClickTime(); - } - -#elif defined(NL_OS_MAC) - // TODO: Missing Mac Implementation for getDoubleClickDelay -#elif defined (NL_OS_UNIX) - - // TODO for Linux - -#endif - - return res; -} - bool CDriverGL::getBestCursorSize(uint srcWidth, uint srcHeight, uint &dstWidth, uint &dstHeight) { #ifdef NL_OS_WINDOWS diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index e377554d0..03796206c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -938,20 +938,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re // setup the event emitter, and try to retrieve a direct input interface _EventEmitter.addEmitter(we, true /*must delete*/); // the main emitter - /// try to get direct input - try - { - NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _win, we); - if (diee) - { - _EventEmitter.addEmitter(diee, true); - } - } - catch(const EDirectInput &e) - { - nlinfo(e.what()); - } - #elif defined(NL_OS_MAC) if (wnd == EmptyWindow) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 695f87bf8..8eb1d68b9 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -165,7 +165,6 @@ using namespace std; // EXTERN // //////////// extern UDriver *Driver; -extern IMouseDevice *MouseDevice; extern UScene *Scene; extern UScene *SceneRoot; extern ULandscape *Landscape; From 7200d17801f8e52ffdc2b9ea73819a3b4e1535b1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 12 Jul 2014 17:47:00 +0200 Subject: [PATCH 008/240] HID: Adjust free look --HG-- branch : game-device --- code/ryzom/client/src/events_listener.cpp | 41 ++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/code/ryzom/client/src/events_listener.cpp b/code/ryzom/client/src/events_listener.cpp index a35fdbcb7..89963a2ab 100644 --- a/code/ryzom/client/src/events_listener.cpp +++ b/code/ryzom/client/src/events_listener.cpp @@ -182,30 +182,33 @@ void CEventsListener::operator()(const CEvent& event) s_MouseFreeLookLastY = pscY; s_MouseFreeLookWaitCenter = false; } - if (s_MouseFreeLookWaitCenter && scX == 0 && scY == 0) + + // NOTE: No 0, 0 center mouse message in Windows (lower mouse message rate), but safe to assume any movement messages are requeued relative to our new position + // In case free look bugs on other platform, we may need to push in our own message on setMousePos for Windows + if (s_MouseFreeLookWaitCenter) // scX == 0 && scY == 0) { - // Centered, ignore + // Centered, set last to 0 s_MouseFreeLookLastX = 0; s_MouseFreeLookLastY = 0; + s_MouseFreeLookWaitCenter = false; } - else + + // Get delta since last center + sint scXd = scX - s_MouseFreeLookLastX; + sint scYd = scY - s_MouseFreeLookLastY; + s_MouseFreeLookLastX = scX; + s_MouseFreeLookLastY = scY; + + s_MouseFreeLookFrameX += scXd; + s_MouseFreeLookFrameY += scYd; + // updateFreeLookPos is called in updateMouseSmoothing per frame + + // Center cursor + bool outsideBounds = ((abs(scX) > (drW >> 3)) || (abs(scY) > (drH >> 3))); + if (outsideBounds) { - // Get delta since last center - sint scXd = scX - s_MouseFreeLookLastX; - sint scYd = scY - s_MouseFreeLookLastY; - s_MouseFreeLookLastX = scX; - s_MouseFreeLookLastY = scY; - - s_MouseFreeLookFrameX += scXd; - s_MouseFreeLookFrameY += scYd; - // updateFreeLookPos is called in updateMouseSmoothing per frame - - // Center cursor - if (abs(scX) > (drW >> 3) || abs(scY) > (drH >> 3)) - { - s_MouseFreeLookWaitCenter = true; - Driver->setMousePos(0.5f, 0.5f); - } + s_MouseFreeLookWaitCenter = true; + Driver->setMousePos(0.5f, 0.5f); } } } From 99a3b93703f4c651605f5179d7f88ae61bb8a0c2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 14:44:16 +0200 Subject: [PATCH 009/240] Restored lost class names --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml | 1 + code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml | 1 + code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml | 1 + .../src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml | 1 + code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupList.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupModal.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTab.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTable.xml | 1 + code/studio/src/plugins/gui_editor/widgets/GroupTree.xml | 1 + code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml | 1 + .../src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewText.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml | 1 + code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml | 1 + .../studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml | 1 + 28 files changed, 28 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml index 12b82e7f6..c081f3dae 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlButton.xml @@ -2,6 +2,7 @@
CtrlButton CCtrlButton + button CtrlBaseButton false diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml index ea2ba6171..7ab3e2f48 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlColPick.xml @@ -2,6 +2,7 @@
CtrlColPick CCtrlColPick + colpick CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml index 1ad970f31..9f5fcfc60 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlScroll.xml @@ -2,6 +2,7 @@
CtrlScroll CCtrlScroll + scroll CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml b/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml index 624ded887..7d78fc6b9 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBGroupSelectNumber.xml @@ -2,6 +2,7 @@
DBGroupSelectNumber CDBGroupSelectNumber + select_number InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml index c7f644fa4..878f9b563 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewBar.xml @@ -2,6 +2,7 @@
DBViewBar CDBViewBar + bar ViewBitmap false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml index 8295c5f30..db635eb27 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewBar3.xml @@ -2,6 +2,7 @@
DBViewBar3 CDBViewBar3 + bar3 ViewBitmap false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml index 0c12445f9..1a659fd91 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewDigit.xml @@ -2,6 +2,7 @@
DBViewDigit CDBViewDigit + digit CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml index c1861df61..36a7d23ce 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewNumber.xml @@ -2,6 +2,7 @@
DBViewNumber CDBViewNumber + text_number ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml b/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml index c24379c96..c11c1a4cc 100644 --- a/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml +++ b/code/studio/src/plugins/gui_editor/widgets/DBViewQuantity.xml @@ -2,6 +2,7 @@
DBViewQuantity CDBViewQuantity + text_quantity ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml b/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml index 3d879a150..a3c9aade7 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupContainer.xml @@ -2,6 +2,7 @@
GroupContainer CGroupContainer + container InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml b/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml index 31ca205c7..578262a20 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupEditBox.xml @@ -2,6 +2,7 @@
GroupEditBox CGroupEditBox + edit_box InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml b/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml index 5f0521be8..894580734 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupHTML.xml @@ -2,6 +2,7 @@
GroupHTML CGroupHTML + html GroupScrollText false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml b/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml index cc96fd742..91dd73e36 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupHeader.xml @@ -2,6 +2,7 @@
GroupHeader CGroupHeader + header GroupList false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupList.xml b/code/studio/src/plugins/gui_editor/widgets/GroupList.xml index 3ca2db95c..569aa8d9d 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupList.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupList.xml @@ -2,6 +2,7 @@
GroupList CGroupList + list InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml b/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml index cdd42ba95..3bd0c5506 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupMenu.xml @@ -2,6 +2,7 @@
GroupMenu CGroupMenu + menu GroupModal false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml b/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml index 034e3025e..33bd6fd08 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupModal.xml @@ -2,6 +2,7 @@
GroupModal CGroupModal + modal GroupFrame false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml b/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml index 95719398d..53092a456 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupScrollText.xml @@ -2,6 +2,7 @@
GroupScrollText CGroupScrollText + scroll_text InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml index df148a0a3..e2e1a8bf1 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTab.xml @@ -2,6 +2,7 @@
GroupTab CGroupTab + tab InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml index 9fa957741..dfbc4e2a8 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTable.xml @@ -2,6 +2,7 @@
GroupTable CGroupTable + table InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml b/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml index 73b1dea3b..b20c74733 100644 --- a/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml +++ b/code/studio/src/plugins/gui_editor/widgets/GroupTree.xml @@ -2,6 +2,7 @@
GroupTree CGroupTree + tree InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml index ddcdf01e6..50f7c3e83 100644 --- a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml +++ b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroup.xml @@ -2,6 +2,7 @@
InterfaceGroup CInterfaceGroup + interface_group CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml index b095ecac5..6a35671cd 100644 --- a/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml +++ b/code/studio/src/plugins/gui_editor/widgets/InterfaceGroupWheel.xml @@ -2,6 +2,7 @@
InterfaceGroupWheel CInterfaceGroupWheel + group_wheel InterfaceGroup false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml index 21ef7daff..7d78f6c40 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewBitmap.xml @@ -2,6 +2,7 @@
ViewBitmap CViewBitmap + bitmap CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml b/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml index 8fc579675..461f69c55 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewBitmapCombo.xml @@ -2,6 +2,7 @@
ViewBitmapCombo CViewBitmapCombo + bitmap_combo CtrlBase false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml index 415c3167e..f515f7b3d 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml @@ -2,6 +2,7 @@
ViewText CViewText + text InterfaceElement false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml index cabd081f0..36aa68102 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextFormated.xml @@ -2,6 +2,7 @@
ViewTextFormated CViewTextFormated + text_formated ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml index 52e010ec6..43ac442c0 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextID.xml @@ -2,6 +2,7 @@
ViewTextID CViewTextID + text_id ViewText false diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml b/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml index af8dd54eb..32b08f156 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewTextIDFormated.xml @@ -2,6 +2,7 @@
ViewTextIDFormated CViewTextIDFormated + text_id_formated ViewTextID false From 7e16e95c3570dcfd28684703ff7a30a2d823560d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:26:38 +0200 Subject: [PATCH 010/240] CInterfaceParser in editor mode should look for files in the working directory first. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_parser.h | 8 +++++++ code/nel/include/nel/gui/parser.h | 1 + code/nel/src/gui/interface_parser.cpp | 24 +++++++++++++++---- .../plugins/gui_editor/gui_editor_window.cpp | 2 ++ .../src/plugins/gui_editor/nelgui_ctrl.cpp | 6 +++++ .../src/plugins/gui_editor/nelgui_ctrl.h | 2 ++ 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_parser.h b/code/nel/include/nel/gui/interface_parser.h index 2bf1df9a8..c1b3fa109 100644 --- a/code/nel/include/nel/gui/interface_parser.h +++ b/code/nel/include/nel/gui/interface_parser.h @@ -353,7 +353,15 @@ namespace NLGUI std::map< std::string, std::string > pointerSettings; std::map< std::string, std::map< std::string, std::string > > keySettings; + std::string _WorkDir; + public: + /// Sets the working directory, where files should be looked for + void setWorkDir( const std::string &workdir ){ _WorkDir = workdir; } + + /// Looks up a file in either the working directory or using CPath::lookup + std::string lookup( const std::string &file ); + void initLUA(); void uninitLUA(); bool isLuaInitialized() const{ return luaInitialized; } diff --git a/code/nel/include/nel/gui/parser.h b/code/nel/include/nel/gui/parser.h index db868f70d..0378c22ec 100644 --- a/code/nel/include/nel/gui/parser.h +++ b/code/nel/include/nel/gui/parser.h @@ -88,6 +88,7 @@ namespace NLGUI virtual bool serializePointerSettings( xmlNodePtr parentNode ) const = 0; virtual bool serializeKeySettings( xmlNodePtr parentNode ) const = 0; virtual CViewBase* createClass( const std::string &name ) = 0; + virtual void setWorkDir( const std::string &workdir ) = 0; }; } diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index b26a403c4..f052224ff 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -233,6 +233,22 @@ namespace NLGUI destStream.seek(0, NLMISC::IStream::begin); } + std::string CInterfaceParser::lookup( const std::string &file ) + { + std::string filename; + + if( editorMode && !_WorkDir.empty() ) + { + std::string wdpath = CPath::standardizePath( _WorkDir ) + file; + if( CFile::fileExists( wdpath ) ) + filename = wdpath; + } + if( filename.empty() ) + filename = CPath::lookup( file ); + + return filename; + } + // ---------------------------------------------------------------------------- bool CInterfaceParser::parseInterface (const std::vector & strings, bool reload, bool isFilename, bool checkInData) { @@ -270,7 +286,7 @@ namespace NLGUI { //get the first file document pointer firstFileName = *it; - string filename = CPath::lookup(firstFileName); + string filename = lookup( firstFileName ); bool isInData = false; string::size_type pos = filename.find ("@"); if (pos != string::npos) @@ -283,7 +299,7 @@ namespace NLGUI isInData = true; } - if ((needCheck && !isInData) || !file.open (CPath::lookup(firstFileName))) + if ((needCheck && !isInData) || !file.open (lookup(firstFileName))) { // todo hulud interface syntax error nlwarning ("could not open file %s, skipping xml parsing",firstFileName.c_str()); @@ -331,7 +347,7 @@ namespace NLGUI { saveParseResult = true; std::string archive = CPath::lookup(nextFileName + "_compressed", false, false); - std::string current = CPath::lookup(nextFileName, false, false); + std::string current = lookup(nextFileName); if (!archive.empty() && !current.empty()) { if (CFile::getFileModificationDate(current) <= CFile::getFileModificationDate(archive)) @@ -351,7 +367,7 @@ namespace NLGUI { if (isFilename) { - if (!file.open(CPath::lookup(nextFileName, false, false))) + if (!file.open(lookup(nextFileName))) { // todo hulud interface syntax error nlwarning ("could not open file %s, skipping xml parsing",nextFileName.c_str()); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index ca5e240e7..5b3d835a2 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -181,6 +181,8 @@ namespace GUIEditor currentProject = projectFiles.projectName.c_str(); currentProjectFile = fileName; projectWindow->setupFiles( projectFiles ); + GUICtrl->setWorkDir( _lastDir ); + if( GUICtrl->parse( projectFiles ) ) { hierarchyView->buildHierarchy( projectFiles.masterGroup ); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index 03f784944..8f0f56711 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -187,6 +187,12 @@ namespace GUIEditor } } + void NelGUICtrl::setWorkDir( const QString &dir ) + { + IParser *parser = CWidgetManager::getInstance()->getParser(); + parser->setWorkDir( std::string( dir.toUtf8().constData() ) ); + } + QWidget* NelGUICtrl::getViewPort() { return w; diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index b3c68ff32..63118d947 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -52,6 +52,8 @@ namespace GUIEditor void show(); void hide(); + void setWorkDir( const QString &dir ); + Q_SIGNALS: void guiLoadComplete(); From 816e89c967874194b5f6c705a521af8024aa5403 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:40:41 +0200 Subject: [PATCH 011/240] Another classname. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml index ca66dbd62..6ad8334c5 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml @@ -2,6 +2,7 @@
CtrlTextButton CCtrlTextButton + text_button CtrlBaseButton false From 5217b38f58fd9e6e6b45ceb90386852bd430d400 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 16:47:39 +0200 Subject: [PATCH 012/240] Some defaults. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/widgets/CtrlTextButton.xml | 10 +++++----- .../studio/src/plugins/gui_editor/widgets/ViewText.xml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml index 6ad8334c5..6afd06cdf 100644 --- a/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml +++ b/code/studio/src/plugins/gui_editor/widgets/CtrlTextButton.xml @@ -12,22 +12,22 @@ tx_normal string - + but tx_pushed string - + but tx_over string - + but_over hardtext string - + push me wmargin @@ -157,7 +157,7 @@ line_maxw int - 0 + 100 multi_line_space diff --git a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml index f515f7b3d..4862517aa 100644 --- a/code/studio/src/plugins/gui_editor/widgets/ViewText.xml +++ b/code/studio/src/plugins/gui_editor/widgets/ViewText.xml @@ -47,7 +47,7 @@ line_maxw int - 0 + 100 multi_line_space @@ -102,7 +102,7 @@ hardtext string - + Some text hardtext_format From 03c041310ec73d37e3ac285dbf57189139ac039e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 18:56:24 +0200 Subject: [PATCH 013/240] Added dialog for the new GUI action. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/CMakeLists.txt | 2 + .../plugins/gui_editor/gui_editor_window.cpp | 14 +++- .../src/plugins/gui_editor/new_gui_dlg.cpp | 72 ++++++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 44 ++++++++++ .../src/plugins/gui_editor/new_gui_dlg.ui | 84 +++++++++++++++++++ 5 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.cpp create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.h create mode 100644 code/studio/src/plugins/gui_editor/new_gui_dlg.ui diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 2b46e2cdc..e1e8b38be 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -36,6 +36,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR texture_property_manager.h expression_editor.h expr_link_dlg.h + new_gui_dlg.h ) SET(OVQT_PLUGIN_GUI_EDITOR_UIS @@ -55,6 +56,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS texture_chooser.ui expression_editor.ui expr_link_dlg.ui + new_gui_dlg.ui ) SET(QT_USE_QTGUI TRUE) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 5b3d835a2..1f3c372c0 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -44,6 +44,7 @@ #include "editor_selection_watcher.h" #include "editor_message_processor.h" #include "add_widget_widget.h" +#include "new_gui_dlg.h" namespace GUIEditor { @@ -199,6 +200,13 @@ namespace GUIEditor void GUIEditorWindow::newDocument() { + NewGUIDlg d; + int result = d.exec(); + + if( result == QDialog::Rejected ) + return; + + close(); } void GUIEditorWindow::save() @@ -358,14 +366,14 @@ namespace GUIEditor void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); - //QAction *newAction = mm->action( Core::Constants::NEW ); + QAction *newAction = mm->action( Core::Constants::NEW ); QAction *saveAction = mm->action( Core::Constants::SAVE ); QAction *saveAsAction = mm->action( Core::Constants::SAVE_AS ); QAction *closeAction = mm->action( Core::Constants::CLOSE ); QAction *delAction = mm->action( Core::Constants::DEL ); - //if( newAction != NULL ) - // newAction->setEnabled( true ); + if( newAction != NULL ) + newAction->setEnabled( true ); if( saveAction != NULL ) saveAction->setEnabled( true ); if( saveAsAction != NULL ) diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp new file mode 100644 index 000000000..8dc7abb1e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -0,0 +1,72 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "new_gui_dlg.h" +#include + +NewGUIDlg::NewGUIDlg( QWidget *parent ) : +QDialog( parent ) +{ + m_ui.setupUi( this ); + + connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); + connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + +} + +NewGUIDlg::~NewGUIDlg() +{ +} + +QString NewGUIDlg::getProjectName() const +{ + return m_ui.projectEdit->text(); +} + +QString NewGUIDlg::getWindowName() const +{ + return m_ui.windowEdit->text(); +} + +void NewGUIDlg::onOKClicked() +{ + if( m_ui.projectEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a project name!" ) ); + return; + } + + if( m_ui.windowEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a window name!" ) ); + return; + } + + accept(); +} + +void NewGUIDlg::onCancelClicked() +{ + reject(); +} + + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h new file mode 100644 index 000000000..3e290545c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -0,0 +1,44 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef NEW_GUI_DLG_H +#define NEW_GUI_DLG_H + +#include "ui_new_gui_dlg.h" + +class NewGUIDlg : public QDialog +{ + Q_OBJECT + +public: + NewGUIDlg( QWidget *parent = NULL ); + ~NewGUIDlg(); + + QString getProjectName() const; + QString getWindowName() const; + +private Q_SLOTS: + void onOKClicked(); + void onCancelClicked(); + +private: + Ui::NewGUIDialog m_ui; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui new file mode 100644 index 000000000..a144c58e8 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -0,0 +1,84 @@ + + + NewGUIDialog + + + + 0 + 0 + 292 + 95 + + + + New GUI + + + + + + Project name + + + + + + + + + + Window name + + + + + + + + + + Qt::Horizontal + + + + 107 + 20 + + + + + + + + + + + 0 + 0 + + + + OK + + + + + + + + 0 + 0 + + + + Cancel + + + + + + + + + + From e5d2e9293d1c2fe1e8fb1c4a447572257ce7b7a0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 19:30:30 +0200 Subject: [PATCH 014/240] Moved CRootGroup out of CInterfaceParser. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/root_group.h | 46 +++++++++++++ code/nel/src/gui/interface_parser.cpp | 81 +---------------------- code/nel/src/gui/root_group.cpp | 94 +++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 80 deletions(-) create mode 100644 code/nel/include/nel/gui/root_group.h create mode 100644 code/nel/src/gui/root_group.cpp diff --git a/code/nel/include/nel/gui/root_group.h b/code/nel/include/nel/gui/root_group.h new file mode 100644 index 000000000..58963a3b2 --- /dev/null +++ b/code/nel/include/nel/gui/root_group.h @@ -0,0 +1,46 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef ROOT_GROUP_H +#define ROOT_GROUP_H + +#include +#include + +#include "nel/gui/interface_group.h" + +namespace NLGUI +{ + + class CRootGroup : public CInterfaceGroup + { + public: + CRootGroup(const TCtorParam ¶m); + virtual ~CRootGroup(); + + virtual CInterfaceElement* getElement (const std::string &id); + virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1); + virtual bool delGroup (CInterfaceGroup *child, bool dontDelete = false); + + private: + std::map< std::string, CInterfaceGroup* > _Accel; + }; + +} + +#endif + diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index f052224ff..7bf44c6f6 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -37,6 +37,7 @@ #include "nel/gui/lua_helper.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/lua_manager.h" +#include "nel/gui/root_group.h" #ifdef LUA_NEVRAX_VERSION #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger @@ -113,86 +114,6 @@ namespace NLGUI return node; } - - - // ---------------------------------------------------------------------------- - // CRootGroup - // ---------------------------------------------------------------------------- - - class CRootGroup : public CInterfaceGroup - { - public: - CRootGroup(const TCtorParam ¶m) - : CInterfaceGroup(param) - { } - - /// Destructor - virtual ~CRootGroup() { } - - virtual CInterfaceElement* getElement (const std::string &id) - { - if (_Id == id) - return this; - - if (id.substr(0, _Id.size()) != _Id) - return NULL; - - vector::const_iterator itv; - for (itv = _Views.begin(); itv != _Views.end(); itv++) - { - CViewBase *pVB = *itv; - if (pVB->getId() == id) - return pVB; - } - - vector::const_iterator itc; - for (itc = _Controls.begin(); itc != _Controls.end(); itc++) - { - CCtrlBase* ctrl = *itc; - if (ctrl->getId() == id) - return ctrl; - } - - // Accelerate - string sTmp = id; - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - string::size_type pos = sTmp.find(':'); - if (pos != string::npos) - sTmp = sTmp.substr(0,pos); - - map::iterator it = _Accel.find(sTmp); - if (it != _Accel.end()) - { - CInterfaceGroup *pIG = it->second; - return pIG->getElement(id); - } - return NULL; - } - - virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1) - { - string sTmp = child->getId(); - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - _Accel.insert(pair(sTmp, child)); - CInterfaceGroup::addGroup(child,eltOrder); - } - - virtual bool delGroup (CInterfaceGroup *child, bool dontDelete = false) - { - string sTmp = child->getId(); - sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); - map::iterator it = _Accel.find(sTmp); - if (it != _Accel.end()) - { - _Accel.erase(it); - } - return CInterfaceGroup::delGroup(child,dontDelete); - } - - private: - map _Accel; - }; - // ---------------------------------------------------------------------------- // CInterfaceParser // ---------------------------------------------------------------------------- diff --git a/code/nel/src/gui/root_group.cpp b/code/nel/src/gui/root_group.cpp new file mode 100644 index 000000000..bffdd5579 --- /dev/null +++ b/code/nel/src/gui/root_group.cpp @@ -0,0 +1,94 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "nel/gui/root_group.h" +#include + +namespace NLGUI +{ + + CRootGroup::CRootGroup(const TCtorParam ¶m) : + CInterfaceGroup(param) + { + } + + CRootGroup::~CRootGroup() + { + } + + CInterfaceElement* CRootGroup::getElement (const std::string &id) + { + if (_Id == id) + return this; + + if (id.substr(0, _Id.size()) != _Id) + return NULL; + + std::vector::const_iterator itv; + for (itv = _Views.begin(); itv != _Views.end(); itv++) + { + CViewBase *pVB = *itv; + if (pVB->getId() == id) + return pVB; + } + + std::vector::const_iterator itc; + for (itc = _Controls.begin(); itc != _Controls.end(); itc++) + { + CCtrlBase* ctrl = *itc; + if (ctrl->getId() == id) + return ctrl; + } + + // Accelerate + std::string sTmp = id; + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + std::string::size_type pos = sTmp.find(':'); + if (pos != std::string::npos) + sTmp = sTmp.substr(0,pos); + + std::map::iterator it = _Accel.find(sTmp); + if (it != _Accel.end()) + { + CInterfaceGroup *pIG = it->second; + return pIG->getElement(id); + } + return NULL; + } + + void CRootGroup::addGroup (CInterfaceGroup *child, sint eltOrder) + { + std::string sTmp = child->getId(); + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + _Accel.insert(std::pair(sTmp, child)); + CInterfaceGroup::addGroup(child,eltOrder); + } + + bool CRootGroup::delGroup (CInterfaceGroup *child, bool dontDelete) + { + std::string sTmp = child->getId(); + sTmp = sTmp.substr(_Id.size()+1,sTmp.size()); + std::map::iterator it = _Accel.find(sTmp); + if (it != _Accel.end()) + { + _Accel.erase(it); + } + return CInterfaceGroup::delGroup(child,dontDelete); + } + +} + From ded18b266c1e4fe5579933c3b177880bc50e4934 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 21:43:28 +0200 Subject: [PATCH 015/240] Implemented new action. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 2 + code/nel/src/gui/widget_manager.cpp | 45 +++++++++++++++++++ .../plugins/gui_editor/gui_editor_window.cpp | 40 ++++++++++++----- .../plugins/gui_editor/gui_editor_window.h | 1 + .../src/plugins/gui_editor/nelgui_ctrl.cpp | 35 +++++++++++++-- .../src/plugins/gui_editor/nelgui_ctrl.h | 3 ++ 6 files changed, 112 insertions(+), 14 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index d722a9165..6d2336047 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -528,6 +528,8 @@ namespace NLGUI bool groupSelection(); bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } + + bool createNewGUI( const std::string &project, const std::string &window ); private: CWidgetManager(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c68a2c963..803889a79 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -35,6 +35,7 @@ #include "nel/gui/reflect_register.h" #include "nel/gui/editor_selection_watcher.h" #include "nel/misc/events.h" +#include "nel/gui/root_group.h" namespace NLGUI { @@ -1041,6 +1042,8 @@ namespace NLGUI resetGlobalAlphasProps(); activeAnims.clear(); + + editorSelection.clear(); } @@ -3604,6 +3607,48 @@ namespace NLGUI } + bool CWidgetManager::createNewGUI( const std::string &project, const std::string &window ) + { + reset(); + + for( int i = 0; i < _MasterGroups.size(); i++ ) + delete _MasterGroups[i].Group; + _MasterGroups.clear(); + + // First create the master group + CRootGroup *root = new CRootGroup( CViewBase::TCtorParam() ); + + SMasterGroup mg; + mg.Group = root; + + root->setIdRecurse( project ); + root->setW( 1024 ); + root->setH( 768 ); + root->setActive( true ); + + // Create the first / main window + CInterfaceGroup *wnd = new CInterfaceGroup( CViewBase::TCtorParam() ); + wnd->setW( 1024 ); + wnd->setH( 768 ); + wnd->setParent( root ); + wnd->setParentPos( root ); + wnd->setParentSize( root ); + wnd->setPosRef( Hotspot_MM ); + wnd->setParentPosRef( Hotspot_MM ); + wnd->setIdRecurse( window ); + wnd->setActive( true ); + + // Add the window + root->addElement( wnd ); + mg.addWindow( wnd, wnd->getPriority() ); + _MasterGroups.push_back( mg ); + + _Pointer = new CViewPointer( CViewBase::TCtorParam() ); + + return true; + } + + CWidgetManager::CWidgetManager() { LinkHack(); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 1f3c372c0..aedeea5d6 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -207,6 +207,21 @@ namespace GUIEditor return; close(); + + std::string proj = d.getProjectName().toUtf8().constData(); + std::string wnd = d.getWindowName().toUtf8().constData(); + + bool b = GUICtrl->createNewGUI( proj, wnd ); + if( !b ) + { + QMessageBox::information( this, + tr( "Creating new GUI project" ), + tr( "Failed to create new GUI project :(" ) ); + reset(); + } + + std::string mg = std::string( "ui:" ) + proj; + hierarchyView->buildHierarchy( mg ); } void GUIEditorWindow::save() @@ -279,6 +294,20 @@ namespace GUIEditor } + void GUIEditorWindow::reset() + { + projectFiles.clearAll(); + projectWindow->clear(); + hierarchyView->clearHierarchy(); + GUICtrl->reset(); + browserCtrl.clear(); + linkList->clear(); + procList->clear(); + currentProject = ""; + currentProjectFile = ""; + projectParser.clear(); + } + bool GUIEditorWindow::close() { if( currentProject.isEmpty() ) @@ -296,16 +325,7 @@ namespace GUIEditor disconnect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); disconnect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); - projectFiles.clearAll(); - projectWindow->clear(); - hierarchyView->clearHierarchy(); - GUICtrl->reset(); - browserCtrl.clear(); - linkList->clear(); - procList->clear(); - currentProject = ""; - currentProjectFile = ""; - projectParser.clear(); + reset(); return true; } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index cc2dfbc65..4a0a919a4 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -70,6 +70,7 @@ protected: void showEvent( QShowEvent *evnt ); private: + void reset(); void createMenus(); void removeMenus(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index 8f0f56711..c1e7af3df 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -114,11 +114,29 @@ namespace GUIEditor if( e != NULL ) e->setActive( true ); - timerID = startTimer( 200 ); - guiLoaded = true; - Q_EMIT guiLoadComplete(); + onGUILoaded(); - CWidgetManager::getInstance()->registerSelectionWatcher( watcher ); + return true; + } + + bool NelGUICtrl::createNewGUI( const std::string &project, const std::string &window ) + { + reset(); + bool ok = CWidgetManager::getInstance()->createNewGUI( project, window ); + if( !ok ) + return false; + + std::string mg = std::string( "ui:" ) + project; + std::string ag = mg + ":" + window; + + CWidgetManager::getInstance()->updateAllLocalisedElements(); + CWidgetManager::getInstance()->activateMasterGroup( mg, true ); + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( ag ); + if( e != NULL ) + e->setActive( true ); + + onGUILoaded(); return true; } @@ -160,6 +178,15 @@ namespace GUIEditor } } + void NelGUICtrl::onGUILoaded() + { + timerID = startTimer( 200 ); + guiLoaded = true; + Q_EMIT guiLoadComplete(); + + CWidgetManager::getInstance()->registerSelectionWatcher( watcher ); + } + void NelGUICtrl::show() { if( timerID == 0 ) diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index 63118d947..d7d157ccf 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -43,6 +43,7 @@ namespace GUIEditor void init(); bool parse( SProjectFiles &files ); + bool createNewGUI( const std::string &project, const std::string &window ); void draw(); void reset(); CEditorSelectionWatcher* getWatcher(){ return watcher; } @@ -61,6 +62,8 @@ Q_SIGNALS: void timerEvent( QTimerEvent *evnt ); private: + void onGUILoaded(); + int timerID; bool guiLoaded; CEditorSelectionWatcher *watcher; From 2c5617cea7205510364137900ac649573ab4a957 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 20:09:42 +0200 Subject: [PATCH 016/240] When creating a new project, save it right away. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 38 ++++++++++++++++++- .../src/plugins/gui_editor/new_gui_dlg.cpp | 26 +++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 2 + .../src/plugins/gui_editor/new_gui_dlg.ui | 23 +++++++++-- .../gui_editor/project_file_parser.cpp | 5 ++- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index aedeea5d6..70f206b3b 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -210,6 +210,9 @@ namespace GUIEditor std::string proj = d.getProjectName().toUtf8().constData(); std::string wnd = d.getWindowName().toUtf8().constData(); + std::string mg = std::string( "ui:" ) + proj; + std::string dir = d.getProjectDirectory().toUtf8().constData(); + std::string uiFile = "ui_" + proj + ".xml"; bool b = GUICtrl->createNewGUI( proj, wnd ); if( !b ) @@ -220,8 +223,41 @@ namespace GUIEditor reset(); } - std::string mg = std::string( "ui:" ) + proj; hierarchyView->buildHierarchy( mg ); + + projectFiles.projectName = proj; + projectFiles.masterGroup = mg; + projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; + projectFiles.version = NEW; + projectFiles.guiFiles.push_back( uiFile ); + projectWindow->setupFiles( projectFiles ); + + currentProject = proj.c_str(); + currentProjectFile = std::string( dir + "/" + proj + ".xml" ).c_str(); + + + // Save the project file + CProjectFileSerializer serializer; + serializer.setFile( currentProjectFile.toUtf8().constData() ); + if( !serializer.serialize( projectFiles ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } + + // Save the GUI file + WidgetSerializer widgetSerializer; + widgetSerializer.setFile( dir + "/" + uiFile ); + widgetSerializer.setActiveGroup( projectFiles.activeGroup ); + if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } } void GUIEditorWindow::save() diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp index 8dc7abb1e..88d4a19fd 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -18,6 +18,7 @@ #include "new_gui_dlg.h" #include +#include NewGUIDlg::NewGUIDlg( QWidget *parent ) : QDialog( parent ) @@ -26,6 +27,7 @@ QDialog( parent ) connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); + connect( m_ui.projectDirTB, SIGNAL( clicked( bool ) ), this, SLOT( onProjectDirTBClicked() ) ); } @@ -43,6 +45,11 @@ QString NewGUIDlg::getWindowName() const return m_ui.windowEdit->text(); } +QString NewGUIDlg::getProjectDirectory() const +{ + return m_ui.projectDirEdit->text(); +} + void NewGUIDlg::onOKClicked() { if( m_ui.projectEdit->text().isEmpty() ) @@ -61,6 +68,14 @@ void NewGUIDlg::onOKClicked() return; } + if( m_ui.projectDirEdit->text().isEmpty() ) + { + QMessageBox::information( this, + tr( "New project" ), + tr( "You must specify a project directory!" ) ); + return; + } + accept(); } @@ -69,4 +84,15 @@ void NewGUIDlg::onCancelClicked() reject(); } +void NewGUIDlg::onProjectDirTBClicked() +{ + QString dir = QFileDialog::getExistingDirectory( this, + tr( "Specify project directory" ), + "." ); + if( dir.isEmpty() ) + return; + + m_ui.projectDirEdit->setText( dir ); +} + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h index 3e290545c..f4bf474f7 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.h +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -31,10 +31,12 @@ public: QString getProjectName() const; QString getWindowName() const; + QString getProjectDirectory() const; private Q_SLOTS: void onOKClicked(); void onCancelClicked(); + void onProjectDirTBClicked(); private: Ui::NewGUIDialog m_ui; diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui index a144c58e8..7dca6d2a3 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -6,8 +6,8 @@ 0 0 - 292 - 95 + 332 + 125 @@ -35,6 +35,23 @@ + + + Project directory + + + + + + + + + + ... + + + + Qt::Horizontal @@ -47,7 +64,7 @@ - + diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index 7213b332a..a5646c963 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -16,6 +16,7 @@ #include "project_file_parser.h" +#include "nel/misc/debug.h" namespace GUIEditor { @@ -208,7 +209,9 @@ namespace GUIEditor reader.readNext(); } if( files.mapFiles.empty() ) - return false; + { + nlinfo( "No map file(s) specified in project file." ); + } return true; } From b587acb135fd2b9e671bddcd3abc6f22f14dac35 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 21:15:13 +0200 Subject: [PATCH 017/240] Some refactoring regarding saving. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 60 +++++++++---------- .../gui_editor/project_file_parser.cpp | 4 +- .../gui_editor/project_file_serializer.cpp | 2 +- .../src/plugins/gui_editor/project_files.h | 15 ++--- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 70f206b3b..aad19c2ac 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -212,6 +212,7 @@ namespace GUIEditor std::string wnd = d.getWindowName().toUtf8().constData(); std::string mg = std::string( "ui:" ) + proj; std::string dir = d.getProjectDirectory().toUtf8().constData(); + _lastDir = dir.c_str(); std::string uiFile = "ui_" + proj + ".xml"; bool b = GUICtrl->createNewGUI( proj, wnd ); @@ -228,7 +229,7 @@ namespace GUIEditor projectFiles.projectName = proj; projectFiles.masterGroup = mg; projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; - projectFiles.version = NEW; + projectFiles.version = SProjectFiles::NEW; projectFiles.guiFiles.push_back( uiFile ); projectWindow->setupFiles( projectFiles ); @@ -278,8 +279,23 @@ namespace GUIEditor // Can't save old projects any further, since the widgets are in multiple files in them // using templates, styles and whatnot. There's no way to restore the original XML structure // after it's loaded - if( projectParser.getProjectVersion() == OLD ) + if( projectFiles.version == SProjectFiles::OLD ) return; + + std::string f = _lastDir.toUtf8().constData(); + f += "/"; + f += projectFiles.guiFiles[ 0 ]; + + WidgetSerializer widgetSerializer; + widgetSerializer.setFile( f ); + widgetSerializer.setActiveGroup( projectFiles.activeGroup ); + if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) + { + QMessageBox::critical( this, + tr( "Failed to save project" ), + tr( "There was an error while trying to save the project." ) ); + return; + } } void GUIEditorWindow::saveAs() @@ -292,42 +308,22 @@ namespace GUIEditor if( dir.isEmpty() ) return; + _lastDir = dir; - projectFiles.guiFiles.clear(); - projectFiles.guiFiles.push_back( "ui_" + projectFiles.projectName + ".xml" ); - projectFiles.version = NEW; - - QString newFile = - dir + "/" + projectFiles.projectName.c_str() + ".xml"; - - CProjectFileSerializer serializer; - serializer.setFile( newFile.toUtf8().constData() ); - if( !serializer.serialize( projectFiles ) ) + if( projectFiles.version == SProjectFiles::OLD ) { - QMessageBox::critical( this, - tr( "Failed to save project" ), - tr( "There was an error while trying to save the project." ) ); - return; - } - - std::string guiFile = - std::string( dir.toUtf8().constData() ) + "/" + "ui_" + projectFiles.projectName + ".xml"; + projectFiles.guiFiles.clear(); + projectFiles.guiFiles.push_back( "ui_" + projectFiles.projectName + ".xml" ); + projectFiles.version = SProjectFiles::NEW; - WidgetSerializer widgetSerializer; - widgetSerializer.setFile( guiFile ); - widgetSerializer.setActiveGroup( projectFiles.activeGroup ); - if( !widgetSerializer.serialize( projectFiles.masterGroup ) ) - { - QMessageBox::critical( this, - tr( "Failed to save project" ), - tr( "There was an error while trying to save the project." ) ); - return; } - QMessageBox::information( this, - tr( "Save successful" ), - tr( "Project saved successfully!" ) ); + currentProjectFile = _lastDir; + currentProjectFile += "/"; + currentProjectFile += projectFiles.projectName.c_str(); + currentProjectFile += ".xml"; + save(); } void GUIEditorWindow::reset() diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index a5646c963..a10f5d783 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -63,7 +63,7 @@ namespace GUIEditor unsigned long CProjectFileParser::getProjectVersion() const { if( !loaded ) - return OLD; + return SProjectFiles::OLD; return files.version; } @@ -71,7 +71,7 @@ namespace GUIEditor void CProjectFileParser::clear() { files.projectName = ""; - files.version = OLD; + files.version = SProjectFiles::OLD; files.activeGroup = ""; files.guiFiles.clear(); files.mapFiles.clear(); diff --git a/code/studio/src/plugins/gui_editor/project_file_serializer.cpp b/code/studio/src/plugins/gui_editor/project_file_serializer.cpp index 4eb442d3f..0b34f511b 100644 --- a/code/studio/src/plugins/gui_editor/project_file_serializer.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_serializer.cpp @@ -25,7 +25,7 @@ namespace GUIEditor if( fileName.empty() ) return false; - if( project.version >= MAX_PROJECTFILE_VERSION ) + if( project.version >= SProjectFiles::MAX_PROJECTFILE_VERSION ) return false; out.open( fileName.c_str() ); diff --git a/code/studio/src/plugins/gui_editor/project_files.h b/code/studio/src/plugins/gui_editor/project_files.h index 4ae58493b..786bd22e4 100644 --- a/code/studio/src/plugins/gui_editor/project_files.h +++ b/code/studio/src/plugins/gui_editor/project_files.h @@ -23,16 +23,17 @@ namespace GUIEditor { - enum ProjectVersion - { - OLD = 0, - NEW = 1, - MAX_PROJECTFILE_VERSION - }; - struct SProjectFiles { public: + + enum ProjectVersion + { + OLD = 0, + NEW = 1, + MAX_PROJECTFILE_VERSION + }; + std::string projectName; unsigned long version; std::string masterGroup; From b3dd26e01cb968e0aee8eece958a77c3c82147e2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 23:05:22 +0200 Subject: [PATCH 018/240] Parent positions should now be saved right again. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 1 + code/nel/src/gui/interface_element.cpp | 36 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 0be4c02e3..a8a04b454 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -492,6 +492,7 @@ namespace NLGUI bool isEditorSelected() const{ return editorSelected; } void setPosParent( const std::string &id ); + void getPosParent( std::string &id ) const; void setSizeParent( const std::string &id ); void setSerializable( bool b ){ serializable = b; } diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index c9b480516..e3928e85f 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -294,8 +294,10 @@ namespace NLGUI xmlNewProp( node, BAD_CAST "w", BAD_CAST toString( _W ).c_str() ); xmlNewProp( node, BAD_CAST "h", BAD_CAST toString( _H ).c_str() ); xmlNewProp( node, BAD_CAST "posref", BAD_CAST HotSpotCoupleToString( _ParentPosRef, _PosRef ).c_str() ); - xmlNewProp( node, BAD_CAST "posparent", - BAD_CAST CWidgetManager::getInstance()->getParser()->getParentPosAssociation( (CInterfaceElement*)this ).c_str() ); + + std::string pp; + getPosParent( pp ); + xmlNewProp( node, BAD_CAST "posparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "sizeref", BAD_CAST getSizeRefAsString().c_str() ); xmlNewProp( node, BAD_CAST "sizeparent", BAD_CAST CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ).c_str() ); @@ -1541,6 +1543,36 @@ namespace NLGUI } } + void CInterfaceElement::getPosParent( std::string &id ) const + { + + // If there's no pos parent set, then the parent group is the pos parent + if( getParentPos() == NULL ) + { + id = "parent"; + return; + } + + // If pos parent and parent are the same then ofc the parent group is the pos parent... + CInterfaceElement *p = getParent(); + if( getParentPos() == p ) + { + id = "parent"; + return; + } + + // If parent is in the same group, use the short id + p = getParentPos(); + if( p->isInGroup( getParent() ) ) + { + id = p->getShortId(); + return; + } + + // Otherwise use the full id + id = p->getId(); + } + void CInterfaceElement::setSizeParent( const std::string &id ) { std::string Id = stripId( id ); From 487c6a344019236b6decaeb3ec5acc2a60fef022 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 12 Oct 2014 23:07:08 +0200 Subject: [PATCH 019/240] GUI Editor should show the right parent position. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index e3928e85f..0e7458f3a 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -147,7 +147,9 @@ namespace NLGUI } if( name == "posparent" ) { - return CWidgetManager::getInstance()->getParser()->getParentPosAssociation( (CInterfaceElement*)this ); + std::string pp; + getPosParent( pp ); + return pp; } else if( name == "sizeparent" ) From 2dd62787719d810f4f47963a0e7a9312fc7e7f55 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 15:26:47 +0200 Subject: [PATCH 020/240] Size parent is now queried directly from the widget. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 1 + code/nel/src/gui/interface_element.cpp | 37 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index a8a04b454..0f9b271ce 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -494,6 +494,7 @@ namespace NLGUI void setPosParent( const std::string &id ); void getPosParent( std::string &id ) const; void setSizeParent( const std::string &id ); + void getSizeParent( std::string &id ) const; void setSerializable( bool b ){ serializable = b; } bool IsSerializable() const{ return serializable; } diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 0e7458f3a..a18b8e71d 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -154,7 +154,9 @@ namespace NLGUI else if( name == "sizeparent" ) { - return CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ); + std::string sp; + getSizeParent( sp ); + return sp; } else if( name == "global_color" ) @@ -301,8 +303,8 @@ namespace NLGUI getPosParent( pp ); xmlNewProp( node, BAD_CAST "posparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "sizeref", BAD_CAST getSizeRefAsString().c_str() ); - xmlNewProp( node, BAD_CAST "sizeparent", - BAD_CAST CWidgetManager::getInstance()->getParser()->getParentSizeAssociation( (CInterfaceElement*)this ).c_str() ); + getSizeParent( pp ); + xmlNewProp( node, BAD_CAST "sizeparent", BAD_CAST pp.c_str() ); xmlNewProp( node, BAD_CAST "global_color", BAD_CAST toString( _ModulateGlobalColor ).c_str() ); xmlNewProp( node, BAD_CAST "render_layer", BAD_CAST toString( _RenderLayer ).c_str() ); @@ -1598,6 +1600,35 @@ namespace NLGUI } } + void CInterfaceElement::getSizeParent( std::string &id ) const + { + CInterfaceElement *p = getParentSize(); + + // If there's no parent set then the size parent is the parent + if( p == NULL ) + { + id = "parent"; + return; + } + + // If the size parent is the same as the group parent, then the size parent is the parent ofc + if( p == getParent() ) + { + id = "parent"; + return; + } + + // If the size parent is in the parent group, use the short Id + if( p->isInGroup( getParent() ) ) + { + id = p->getShortId(); + return; + } + + // Otherwise use the full Id + id = p->getId(); + } + void CInterfaceElement::registerDeletionWatcher( IDeletionWatcher *watcher ) { std::vector< IDeletionWatcher* >::iterator itr From 8066717aa22475ae2dd574ea9dd0178e4bb3598a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 15:43:10 +0200 Subject: [PATCH 021/240] Pos and Size parent setters should now use the widget directly as well. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 71 ++++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index a18b8e71d..620e7dbdb 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1534,17 +1534,36 @@ namespace NLGUI void CInterfaceElement::setPosParent( const std::string &id ) { - std::string Id = stripId( id ); + // Parent or empty id simply means the group parent + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentPos( getParent() ); + return; + } + + CInterfaceElement *pp = NULL; - if( Id != "parent" ) + // Check if it's a short Id + std::string::size_type idx = id.find( "ui:" ); + if( idx == std::string::npos ) { - std::string idParent; - if( _Parent != NULL ) - idParent = _Parent->getId() + ":"; - else - idParent = "ui:"; - CWidgetManager::getInstance()->getParser()->addParentPositionAssociation( this, idParent + Id ); + // If it is, find the widget in the parent group and set as posparent + CInterfaceGroup *p = getParent(); + if( p != NULL ) + { + pp = p->findFromShortId( id ); + } + } + else + { + // If it is not, find using the widgetmanager + // TODO: refactor, shouldn't use a singleton + pp = CWidgetManager::getInstance()->getElementFromId( id ); } + + if( pp != NULL ) + setParentPos( pp ); + } void CInterfaceElement::getPosParent( std::string &id ) const @@ -1579,25 +1598,35 @@ namespace NLGUI void CInterfaceElement::setSizeParent( const std::string &id ) { - std::string Id = stripId( id ); - std::string idParent; - - if( Id != "parent" ) + // Parent or empty id simply means the group parent + if( ( id == "parent" ) || ( id.empty() ) ) { - if( _Parent != NULL ) - idParent = _Parent->getId() + ":"; - else - idParent = "ui:"; - CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, idParent + Id ); + setParentSize( getParent() ); + return; } - else + + CInterfaceElement *pp = NULL; + + // Check if it's a short Id + std::string::size_type idx = id.find( "ui:" ); + if( idx == std::string::npos ) { - if( _Parent != NULL ) + // If it is, find the widget in the parent group and set as posparent + CInterfaceGroup *p = getParent(); + if( p != NULL ) { - idParent = _Parent->getId(); - CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, idParent ); + pp = p->findFromShortId( id ); } } + else + { + // If it is not, find using the widgetmanager + // TODO: refactor, shouldn't use a singleton + pp = CWidgetManager::getInstance()->getElementFromId( id ); + } + + if( pp != NULL ) + setParentSize( pp ); } void CInterfaceElement::getSizeParent( std::string &id ) const From c5cd6990fe808fef6fc38bc126ccd449e49908a2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 17:47:42 +0200 Subject: [PATCH 022/240] When creating a new GUI set the base color to white. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_parser.h | 16 +------- code/nel/include/nel/gui/parser.h | 2 + code/nel/include/nel/gui/variable_data.h | 41 +++++++++++++++++++++ code/nel/src/gui/interface_parser.cpp | 28 ++++++++++++++ code/nel/src/gui/widget_manager.cpp | 20 ++++++++++ 5 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 code/nel/include/nel/gui/variable_data.h diff --git a/code/nel/include/nel/gui/interface_parser.h b/code/nel/include/nel/gui/interface_parser.h index c1b3fa109..18ec9045a 100644 --- a/code/nel/include/nel/gui/interface_parser.h +++ b/code/nel/include/nel/gui/interface_parser.h @@ -28,6 +28,7 @@ #include "nel/gui/proc.h" #include "nel/gui/widget_manager.h" #include "nel/gui/link_data.h" +#include "nel/gui/variable_data.h" namespace NLGUI { @@ -100,20 +101,6 @@ namespace NLGUI virtual void setupOptions() = 0; }; - - struct VariableData - { - std::string entry; - std::string type; - std::string value; - uint32 size; - - VariableData() - { - size = 0; - } - }; - CInterfaceParser(); virtual ~CInterfaceParser(); @@ -386,6 +373,7 @@ namespace NLGUI void setEditorMode( bool b ){ editorMode = b; } + void setVariable( const VariableData &v ); bool serializeVariables( xmlNodePtr parentNode ) const; bool serializeProcs( xmlNodePtr parentNode ) const; bool serializePointerSettings( xmlNodePtr parentNode ) const; diff --git a/code/nel/include/nel/gui/parser.h b/code/nel/include/nel/gui/parser.h index 0378c22ec..bc53e402d 100644 --- a/code/nel/include/nel/gui/parser.h +++ b/code/nel/include/nel/gui/parser.h @@ -23,6 +23,7 @@ #include "nel/misc/types_nl.h" #include "nel/gui/proc.h" #include "nel/gui/link_data.h" +#include "nel/gui/variable_data.h" namespace NLGUI { @@ -83,6 +84,7 @@ namespace NLGUI virtual void removeLinkData( uint32 id ) = 0; virtual bool getLinkData( uint32 id, SLinkData &linkData ) = 0; virtual void updateLinkData( uint32 id, const SLinkData &linkData ) = 0; + virtual void setVariable( const VariableData &v ) = 0; virtual bool serializeVariables( xmlNodePtr parentNode ) const = 0; virtual bool serializeProcs( xmlNodePtr parentNode ) const = 0; virtual bool serializePointerSettings( xmlNodePtr parentNode ) const = 0; diff --git a/code/nel/include/nel/gui/variable_data.h b/code/nel/include/nel/gui/variable_data.h new file mode 100644 index 000000000..cffba2bce --- /dev/null +++ b/code/nel/include/nel/gui/variable_data.h @@ -0,0 +1,41 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef VARIABLE_DATA_H +#define VARIABLE_DATA_H + +#include "nel/misc/types_nl.h" + +namespace NLGUI +{ + struct VariableData + { + std::string entry; + std::string type; + std::string value; + uint32 size; + + VariableData() + { + size = 0; + } + }; + +} + + +#endif + diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index 7bf44c6f6..096c001ae 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -2951,6 +2951,34 @@ namespace NLGUI itr->second = linkData; } + void CInterfaceParser::setVariable( const VariableData &v ) + { + CInterfaceProperty prop; + const std::string &type = v.type; + const std::string &value = v.value; + const std::string &entry = v.entry; + + if( type == "sint64" ) + prop.readSInt64( value.c_str(), entry ); + else + if( type == "sint32" ) + prop.readSInt32( value.c_str(), entry ); + else + if( type == "float" || type == "double" ) + prop.readDouble( value.c_str(), entry ); + else + if( type == "bool" ) + prop.readBool( value.c_str(), entry ); + else + if( type == "rgba" ) + prop.readRGBA( value.c_str(), entry ); + else + if( type == "hotspot" ) + prop.readHotSpot( value.c_str(), entry ); + + variableCache[ entry ] = v; + } + bool CInterfaceParser::serializeVariables( xmlNodePtr parentNode ) const { diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 803889a79..81fbaf28b 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -3645,6 +3645,26 @@ namespace NLGUI _Pointer = new CViewPointer( CViewBase::TCtorParam() ); + IParser *parser = getParser(); + + + // Set base color to white + VariableData v; + v.type = "sint32"; + v.value = "255"; + + v.entry = "UI:SAVE:COLOR:R"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:G"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:B"; + parser->setVariable( v ); + + v.entry = "UI:SAVE:COLOR:A"; + parser->setVariable( v ); + return true; } From 22a1d39ac7bf42ed4d8cdaffcf474c22bc89210e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 18:53:26 +0200 Subject: [PATCH 023/240] Map files can now be specified when creating a new GUI project. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/gui_editor_window.cpp | 20 ++++++++ .../src/plugins/gui_editor/nelgui_ctrl.cpp | 36 ++++++++------ .../src/plugins/gui_editor/nelgui_ctrl.h | 1 + .../src/plugins/gui_editor/new_gui_dlg.cpp | 37 +++++++++++++++ .../src/plugins/gui_editor/new_gui_dlg.h | 4 ++ .../src/plugins/gui_editor/new_gui_dlg.ui | 47 +++++++++++++++---- 6 files changed, 122 insertions(+), 23 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index aad19c2ac..002002abd 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -215,6 +215,9 @@ namespace GUIEditor _lastDir = dir.c_str(); std::string uiFile = "ui_" + proj + ".xml"; + QList< QString > mapList; + d.getMapList( mapList ); + bool b = GUICtrl->createNewGUI( proj, wnd ); if( !b ) { @@ -222,6 +225,7 @@ namespace GUIEditor tr( "Creating new GUI project" ), tr( "Failed to create new GUI project :(" ) ); reset(); + return; } hierarchyView->buildHierarchy( mg ); @@ -231,6 +235,22 @@ namespace GUIEditor projectFiles.activeGroup = std::string( "ui:" ) + proj + ":" + wnd; projectFiles.version = SProjectFiles::NEW; projectFiles.guiFiles.push_back( uiFile ); + + for( int i = 0; i < mapList.size(); i++ ) + { + projectFiles.mapFiles.push_back( mapList[ i ].toUtf8().constData() ); + } + + b = GUICtrl->loadMapFiles( projectFiles.mapFiles ); + if( !b ) + { + QMessageBox::information( this, + tr( "Creating new GUI project" ), + tr( "Failed to create new GUI project: Couldn't load map files. " ) ); + reset(); + return; + } + projectWindow->setupFiles( projectFiles ); currentProject = proj.c_str(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp index c1e7af3df..e9712ce4e 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.cpp @@ -89,20 +89,8 @@ namespace GUIEditor reset(); IParser *parser = CWidgetManager::getInstance()->getParser(); - std::vector< std::string >::iterator itr; - for( itr = files.mapFiles.begin(); itr != files.mapFiles.end(); ++itr ) - { - std::string &file = *itr; - std::string::size_type i = file.find_last_of( '.' ); - std::string mapFile = file.substr( 0, i ); - mapFile.append( ".txt" ); - - if( !CViewRenderer::getInstance()->loadTextures( file, mapFile, false ) ) - { - CViewRenderer::getInstance()->reset(); - return false; - } - } + if( !loadMapFiles( files.mapFiles ) ) + return false; if( !parser->parseInterface( files.guiFiles, false ) ) return false; @@ -119,6 +107,26 @@ namespace GUIEditor return true; } + bool NelGUICtrl::loadMapFiles( const std::vector< std::string > &v ) + { + std::vector< std::string >::const_iterator itr; + for( itr = v.begin(); itr != v.end(); ++itr ) + { + const std::string &file = *itr; + std::string::size_type i = file.find_last_of( '.' ); + std::string mapFile = file.substr( 0, i ); + mapFile.append( ".txt" ); + + if( !CViewRenderer::getInstance()->loadTextures( file, mapFile, false ) ) + { + CViewRenderer::getInstance()->reset(); + return false; + } + } + + return true; + } + bool NelGUICtrl::createNewGUI( const std::string &project, const std::string &window ) { reset(); diff --git a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h index d7d157ccf..d54c78c7a 100644 --- a/code/studio/src/plugins/gui_editor/nelgui_ctrl.h +++ b/code/studio/src/plugins/gui_editor/nelgui_ctrl.h @@ -43,6 +43,7 @@ namespace GUIEditor void init(); bool parse( SProjectFiles &files ); + bool loadMapFiles( const std::vector< std::string > &v ); bool createNewGUI( const std::string &project, const std::string &window ); void draw(); void reset(); diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp index 88d4a19fd..3c9208dfc 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.cpp @@ -28,6 +28,8 @@ QDialog( parent ) connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); connect( m_ui.projectDirTB, SIGNAL( clicked( bool ) ), this, SLOT( onProjectDirTBClicked() ) ); + connect( m_ui.addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) ); + connect( m_ui.removeButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveClicked() ) ); } @@ -50,6 +52,16 @@ QString NewGUIDlg::getProjectDirectory() const return m_ui.projectDirEdit->text(); } +void NewGUIDlg::getMapList( QList< QString > &l ) +{ + l.clear(); + + for( int i = 0; i < m_ui.mapList->count(); i++ ) + { + l.push_back( m_ui.mapList->item( i )->text() ); + } +} + void NewGUIDlg::onOKClicked() { if( m_ui.projectEdit->text().isEmpty() ) @@ -95,4 +107,29 @@ void NewGUIDlg::onProjectDirTBClicked() m_ui.projectDirEdit->setText( dir ); } +void NewGUIDlg::onAddClicked() +{ + if( m_ui.mapEdit->text().isEmpty() ) + return; + + QList< QListWidgetItem* > l = m_ui.mapList->findItems( m_ui.mapEdit->text(), Qt::MatchContains ); + if( !l.isEmpty() ) + { + return; + } + + m_ui.mapList->addItem( m_ui.mapEdit->text() ); + m_ui.mapEdit->clear(); +} + +void NewGUIDlg::onRemoveClicked() +{ + QListWidgetItem *item = m_ui.mapList->currentItem(); + if( item == NULL ) + return; + + delete item; +} + + diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.h b/code/studio/src/plugins/gui_editor/new_gui_dlg.h index f4bf474f7..0d878461c 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.h +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.h @@ -20,6 +20,7 @@ #define NEW_GUI_DLG_H #include "ui_new_gui_dlg.h" +#include class NewGUIDlg : public QDialog { @@ -32,11 +33,14 @@ public: QString getProjectName() const; QString getWindowName() const; QString getProjectDirectory() const; + void getMapList( QList< QString > &l ); private Q_SLOTS: void onOKClicked(); void onCancelClicked(); void onProjectDirTBClicked(); + void onAddClicked(); + void onRemoveClicked(); private: Ui::NewGUIDialog m_ui; diff --git a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui index 7dca6d2a3..bf22e8c6b 100644 --- a/code/studio/src/plugins/gui_editor/new_gui_dlg.ui +++ b/code/studio/src/plugins/gui_editor/new_gui_dlg.ui @@ -6,14 +6,14 @@ 0 0 - 332 - 125 + 399 + 354 New GUI - + @@ -21,7 +21,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -41,17 +41,46 @@ - + - + ... - + + + + Map files + + + + + + Add + + + + + + + + + + Remove + + + + + + + + + + Qt::Horizontal @@ -64,7 +93,7 @@ - + From fae1e39039dc9d0b7e69c124b73bc22a6875b4f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 18:55:17 +0200 Subject: [PATCH 024/240] Don't reject an action property just because it's empty... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index 84302bcf0..c518d7acc 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -728,9 +728,6 @@ namespace GUIEditor { std::string j = element->getProperty( prop.propName ); - if( j.empty() ) - return; - QtProperty *pp = actionMgr->addProperty( prop.propName.c_str() ); if( pp == NULL ) return; From ab76b7ed85630c41abe00f84ffc6ecfa9ca6ab84 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 19:15:59 +0200 Subject: [PATCH 025/240] It's not a bad idea to actually retrieve the version if we load it... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/project_file_parser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/studio/src/plugins/gui_editor/project_file_parser.cpp b/code/studio/src/plugins/gui_editor/project_file_parser.cpp index a10f5d783..856b3c164 100644 --- a/code/studio/src/plugins/gui_editor/project_file_parser.cpp +++ b/code/studio/src/plugins/gui_editor/project_file_parser.cpp @@ -58,6 +58,7 @@ namespace GUIEditor projectFiles.projectName = files.projectName; projectFiles.masterGroup = files.masterGroup; projectFiles.activeGroup = files.activeGroup; + projectFiles.version = files.version; } unsigned long CProjectFileParser::getProjectVersion() const From 2b5898565f4ec153c71b8b42fc65dd285c9c25a5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 13 Oct 2014 20:15:41 +0200 Subject: [PATCH 026/240] Don't disable the active group before serializing. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_serializer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_serializer.cpp b/code/studio/src/plugins/gui_editor/widget_serializer.cpp index fd4e7cfbe..8006a6b50 100644 --- a/code/studio/src/plugins/gui_editor/widget_serializer.cpp +++ b/code/studio/src/plugins/gui_editor/widget_serializer.cpp @@ -93,8 +93,6 @@ namespace GUIEditor return false; } - ag->setActive( false ); - if( mg->serializeSubGroups( root ) == NULL ) { ag->setActive( true ); @@ -103,8 +101,6 @@ namespace GUIEditor return false; } - ag->setActive( true ); - if( !mg->serializeLinks( root ) ) { xmlFreeNode( root ); From 07a57f81f8b914f2d640d3d979ee7a967834ebee Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 14 Oct 2014 23:45:08 +0200 Subject: [PATCH 027/240] Shadow should not be taken into account for font height, breaks vertical centering --HG-- branch : develop --- code/nel/src/gui/view_text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 815007723..a70194c7b 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -2547,8 +2547,8 @@ namespace NLGUI // Letter size UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext - _FontHeight = (uint) si.StringHeight + (_Shadow?(_ShadowOutline?2:1):0); - _FontLegHeight = (uint) si.StringLine + (_Shadow?(_ShadowOutline?2:1):0); + _FontHeight = (uint) si.StringHeight; // + (_Shadow?(_ShadowOutline?2:1):0); + _FontLegHeight = (uint) si.StringLine; // + (_Shadow?(_ShadowOutline?2:1):0); // Space width si = TextContext->getStringInfo(ucstring(" ")); From b010f224e45233a929360d7df2a471525c848f98 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 14 Oct 2014 23:45:08 +0200 Subject: [PATCH 028/240] Don't use I18N when the required ui prefix is not in the tooltip text (convention actually dictates uitt as tooltip prefix) --HG-- branch : develop --- code/nel/src/gui/view_text.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index a70194c7b..db069a29d 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -2834,7 +2834,8 @@ namespace NLGUI pTooltip->setId(_Id+"_tt"+toString(i)); pTooltip->setAvoidResizeParent(avoidResizeParent()); pTooltip->setRenderLayer(getRenderLayer()); - pTooltip->setDefaultContextHelp(CI18N::get(tempTooltips[i].toString())); + bool isI18N = tempTooltips[i].size() >= 2 && tempTooltips[i][0] == 'u' && tempTooltips[i][1] == 'i'; + pTooltip->setDefaultContextHelp(isI18N ? CI18N::get(tempTooltips[i].toString()) : tempTooltips[i]); pTooltip->setParentPos(this); pTooltip->setParentPosRef(Hotspot_BR); pTooltip->setPosRef(Hotspot_BR); From 3209f48daa8107aaf5f8a203482bc3af0c885d1d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 12:09:57 +0200 Subject: [PATCH 029/240] Don't drop the texture property just because there's no texture assigned... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index c518d7acc..6db5423a3 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -713,9 +713,6 @@ namespace GUIEditor { std::string j = element->getProperty( prop.propName ); - if( j.empty() ) - return; - QtProperty *pp = textureMgr->addProperty( prop.propName.c_str() ); if( pp == NULL ) return; From f91846c9709d708c9f9641892e0ddbddf730b650 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 15 Oct 2014 19:46:43 +0200 Subject: [PATCH 030/240] Fix parent pos and size parsing. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 2 + code/nel/src/gui/interface_element.cpp | 44 +++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 0f9b271ce..c1f6d20e7 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -491,8 +491,10 @@ namespace NLGUI void setEditorSelected( bool b ){ editorSelected = b; } bool isEditorSelected() const{ return editorSelected; } + void parsePosParent( const std::string &id ); void setPosParent( const std::string &id ); void getPosParent( std::string &id ) const; + void parseSizeParent( const std::string &id ); void setSizeParent( const std::string &id ); void getSizeParent( std::string &id ) const; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 620e7dbdb..66eee038e 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -388,13 +388,13 @@ namespace NLGUI ptr = (char*) xmlGetProp( cur, (xmlChar*)"posparent" ); if (ptr) { - setPosParent( std::string( (const char*)ptr ) ); + parsePosParent( (const char*)ptr ); } ptr = (char*) xmlGetProp( cur, (xmlChar*)"sizeparent" ); if (ptr) { - setSizeParent( std::string( (const char*)ptr ) ); + parseSizeParent( (const char*)ptr ); } ptr = (char*) xmlGetProp (cur, (xmlChar*)"sizeref"); @@ -1532,6 +1532,26 @@ namespace NLGUI return false; } + void CInterfaceElement::parsePosParent( const std::string &id ) + { + CInterfaceElement *p = getParent(); + + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentPos( p ); + return; + } + + std::string ppId; + + if( p != NULL ) + ppId = p->getId() + ":" + id; + else + ppId = std::string( "ui:" ) + id; + + CWidgetManager::getInstance()->getParser()->addParentPositionAssociation( this, ppId ); + } + void CInterfaceElement::setPosParent( const std::string &id ) { // Parent or empty id simply means the group parent @@ -1596,6 +1616,26 @@ namespace NLGUI id = p->getId(); } + void CInterfaceElement::parseSizeParent( const std::string &id ) + { + CInterfaceElement *p = getParent(); + + if( ( id == "parent" ) || ( id.empty() ) ) + { + setParentSize( p ); + return; + } + + std::string spId; + + if( p != NULL ) + spId = p->getId() + ":" + id; + else + spId = std::string( "ui:" ) + id; + + CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, spId ); + } + void CInterfaceElement::setSizeParent( const std::string &id ) { // Parent or empty id simply means the group parent From 7487ea41357f16c1e136be1bddc8e955018e4221 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 16 Oct 2014 02:00:45 +0200 Subject: [PATCH 031/240] Higher quality outline, visual difference is relevant only for black --HG-- branch : develop --- code/nel/include/nel/3d/text_context.h | 85 ++++++++++++++++++++------ 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/code/nel/include/nel/3d/text_context.h b/code/nel/include/nel/3d/text_context.h index 064a0ef64..8cf7ad7f0 100644 --- a/code/nel/include/nel/3d/text_context.h +++ b/code/nel/include/nel/3d/text_context.h @@ -147,12 +147,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color = _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); if (_ShadeOutline) { - rCS.render2D(*_Driver, x-_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); - rCS.render2D(*_Driver, x-_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); - rCS.render2D(*_Driver, x+_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + float rext = _ShadeExtent * 0.7071f; + rCS.render2D(*_Driver, x+rext, z-rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-rext, z-rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-rext, z+rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+rext, z+rext, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + } + else + { + rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); } rCS.Color= bkup; } @@ -171,12 +180,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); if (_ShadeOutline) { - rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); - rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); - rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + float rext = _ShadeExtent * 0.7071f; + rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z-rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z-rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z+rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z+rext, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x, z+_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x, z-_ShadeExtent, xmin, ymin, xmax, ymax); + } + else + { + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); } rCS.Color= bkup; } @@ -195,12 +213,21 @@ public: CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); if (_ShadeOutline) { - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); - rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + float rext = _ShadeExtent * 0.7071f; + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y-rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y-rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y+rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y+rext, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + } + else + { + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); } rCS.Color= bkup; } @@ -221,12 +248,21 @@ public: CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); if (_ShadeOutline) { - _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + float rext = _ShadeExtent * 0.7071f; + _TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + else + { + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); } _TempString.Color = bkup; } @@ -251,12 +287,21 @@ public: CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); if (_ShadeOutline) { - _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + float rext = _ShadeExtent * 0.7071f; + _TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + else + { + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); } _TempString.Color = bkup; } From fff4edb2c9bdcc9d3888b2df2e27460db8a476f5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 16 Oct 2014 02:00:53 +0200 Subject: [PATCH 032/240] Maybe solves #210 --HG-- branch : develop --- code/ryzom/client/src/main_loop.cpp | 2 ++ code/ryzom/client/src/motion/user_controls.cpp | 4 ++++ code/ryzom/client/src/motion/user_controls.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index f6d921ff8..9b39c53c9 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1013,6 +1013,7 @@ bool mainLoop() SetMouseCursor (); // Set the cursor. ContextCur.context("STAND BY"); + UserControls.reset(); // set the default box for keyboard setDefaultChatWindow(PeopleInterraction.ChatGroup.Window); @@ -2463,6 +2464,7 @@ bool mainLoop() SetMouseCursor (); // Set the cursor. ContextCur.context("STAND BY"); + UserControls.reset(); // set the default box for keyboard CChatWindow *defaultChatWindow; diff --git a/code/ryzom/client/src/motion/user_controls.cpp b/code/ryzom/client/src/motion/user_controls.cpp index 285848120..897cba9c1 100644 --- a/code/ryzom/client/src/motion/user_controls.cpp +++ b/code/ryzom/client/src/motion/user_controls.cpp @@ -174,6 +174,10 @@ void CUserControls::init() }// init // +void CUserControls::reset() +{ + init(); +} //----------------------------------------------- // needReleaseForward : diff --git a/code/ryzom/client/src/motion/user_controls.h b/code/ryzom/client/src/motion/user_controls.h index eb4de2020..018b2c8e9 100644 --- a/code/ryzom/client/src/motion/user_controls.h +++ b/code/ryzom/client/src/motion/user_controls.h @@ -152,6 +152,8 @@ public: /// Constructor CUserControls(); + void reset(); + /// Return the string associated to the motion Mode. std::string modeStr() const; /// Return the motion Mode. From 176c3d8a4a7ad36412a7e566378c05e0f51421c6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 12 Jul 2014 18:19:25 +0200 Subject: [PATCH 033/240] Add callback template class --HG-- branch : develop --- code/nel/include/nel/misc/callback.h | 327 ++++++++++++++++++ code/nel/samples/misc/CMakeLists.txt | 1 + code/nel/samples/misc/callback/CMakeLists.txt | 9 + code/nel/samples/misc/callback/main.cpp | 62 ++++ 4 files changed, 399 insertions(+) create mode 100644 code/nel/include/nel/misc/callback.h create mode 100644 code/nel/samples/misc/callback/CMakeLists.txt create mode 100644 code/nel/samples/misc/callback/main.cpp diff --git a/code/nel/include/nel/misc/callback.h b/code/nel/include/nel/misc/callback.h new file mode 100644 index 000000000..ca5140f6f --- /dev/null +++ b/code/nel/include/nel/misc/callback.h @@ -0,0 +1,327 @@ +/* + +Copyright (c) 2009-2014, Jan BOON +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NLMISC_CALLBACK_H +#define NLMISC_CALLBACK_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NLMISC { + +#define NLMISC_CALLBACK_TEMPLATE \ +/** \ + * \brief NLMISC_CALLBACK_ARGS_CLASS \ + * \date 2009-03-03 18:09GMT \ + * \author Jan BOON \ + * Callback template \ + */ \ +template \ +class NLMISC_CALLBACK_ARGS_CLASS \ +{ \ + /* Very simple reference counting callback base */ \ + class CCallbackBase \ + { \ + public: \ + CCallbackBase() : m_RefCount(0) \ + { \ + \ + } \ + \ + virtual ~CCallbackBase() \ + { \ + nlassert(!m_RefCount); \ + } \ + \ + void refAdd() \ + { \ + ++m_RefCount; \ + } \ + \ + void refRemove() \ + { \ + --m_RefCount; \ + if (!m_RefCount) \ + delete this; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) = 0; \ + \ + virtual bool equals(const CCallbackBase *callbackBase) = 0; \ + \ + /* disable copy */ \ + CCallbackBase(const CCallbackBase &); \ + CCallbackBase &operator=(const CCallbackBase &); \ + \ + private: \ + uint m_RefCount; \ + }; \ + \ + typedef TReturn TCallbackFunction(NLMISC_CALLBACK_ARGS_DECL); \ + class CCallbackFunction : public CCallbackBase \ + { \ + public: \ + CCallbackFunction(TCallbackFunction *callbackFunction) : m_CallbackFunction(callbackFunction) \ + { \ + nlassert(m_CallbackFunction); \ + } \ + \ + virtual ~CCallbackFunction() \ + { \ + m_CallbackFunction = NULL; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + return m_CallbackFunction(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + virtual bool equals(const CCallbackBase *callbackBase) \ + { \ + const CCallbackFunction *callbackFunction = \ + dynamic_cast(callbackBase); \ + if (!callbackFunction) return false; \ + return m_CallbackFunction == callbackFunction->m_CallbackFunction; \ + } \ + \ + private: \ + TCallbackFunction *m_CallbackFunction; \ + }; \ + \ + template \ + class CCallbackMethod : public CCallbackBase \ + { \ + typedef TReturn (TClass::*TCallbackMethod)(NLMISC_CALLBACK_ARGS_DECL); \ + public: \ + CCallbackMethod(TClass *callbackObject, TCallbackMethod callbackMethod) : m_CallbackObject(callbackObject), m_CallbackMethod(callbackMethod) \ + { \ + nlassert(m_CallbackObject); \ + nlassert(m_CallbackMethod); \ + } \ + \ + virtual ~CCallbackMethod() \ + { \ + m_CallbackObject = NULL; \ + m_CallbackMethod = NULL; \ + } \ + \ + virtual TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + return (m_CallbackObject->*m_CallbackMethod)(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + virtual bool equals(const CCallbackBase *callbackBase) \ + { \ + const CCallbackMethod *callbackMethod = \ + dynamic_cast(callbackBase); \ + if (!callbackMethod) return false; \ + return m_CallbackObject == callbackMethod->m_CallbackObject \ + && m_CallbackMethod == callbackMethod->m_CallbackMethod; \ + } \ + \ + private: \ + TClass *m_CallbackObject; \ + TCallbackMethod m_CallbackMethod; \ + }; \ + \ +public: \ + CCallback() : m_CallbackBase(NULL) \ + { \ + \ + } \ + \ + CCallback(TCallbackFunction *callbackFunction) : m_CallbackBase(new CCallbackFunction(callbackFunction)) \ + { \ + nlassert(m_CallbackBase); \ + m_CallbackBase->refAdd(); \ + } \ + \ + template \ + CCallback(TClass *callbackObject, TReturn (TClass::*callbackMethod)(NLMISC_CALLBACK_ARGS_DECL)) : m_CallbackBase(new CCallbackMethod(callbackObject, callbackMethod)) \ + { \ + nlassert(m_CallbackBase); \ + m_CallbackBase->refAdd(); \ + } \ + \ + CCallback(const CCallback &callback) \ + { \ + m_CallbackBase = callback.m_CallbackBase; \ + if (m_CallbackBase) \ + m_CallbackBase->refAdd(); \ + } \ + \ + CCallback &operator=(const CCallback &callback) \ + { \ + if (m_CallbackBase != callback.m_CallbackBase) \ + { \ + if (m_CallbackBase) \ + m_CallbackBase->refRemove(); \ + m_CallbackBase = callback.m_CallbackBase; \ + if (m_CallbackBase) \ + m_CallbackBase->refAdd(); \ + } \ + return *this; \ + } \ + \ + ~CCallback() \ + { \ + if (m_CallbackBase) \ + { \ + m_CallbackBase->refRemove(); \ + m_CallbackBase = NULL; \ + } \ + } \ + \ + TReturn callback(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + nlassert(m_CallbackBase); \ + return m_CallbackBase->callback(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + TReturn operator()(NLMISC_CALLBACK_ARGS_DECL) \ + { \ + nlassert(m_CallbackBase); \ + return m_CallbackBase->callback(NLMISC_CALLBACK_ARGS_IMPL); \ + } \ + \ + bool valid() const \ + { \ + return m_CallbackBase != NULL; \ + } \ + \ + operator bool() const \ + { \ + return m_CallbackBase != NULL; \ + } \ + \ + bool operator==(const CCallback &callback) \ + { \ + return m_CallbackBase->equals(callback.m_CallbackBase); \ + } \ + \ +private: \ + CCallbackBase *m_CallbackBase; \ + \ +}; /* class CCallback */ \ + +template +class CCallback; + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME +#define NLMISC_CALLBACK_ARGS_DECL +#define NLMISC_CALLBACK_ARGS_IMPL +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA +#define NLMISC_CALLBACK_ARGS_IMPL argsA +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL + +#define NLMISC_CALLBACK_ARGS_CLASS CCallback +#define NLMISC_CALLBACK_ARGS_TYPENAME , typename TArgsA, typename TArgsB, typename TArgsC, typename TArgsD, typename TArgsE, typename TArgsF, typename TArgsG +#define NLMISC_CALLBACK_ARGS_DECL TArgsA argsA, TArgsB argsB, TArgsC argsC, TArgsD argsD, TArgsE argsE, TArgsF argsF, TArgsG argsG +#define NLMISC_CALLBACK_ARGS_IMPL argsA, argsB, argsC, argsD, argsE, argsF, argsG +NLMISC_CALLBACK_TEMPLATE +#undef NLMISC_CALLBACK_ARGS_CLASS +#undef NLMISC_CALLBACK_ARGS_TYPENAME +#undef NLMISC_CALLBACK_ARGS_DECL +#undef NLMISC_CALLBACK_ARGS_IMPL +#undef NLMISC_CALLBACK_ARGS_CLASSNAME + +#undef NLMISC_CALLBACK_TEMPLATE + +} /* namespace NLMISC */ + +#endif /* #ifndef NLMISC_CALLBACK_H */ + +/* end of file */ diff --git a/code/nel/samples/misc/CMakeLists.txt b/code/nel/samples/misc/CMakeLists.txt index 753b418ae..d00a54952 100644 --- a/code/nel/samples/misc/CMakeLists.txt +++ b/code/nel/samples/misc/CMakeLists.txt @@ -1,3 +1,4 @@ +ADD_SUBDIRECTORY(callback) ADD_SUBDIRECTORY(command) ADD_SUBDIRECTORY(configfile) ADD_SUBDIRECTORY(debug) diff --git a/code/nel/samples/misc/callback/CMakeLists.txt b/code/nel/samples/misc/callback/CMakeLists.txt new file mode 100644 index 000000000..62626b0a7 --- /dev/null +++ b/code/nel/samples/misc/callback/CMakeLists.txt @@ -0,0 +1,9 @@ +FILE(GLOB SRC *.cpp) + +ADD_EXECUTABLE(nl_sample_callback ${SRC}) + +TARGET_LINK_LIBRARIES(nl_sample_callback nelmisc) +NL_DEFAULT_PROPS(nl_sample_callback "NeL, Samples, Misc: Callback") +NL_ADD_RUNTIME_FLAGS(nl_sample_callback) + +INSTALL(TARGETS nl_sample_callback RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT samplesmisc) diff --git a/code/nel/samples/misc/callback/main.cpp b/code/nel/samples/misc/callback/main.cpp new file mode 100644 index 000000000..157f3b259 --- /dev/null +++ b/code/nel/samples/misc/callback/main.cpp @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014, Jan BOON +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +class CTestClass +{ +public: + void helloWorld(int y) + { + nldebug("Method call: %i, %i", y, x); + } + int x; +}; + +void functionCall(int i) +{ + nldebug("Function call: %i", i); +} + +typedef NLMISC::CCallback TCallbackType; + +int main(int argc, char **argv) +{ + CTestClass tc; + tc.x = 42; + + TCallbackType cbMethod = TCallbackType(&tc, &CTestClass::helloWorld); + TCallbackType cbFunction = TCallbackType(functionCall); + cbMethod(100); + cbFunction(99); + + getchar(); + + return EXIT_SUCCESS; +} From b1e2b60381a50d5d2737f6b65fcfa376e1d5feb5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 31 Jul 2014 00:46:00 +0200 Subject: [PATCH 034/240] Add render target manager, issue #47 --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/driver_user.h | 5 +- .../include/nel/3d/render_target_manager.h | 83 ++++++++++ code/nel/include/nel/3d/stereo_debugger.h | 8 +- code/nel/include/nel/3d/u_driver.h | 3 + code/nel/src/3d/driver_user.cpp | 2 + code/nel/src/3d/render_target_manager.cpp | 152 ++++++++++++++++++ code/nel/src/3d/stereo_debugger.cpp | 51 ++++-- 7 files changed, 285 insertions(+), 19 deletions(-) create mode 100644 code/nel/include/nel/3d/render_target_manager.h create mode 100644 code/nel/src/3d/render_target_manager.cpp diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index ff9ba8973..94e87d153 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -34,7 +34,7 @@ #include "nel/3d/vertex_stream_manager.h" #include "nel/3d/async_texture_manager.h" #include "nel/3d/lod_character_manager.h" - +#include "nel/3d/render_target_manager.h" namespace NL3D { @@ -71,6 +71,7 @@ protected: bool _WindowInit; CMatrixContext _CurrentMatrixContext; CFontManager _FontManager; + CRenderTargetManager _RenderTargetManager; // Components List. typedef CPtrSet TTextureSet; typedef CPtrSet TTextContextSet; @@ -253,6 +254,8 @@ public: /// get cahce information. virtual std::string getFontManagerCacheInformation() const ; + virtual CRenderTargetManager &getRenderTargetManager() { return _RenderTargetManager; } + /** Create a new texture file, searching in CPath. * \param file filename, local to CPath paths. diff --git a/code/nel/include/nel/3d/render_target_manager.h b/code/nel/include/nel/3d/render_target_manager.h new file mode 100644 index 000000000..c341de3f2 --- /dev/null +++ b/code/nel/include/nel/3d/render_target_manager.h @@ -0,0 +1,83 @@ +/** + * \file render_target_manager.h + * \brief CRenderTargetManager + * \date 2014-07-30 21:30GMT + * \author Jan Boon (Kaetemi) + * CRenderTargetManager + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_RENDER_TARGET_MANAGER_H +#define NL3D_RENDER_TARGET_MANAGER_H +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +// ... + +namespace NL3D { + +class UDriver; +class ITexture; +class CTextureUser; +class CDriverUser; + +struct CRenderTargetDescInt; + +/** + * \brief CRenderTargetManager + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CRenderTargetManager + * Usage: Call 'getRenderTarget' when you start using a render target, + * call 'recycledRenderTarget' when the render target can be recycled. + * At end of frame call cleanup. + * Assumes semi-constant render target quantity between frames, + * except on changes of resolution or feature settings. + */ +class CRenderTargetManager +{ +public: + CRenderTargetManager(); + ~CRenderTargetManager(); + + NL3D::CTextureUser *getRenderTarget(uint width, uint height); + void recycleRenderTarget(NL3D::CTextureUser *renderTarget); + + void cleanup(); + +private: + friend class CDriverUser; + NL3D::UDriver *m_Driver; + std::vector m_RenderTargets; + +}; /* class CRenderTargetManager */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_RENDER_TARGET_MANAGER_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index b07a9630c..a842ee1c8 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -65,10 +65,12 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver); - void releaseTextures(); + /*void releaseTextures(); void initTextures(); void setTextures(); - void verifyTextures(); + void verifyTextures();*/ + void getTextures(); + void recycleTextures(); /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height); @@ -116,9 +118,7 @@ private: CFrustum m_Frustum[NL_STEREO_MAX_USER_CAMERAS]; CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; - NLMISC::CSmartPtr m_LeftTex; NL3D::CTextureUser *m_LeftTexU; - NLMISC::CSmartPtr m_RightTex; NL3D::CTextureUser *m_RightTexU; NL3D::UMaterial m_Mat; NLMISC::CQuadUV m_QuadUV; diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index 67e0c30fd..79ec7b9ac 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -63,6 +63,7 @@ class U3dMouseListener; class ULight; class UAnimationSet; class UWaterEnvMap; +class CRenderTargetManager; typedef void (*emptyProc)(void); @@ -322,6 +323,8 @@ public: /// get cahce information. virtual std::string getFontManagerCacheInformation() const =0; + virtual CRenderTargetManager &getRenderTargetManager() =0; + /** Create a new texture file, searching in CPath. NB: by default a textureFile created with this * method has a setAllowDegradation() at false. diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 7ccf4cfce..c7ec081be 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -192,6 +192,7 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu _PBTri.lock (iba); iba.setTri(0, 0, 1, 2); + _RenderTargetManager.m_Driver = this; _ShapeBank._DriverUser = this; NL_SET_IB_NAME(_PBLine, "CDriverUser::_PBLine"); @@ -1357,6 +1358,7 @@ void CDriverUser::swapBuffers() NL3D_HAUTO_SWAP_DRIVER; _Driver->swapBuffers(); + _RenderTargetManager.cleanup(); } // *************************************************************************** diff --git a/code/nel/src/3d/render_target_manager.cpp b/code/nel/src/3d/render_target_manager.cpp new file mode 100644 index 000000000..7939ba542 --- /dev/null +++ b/code/nel/src/3d/render_target_manager.cpp @@ -0,0 +1,152 @@ +/** + * \file render_target_manager.cpp + * \brief CRenderTargetManager + * \date 2014-07-30 21:30GMT + * \author Jan Boon (Kaetemi) + * CRenderTargetManager + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes +#include + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +struct CRenderTargetDescInt +{ +public: + uint Width; + uint Height; + NL3D::CTextureUser *TextureUser; + NLMISC::CSmartPtr TextureInterface; + bool InUse; + bool Used; +}; + +CRenderTargetManager::CRenderTargetManager() : m_Driver(NULL) +{ + +} + +CRenderTargetManager::~CRenderTargetManager() +{ + // Call twice to reset counters and cleanup + cleanup(); + cleanup(); +} + +NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height) +{ + // Find or create a render target, short loop so no real optimization + for (std::vector::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it) + { + CRenderTargetDescInt *desc = *it; + if (!desc->InUse && desc->Width == width && desc->Height == height) + { + desc->InUse = true; + desc->Used = true; + return desc->TextureUser; + } + } + + nldebug("3D: Create new render target (%u x %u)", width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + CRenderTargetDescInt *desc = new CRenderTargetDescInt(); + desc->TextureInterface = new CTextureBloom(); // LOL + desc->TextureInterface->setRenderTarget(true); + desc->TextureInterface->setReleasable(false); + desc->TextureInterface->resize(width, height); + desc->TextureInterface->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + desc->TextureInterface->setWrapS(ITexture::Clamp); + desc->TextureInterface->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*desc->TextureInterface); + desc->TextureUser = new CTextureUser(desc->TextureInterface); + nlassert(!drvInternal->isTextureRectangle(desc->TextureInterface)); // Not allowed, we only support NPOT for render targets now. + desc->Width = width; + desc->Height = height; + desc->Used = true; + desc->InUse = true; + m_RenderTargets.push_back(desc); + return desc->TextureUser; +} + +void CRenderTargetManager::recycleRenderTarget(NL3D::CTextureUser *renderTarget) +{ + for (std::vector::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it) + { + CRenderTargetDescInt *desc = *it; + if (desc->TextureUser == renderTarget) + { + desc->InUse = false; + return; + } + } + nlerror("3D: Render target not found"); +} + +void CRenderTargetManager::cleanup() +{ + for (sint i = 0; i < (sint)m_RenderTargets.size(); ++i) + { + CRenderTargetDescInt *desc = m_RenderTargets[i]; + nlassert(!desc->InUse); // Assert for debugging, to not allow textures being carried over between frames. Optional assert + if (!desc->InUse) + { + if (!desc->Used) + { + // No longer in use + nldebug("3D: Release render target (%u x %u)", desc->Width, desc->Height); + delete desc->TextureUser; + desc->TextureUser = NULL; + desc->TextureInterface = NULL; // CSmartPtr + m_RenderTargets.erase(m_RenderTargets.begin() + i); + --i; + } + else + { + // Flag for next round + desc->Used = false; + } + } + } +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 34a348c80..39904defc 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -42,6 +42,7 @@ #include #include #include +#include using namespace std; // using namespace NLMISC; @@ -137,8 +138,6 @@ CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0), CStereoDebugger::~CStereoDebugger() { - releaseTextures(); - if (!m_Mat.empty()) { m_Driver->deleteMaterial(m_Mat); @@ -188,8 +187,6 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) if (m_PixelProgram) { - initTextures(); - m_Mat = m_Driver->createMaterial(); m_Mat.initUnlit(); m_Mat.setColor(CRGBA::White); @@ -202,8 +199,6 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) mat->setZFunc(CMaterial::always); mat->setDoubleSided(true); - setTextures(); - m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); @@ -216,6 +211,32 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } } +void CStereoDebugger::getTextures() +{ + nlassert(!m_LeftTexU); + nlassert(!m_RightTexU); + uint32 width, height; + m_Driver->getWindowSize(width, height); + m_LeftTexU = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + m_RightTexU = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTexU->getITexture()); + mat->setTexture(1, m_RightTexU->getITexture()); +} + +void CStereoDebugger::recycleTextures() +{ + nlassert(m_LeftTexU); + nlassert(m_RightTexU); + m_Mat.getObjectPtr()->setTexture(0, NULL); + m_Mat.getObjectPtr()->setTexture(1, NULL); + m_Driver->getRenderTargetManager().recycleRenderTarget(m_LeftTexU); + m_Driver->getRenderTargetManager().recycleRenderTarget(m_RightTexU); + m_LeftTexU = NULL; + m_RightTexU = NULL; +} + +/* void CStereoDebugger::releaseTextures() { if (!m_Mat.empty()) @@ -233,7 +254,7 @@ void CStereoDebugger::releaseTextures() m_RightTexU = NULL; m_RightTex = NULL; // CSmartPtr } - +*//* void CStereoDebugger::initTextures() { uint32 width, height; @@ -261,15 +282,15 @@ void CStereoDebugger::initTextures() drvInternal->setupTexture(*m_RightTex); m_RightTexU = new CTextureUser(m_RightTex); nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed -} - +}*/ +/* void CStereoDebugger::setTextures() { NL3D::CMaterial *mat = m_Mat.getObjectPtr(); mat->setTexture(0, m_LeftTex); mat->setTexture(1, m_RightTex); -} - +}*/ +/* void CStereoDebugger::verifyTextures() { if (m_Driver) @@ -287,7 +308,7 @@ void CStereoDebugger::verifyTextures() setTextures(); } } -} +}*/ /// Gets the required screen resolution for this device bool CStereoDebugger::getScreenResolution(uint &width, uint &height) @@ -407,6 +428,7 @@ bool CStereoDebugger::beginRenderTarget() { if (m_Stage != 3 && m_Driver && (m_Driver->getPolygonMode() == UDriver::Filled)) { + if (!m_LeftTexU) getTextures(); if (m_Stage % 2) static_cast(m_Driver)->setRenderTarget(*m_RightTexU, 0, 0, 0, 0); else static_cast(m_Driver)->setRenderTarget(*m_LeftTexU, 0, 0, 0, 0); return true; @@ -430,14 +452,15 @@ bool CStereoDebugger::endRenderTarget() uint32 width, height; NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); NL3D::CMaterial *mat = m_Mat.getObjectPtr(); - mat->setTexture(0, m_LeftTex); - mat->setTexture(1, m_RightTex); + mat->setTexture(0, m_LeftTexU->getITexture()); + mat->setTexture(1, m_RightTexU->getITexture()); drvInternal->activePixelProgram(m_PixelProgram); m_Driver->drawQuad(m_QuadUV, m_Mat); drvInternal->activePixelProgram(NULL); m_Driver->enableFog(fogEnabled); + recycleTextures(); return true; } From 22d03c5f79031313c599c1f139386179d3e6aaf5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 31 Jul 2014 03:53:38 +0200 Subject: [PATCH 035/240] Mode2D selection --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/render_target_manager.h | 2 +- .../nel/src/3d/driver/opengl/driver_opengl_texture.cpp | 7 ++++--- code/nel/src/3d/render_target_manager.cpp | 10 +++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/3d/render_target_manager.h b/code/nel/include/nel/3d/render_target_manager.h index c341de3f2..9203a5f3d 100644 --- a/code/nel/include/nel/3d/render_target_manager.h +++ b/code/nel/include/nel/3d/render_target_manager.h @@ -64,7 +64,7 @@ public: CRenderTargetManager(); ~CRenderTargetManager(); - NL3D::CTextureUser *getRenderTarget(uint width, uint height); + NL3D::CTextureUser *getRenderTarget(uint width, uint height, bool mode2D = false); void recycleRenderTarget(NL3D::CTextureUser *renderTarget); void cleanup(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index f26b53254..10dea6d7e 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -2401,10 +2401,11 @@ bool CDriverGL::copyTargetToTexture (ITexture *tex, bool CDriverGL::getRenderTargetSize (uint32 &width, uint32 &height) { H_AUTO_OGL(CDriverGL_getRenderTargetSize) - if (_TextureTarget) + NLMISC::CSmartPtr tex = _TextureTarget ? _TextureTarget : (_RenderTargetFBO ? _RenderTargetFBO : NULL); + if (tex) { - width = _TextureTarget->getWidth(); - height = _TextureTarget->getHeight(); + width = tex->getWidth(); + height = tex->getHeight(); } else { diff --git a/code/nel/src/3d/render_target_manager.cpp b/code/nel/src/3d/render_target_manager.cpp index 7939ba542..ba6172ac6 100644 --- a/code/nel/src/3d/render_target_manager.cpp +++ b/code/nel/src/3d/render_target_manager.cpp @@ -53,6 +53,7 @@ struct CRenderTargetDescInt public: uint Width; uint Height; + bool Mode2D; NL3D::CTextureUser *TextureUser; NLMISC::CSmartPtr TextureInterface; bool InUse; @@ -71,13 +72,13 @@ CRenderTargetManager::~CRenderTargetManager() cleanup(); } -NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height) +NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height, bool mode2D) { // Find or create a render target, short loop so no real optimization for (std::vector::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it) { CRenderTargetDescInt *desc = *it; - if (!desc->InUse && desc->Width == width && desc->Height == height) + if (!desc->InUse && desc->Width == width && desc->Height == height && desc->Mode2D == mode2D) { desc->InUse = true; desc->Used = true; @@ -88,7 +89,9 @@ NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint heigh nldebug("3D: Create new render target (%u x %u)", width, height); NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); CRenderTargetDescInt *desc = new CRenderTargetDescInt(); - desc->TextureInterface = new CTextureBloom(); // LOL + CTextureBloom *tex = new CTextureBloom(); // LOL + tex->mode2D(mode2D); + desc->TextureInterface = tex; desc->TextureInterface->setRenderTarget(true); desc->TextureInterface->setReleasable(false); desc->TextureInterface->resize(width, height); @@ -100,6 +103,7 @@ NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint heigh nlassert(!drvInternal->isTextureRectangle(desc->TextureInterface)); // Not allowed, we only support NPOT for render targets now. desc->Width = width; desc->Height = height; + desc->Mode2D = mode2D; desc->Used = true; desc->InUse = true; m_RenderTargets.push_back(desc); From 61f97fae40dfadca44ac91f93a567715cf7e09e5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 31 Jul 2014 17:41:56 +0200 Subject: [PATCH 036/240] Fix issue with render target in OpenGL when size not specified --HG-- branch : multipass-stereo --- code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 10dea6d7e..58d708b09 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -2314,11 +2314,16 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width if(tex->isBloomTexture() && supportBloomEffect()) { + // NOTE: No support for mip map level here! + uint32 w, h; getWindowSize(w, h); getViewport(_OldViewport); + if (!width) width = tex->getWidth(); + if (!height) height = tex->getHeight(); + CViewport newVP; newVP.init(0, 0, ((float)width/(float)w), ((float)height/(float)h)); setupViewport(newVP); @@ -2401,7 +2406,7 @@ bool CDriverGL::copyTargetToTexture (ITexture *tex, bool CDriverGL::getRenderTargetSize (uint32 &width, uint32 &height) { H_AUTO_OGL(CDriverGL_getRenderTargetSize) - NLMISC::CSmartPtr tex = _TextureTarget ? _TextureTarget : (_RenderTargetFBO ? _RenderTargetFBO : NULL); + NLMISC::CSmartPtr tex = _RenderTargetFBO ? _RenderTargetFBO : (_TextureTarget ? _TextureTarget : NULL); if (tex) { width = tex->getWidth(); From 79c6f500546b828268c56681eb035845133166b8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 31 Jul 2014 18:25:50 +0200 Subject: [PATCH 037/240] Render target format (for alpha) --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/render_target_manager.h | 4 ++-- code/nel/src/3d/render_target_manager.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/3d/render_target_manager.h b/code/nel/include/nel/3d/render_target_manager.h index 9203a5f3d..cae8e31b0 100644 --- a/code/nel/include/nel/3d/render_target_manager.h +++ b/code/nel/include/nel/3d/render_target_manager.h @@ -36,7 +36,7 @@ #include // Project includes -// ... +#include namespace NL3D { @@ -64,7 +64,7 @@ public: CRenderTargetManager(); ~CRenderTargetManager(); - NL3D::CTextureUser *getRenderTarget(uint width, uint height, bool mode2D = false); + NL3D::CTextureUser *getRenderTarget(uint width, uint height, bool mode2D = false, UTexture::TUploadFormat format = UTexture::Auto); void recycleRenderTarget(NL3D::CTextureUser *renderTarget); void cleanup(); diff --git a/code/nel/src/3d/render_target_manager.cpp b/code/nel/src/3d/render_target_manager.cpp index ba6172ac6..0c4daa507 100644 --- a/code/nel/src/3d/render_target_manager.cpp +++ b/code/nel/src/3d/render_target_manager.cpp @@ -51,9 +51,13 @@ namespace NL3D { struct CRenderTargetDescInt { public: + // Options uint Width; uint Height; bool Mode2D; + UTexture::TUploadFormat Format; + + // Data NL3D::CTextureUser *TextureUser; NLMISC::CSmartPtr TextureInterface; bool InUse; @@ -72,13 +76,13 @@ CRenderTargetManager::~CRenderTargetManager() cleanup(); } -NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height, bool mode2D) +NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height, bool mode2D, UTexture::TUploadFormat format) { // Find or create a render target, short loop so no real optimization for (std::vector::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it) { CRenderTargetDescInt *desc = *it; - if (!desc->InUse && desc->Width == width && desc->Height == height && desc->Mode2D == mode2D) + if (!desc->InUse && desc->Width == width && desc->Height == height && desc->Mode2D == mode2D && desc->Format == format) { desc->InUse = true; desc->Used = true; @@ -94,6 +98,7 @@ NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint heigh desc->TextureInterface = tex; desc->TextureInterface->setRenderTarget(true); desc->TextureInterface->setReleasable(false); + desc->TextureInterface->setUploadFormat((ITexture::TUploadFormat)(uint32)format); desc->TextureInterface->resize(width, height); desc->TextureInterface->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); desc->TextureInterface->setWrapS(ITexture::Clamp); @@ -104,6 +109,7 @@ NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint heigh desc->Width = width; desc->Height = height; desc->Mode2D = mode2D; + desc->Format = format; desc->Used = true; desc->InUse = true; m_RenderTargets.push_back(desc); From caefb04928cd57280849bc68a506a040e8b07abd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 1 Aug 2014 13:20:55 +0200 Subject: [PATCH 038/240] Restore camera and scene viewport after disabling VR --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_debugger.h | 2 ++ code/nel/include/nel/3d/stereo_display.h | 2 ++ code/nel/include/nel/3d/stereo_ovr.h | 3 +++ code/nel/src/3d/stereo_debugger.cpp | 6 ++++++ code/nel/src/3d/stereo_ovr.cpp | 8 ++++++++ code/ryzom/client/src/release.cpp | 10 ++++++++++ 6 files changed, 31 insertions(+) diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index a842ee1c8..ba9fff68d 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -78,6 +78,8 @@ public: virtual void updateCamera(uint cid, const NL3D::UCamera *camera); /// Get the frustum to use for clipping virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + /// Get the original frustum of the camera + virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const; /// Is there a next pass virtual bool nextPass(); diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 3b9c73b74..78db78e07 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -101,6 +101,8 @@ public: virtual void updateCamera(uint cid, const NL3D::UCamera *camera) = 0; /// Get the frustum to use for clipping virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const = 0; + /// Get the original frustum of the camera + virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const = 0; /// Is there a next pass virtual bool nextPass() = 0; diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index ba6895bf0..b92830b36 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -91,6 +91,8 @@ public: virtual void updateCamera(uint cid, const NL3D::UCamera *camera); /// Get the frustum to use for clipping virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + /// Get the original frustum of the camera + virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const; /// Is there a next pass virtual bool nextPass(); @@ -152,6 +154,7 @@ private: CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS]; CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 39904defc..3a3144113 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -328,6 +328,12 @@ void CStereoDebugger::getClippingFrustum(uint cid, NL3D::UCamera *camera) const // do nothing } +/// Get the original frustum of the camera +void CStereoDebugger::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const +{ + // do nothing, as we never modified it +} + /// Is there a next pass bool CStereoDebugger::nextPass() { diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 402d9b2d0..e7816587b 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -400,6 +400,8 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height) void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { + m_OriginalFrustum[cid] = camera->getFrustum(); + float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); @@ -427,6 +429,12 @@ void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const camera->setFrustum(m_ClippingFrustum[cid]); } +/// Get the original frustum of the camera +void CStereoOVR::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_OriginalFrustum[cid]); +} + void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) { if (camera->getFrustum().Near != m_LeftFrustum[cid].Near diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index b40d68b35..3f36bca5d 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -516,6 +516,16 @@ void releaseStereoDisplayDevice() { if (StereoDisplay) { + StereoDisplay->getOriginalFrustum(0, &MainCam); + if (SceneRoot) + { + UCamera cam = SceneRoot->getCam(); + StereoDisplay->getOriginalFrustum(1, &cam); + } + nlassert(Driver); + Driver->setViewport(NL3D::CViewport()); + nlassert(Scene); + Scene->setViewport(NL3D::CViewport()); delete StereoDisplay; StereoDisplay = NULL; StereoHMD = NULL; From f32c3bf6b0ef4c9f947aa37deeeb4425d774b2d5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 1 Aug 2014 15:23:13 +0200 Subject: [PATCH 039/240] Temporary crashfix, ref #68 --HG-- branch : multipass-stereo --- code/nel/src/3d/particle_system.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/3d/particle_system.cpp b/code/nel/src/3d/particle_system.cpp index 3b25c3e1e..f6060640b 100644 --- a/code/nel/src/3d/particle_system.cpp +++ b/code/nel/src/3d/particle_system.cpp @@ -422,6 +422,11 @@ void CParticleSystem::step(TPass pass, TAnimationTime ellapsedTime, CParticleSys NL_PS_FUNC_MAIN(CParticleSystem_step) CHECK_INTEGRITY OwnerModel = &model; + if (!_CoordSystemInfo.Matrix) + { + nlwarning("3D: BUG: CParticleSystem::step -> !_CoordSystemInfo.Matrix"); + return; + } nlassert(_CoordSystemInfo.Matrix); // matrix not set for position of system if (_UserCoordSystemInfo) { From c11706feb8295b6d47dfe067c74d8b1e28fc77bd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 1 Aug 2014 15:44:12 +0200 Subject: [PATCH 040/240] Project GUI into space --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_hmd.h | 3 + code/nel/include/nel/3d/stereo_ovr.h | 22 ++- code/nel/src/3d/stereo_ovr.cpp | 218 ++++++++++++++++++++++----- code/ryzom/client/src/main_loop.cpp | 20 ++- 4 files changed, 211 insertions(+), 52 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_hmd.h b/code/nel/include/nel/3d/stereo_hmd.h index 95c159cfd..3276e78fe 100644 --- a/code/nel/include/nel/3d/stereo_hmd.h +++ b/code/nel/include/nel/3d/stereo_hmd.h @@ -53,6 +53,9 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const = 0; + /// Set the GUI reference + virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix) = 0; + /// Get GUI center (1 = width, 1 = height, 0 = center) virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const = 0; diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index b92830b36..a215ff8b6 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -123,6 +123,9 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; + /// Set the GUI reference + virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix); + /// Get GUI center (1 = width, 1 = height, 0 = center) virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; @@ -134,21 +137,23 @@ public: /// Set the scale of the game in units per meter virtual void setScale(float s); - - static void listDevices(std::vector &devicesOut); - static bool isLibraryInUse(); - static void releaseLibrary(); - - /// Calculates internal camera information based on the reference camera void initCamera(uint cid, const NL3D::UCamera *camera); + /// Render GUI + void renderGUI(); + /// Checks if the device used by this class was actually created bool isDeviceCreated(); + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + private: CStereoOVRDevicePtr *m_DevicePtr; int m_Stage; int m_SubStage; + CViewport m_RegularViewport; CViewport m_LeftViewport; CViewport m_RightViewport; CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; @@ -156,12 +161,13 @@ private: CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS]; CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_InterfaceCameraMatrix; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; UDriver *m_Driver; - NLMISC::CSmartPtr m_BarrelTex; - NL3D::CTextureUser *m_BarrelTexU; + NL3D::CTextureUser *m_SceneTexture; NL3D::UMaterial m_BarrelMat; + NL3D::CTextureUser *m_GUITexture; NLMISC::CQuadUV m_BarrelQuadLeft; NLMISC::CQuadUV m_BarrelQuadRight; NLMISC::CRefPtr m_PixelProgram; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e7816587b..789d48926 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -169,7 +169,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -213,9 +213,6 @@ CStereoOVR::~CStereoOVR() m_BarrelMat.getObjectPtr()->setTexture(0, NULL); m_Driver->deleteMaterial(m_BarrelMat); } - delete m_BarrelTexU; - m_BarrelTexU = NULL; - m_BarrelTex = NULL; // CSmartPtr delete m_PixelProgram; m_PixelProgram = NULL; @@ -340,7 +337,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) { m_Driver = driver; - m_BarrelTex = new CTextureBloom(); // lol bloom + /*m_BarrelTex = new CTextureBloom(); // lol bloom m_BarrelTex->setRenderTarget(true); m_BarrelTex->setReleasable(false); m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); @@ -348,7 +345,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelTex->setWrapS(ITexture::Clamp); m_BarrelTex->setWrapT(ITexture::Clamp); drvInternal->setupTexture(*m_BarrelTex); - m_BarrelTexU = new CTextureUser(m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex);*/ m_BarrelMat = m_Driver->createMaterial(); m_BarrelMat.initUnlit(); @@ -361,7 +358,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) barrelMat->setZWrite(false); barrelMat->setZFunc(CMaterial::always); barrelMat->setDoubleSided(true); - barrelMat->setTexture(0, m_BarrelTex); + // barrelMat->setTexture(0, m_BarrelTex); m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); @@ -373,7 +370,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); - nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + // nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); @@ -448,53 +445,59 @@ bool CStereoOVR::nextPass() // Do not allow weird stuff. uint32 width, height; m_Driver->getWindowSize(width, height); - nlassert(width == m_DevicePtr->HMDInfo.HResolution); - nlassert(height == m_DevicePtr->HMDInfo.VResolution); + // nlassert(width == m_DevicePtr->HMDInfo.HResolution); + // nlassert(height == m_DevicePtr->HMDInfo.VResolution); if (m_Driver->getPolygonMode() == UDriver::Filled) { - switch (m_Stage) + switch (m_Stage) // Previous stage { case 0: + m_Stage += 2; + m_SubStage = 0; + // stage 2: + // draw interface 2d (onto render target) + return true; + case 2: ++m_Stage; m_SubStage = 0; - // stage 1: + // stage 3: // (initBloom) // clear buffer // draw scene left return true; - case 1: + case 3: ++m_Stage; m_SubStage = 0; - // stage 2: + // stage 4: // draw scene right return true; - case 2: + case 4: ++m_Stage; m_SubStage = 0; - // stage 3: + // stage 5: // (endBloom) // draw interface 3d left return true; - case 3: + case 5: ++m_Stage; m_SubStage = 0; - // stage 4: + // stage 6: // draw interface 3d right return true; - case 4: + /*case 6: ++m_Stage; m_SubStage = 0; - // stage 5: + // stage 7: // (endInterfacesDisplayBloom) // draw interface 2d left return true; - case 5: + case 7: ++m_Stage; m_SubStage = 0; - // stage 6: + // stage 8: // draw interface 2d right - return true; + return true;*/ case 6: m_Stage = 0; m_SubStage = 0; @@ -526,26 +529,30 @@ bool CStereoOVR::nextPass() const NL3D::CViewport &CStereoOVR::getCurrentViewport() const { - if (m_Stage % 2) return m_LeftViewport; + if (m_Stage == 2) return m_RegularViewport; + else if (m_Stage % 2) return m_LeftViewport; else return m_RightViewport; } const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const { - if (m_Stage % 2) return m_LeftFrustum[cid]; + if (m_Stage == 2) return m_OriginalFrustum[cid]; + else if (m_Stage % 2) return m_LeftFrustum[cid]; else return m_RightFrustum[cid]; } void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const { - if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + if (m_Stage == 2) camera->setFrustum(m_OriginalFrustum[cid]); + else if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); else camera->setFrustum(m_RightFrustum[cid]); } void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { CMatrix translate; - if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + if (m_Stage == 2) { } + else if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); CMatrix mat = m_CameraMatrix[cid] * translate; if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) @@ -564,7 +571,7 @@ bool CStereoOVR::wantClear() { switch (m_Stage) { - case 1: + case 3: m_SubStage = 1; return true; } @@ -575,8 +582,8 @@ bool CStereoOVR::wantScene() { switch (m_Stage) { - case 1: - case 2: + case 3: + case 4: m_SubStage = 2; return true; } @@ -587,8 +594,8 @@ bool CStereoOVR::wantInterface3D() { switch (m_Stage) { - case 3: - case 4: + case 5: + case 6: m_SubStage = 3; return true; } @@ -599,37 +606,163 @@ bool CStereoOVR::wantInterface2D() { switch (m_Stage) { - case 5: - case 6: + case 2: m_SubStage = 4; return true; } return m_Driver->getPolygonMode() != UDriver::Filled; } - /// Returns non-NULL if a new render target was set bool CStereoOVR::beginRenderTarget() { // render target always set before driver clear // nlassert(m_SubStage <= 1); - if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled)) + + // Set GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) { - static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + nlassert(!m_GUITexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); + m_GUITexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height, true, UTexture::RGBA8888); + static_cast(m_Driver)->setRenderTarget(*m_GUITexture); + m_Driver->clearBuffers(NLMISC::CRGBA(0, 0, 0, 0)); return true; } + + // Begin 3D scene render target + if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + nlassert(!m_SceneTexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); // Temporary limitation, TODO: scaling! + m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); + return true; + } + return false; } +void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix) +{ + m_InterfaceCameraMatrix = matrix; +} + +void CStereoOVR::renderGUI() +{ + + /*CMatrix mat; + mat.translate(m_InterfaceCameraMatrix.getPos()); + CVector dir = m_InterfaceCameraMatrix.getJ(); + dir.z = 0; + dir.normalize(); + if (dir.y < 0) + mat.rotateZ(float(NLMISC::Pi+asin(dir.x))); + else + mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); + m_Driver->setModelMatrix(mat);*/ + m_Driver->setModelMatrix(m_InterfaceCameraMatrix); + + { + nlassert(m_GUITexture); + + NLMISC::CQuadUV quad; + + NL3D::UMaterial umat = m_Driver->createMaterial(); + umat.initUnlit(); + umat.setColor(NLMISC::CRGBA::White); + umat.setDoubleSided(true); + umat.setBlend(true); + umat.setAlphaTest(false); + NL3D::CMaterial *mat = umat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::Normal); + mat->setBlendFunc(CMaterial::one, CMaterial::TBlend::invsrcalpha); + mat->setZWrite(false); + // mat->setZFunc(CMaterial::always); // Not nice + mat->setDoubleSided(true); + mat->setTexture(0, m_GUITexture->getITexture()); + + // user options + float height = 6.0f; + float distance = 3.0f; + + uint32 winw, winh; + m_Driver->getWindowSize(winw, winh); + float width = height * (float)winw / (float)winh; + + NLMISC::CQuadUV quadUV; + quadUV.V0 = CVector(-(width * 0.5f), distance, -(height * 0.5f)); + quadUV.V1 = CVector((width * 0.5f), distance, -(height * 0.5f)); + quadUV.V2 = CVector((width * 0.5f), distance, (height * 0.5f)); + quadUV.V3 = CVector(-(width * 0.5f), distance, (height * 0.5f)); + quadUV.Uv0 = CUV(0.f, 0.f); + quadUV.Uv1 = CUV(1.f, 0.f); + quadUV.Uv2 = CUV(1.f, 1.f); + quadUV.Uv3 = CUV(0.f, 1.f); + + m_Driver->drawQuad(quadUV, umat); + + m_Driver->deleteMaterial(umat); + } + + { + NLMISC::CLine line(NLMISC::CVector(0, 3, -3), NLMISC::CVector(0, 3, 3)); + + NL3D::UMaterial mat = m_Driver->createMaterial(); + mat.setZWrite(false); + mat.setZFunc(UMaterial::always); + mat.setDoubleSided(true); + mat.setColor(NLMISC::CRGBA::Red); + mat.setBlend(false); + + m_Driver->drawLine(line, mat); + + m_Driver->deleteMaterial(mat); + } +} + /// Returns true if a render target was fully drawn bool CStereoOVR::endRenderTarget() { // after rendering of course // nlassert(m_SubStage > 1); + + // End GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // End GUI render target + nlassert(m_GUITexture); + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + } + + // End of 3D Interface pass left + if (m_Driver && m_Stage == 5 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + } + + // End of 3D Interface pass right + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_GUITexture); + m_GUITexture = NULL; + } + + // End 3D scene render target if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui { - CTextureUser cu; - (static_cast(m_Driver))->setRenderTarget(cu); + nlassert(m_SceneTexture); + + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); bool fogEnabled = m_Driver->fogEnabled(); m_Driver->enableFog(false); @@ -640,7 +773,7 @@ bool CStereoOVR::endRenderTarget() m_Driver->getWindowSize(width, height); NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); - barrelMat->setTexture(0, m_BarrelTex); + barrelMat->setTexture(0, m_SceneTexture->getITexture()); drvInternal->activePixelProgram(m_PixelProgram); @@ -705,8 +838,13 @@ bool CStereoOVR::endRenderTarget() drvInternal->activePixelProgram(NULL); m_Driver->enableFog(fogEnabled); + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_SceneTexture); + m_SceneTexture = NULL; + return true; } + return false; } diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 36c918ca5..e6a9c50a0 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1386,8 +1386,20 @@ bool mainLoop() MainCam.setRotQuat(View.currentViewQuat()); if (StereoHMD) { + CMatrix camMatrix; + camMatrix.translate(MainCam.getMatrix().getPos()); + CVector dir = MainCam.getMatrix().getJ(); + dir.z = 0; + dir.normalize(); + if (dir.y < 0) + camMatrix.rotateZ(float(NLMISC::Pi+asin(dir.x))); + else + camMatrix.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); + + StereoHMD->setInterfaceMatrix(camMatrix); + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); - NLMISC::CMatrix camMatrix = MainCam.getMatrix(); + // NLMISC::CMatrix camMatrix = MainCam.getMatrix(); NLMISC::CMatrix hmdMatrix; hmdMatrix.setRot(hmdOrient); NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future @@ -1645,7 +1657,7 @@ bool mainLoop() { if (Render) { - if (ClientCfg.Bloom) + if (!StereoDisplay && ClientCfg.Bloom) // NO VR BLOOMZ { nlassert(bloomStage == 0); // set bloom parameters before applying bloom effect @@ -1695,7 +1707,7 @@ bool mainLoop() // Render if (Render) { - if (ClientCfg.Bloom && bloomStage == 1) + if (!StereoDisplay && ClientCfg.Bloom && bloomStage == 1) // NO VR BLOOMZ { // End the actual bloom effect visible in the scene. if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); @@ -1822,7 +1834,7 @@ bool mainLoop() // special case in OpenGL : all scene has been display in render target, // now, final texture is display with a quad - if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) + if (!StereoDisplay && !ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ { // End bloom effect system after drawing the 3d interface (z buffer related). if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); From e4e1e3e5a1108e8eb70264a92ce5da8b885a269b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 1 Aug 2014 23:11:35 +0200 Subject: [PATCH 041/240] Sound orientation with HMD and Headphones --HG-- branch : multipass-stereo --- code/ryzom/client/src/main_loop.cpp | 7 +++++++ code/ryzom/client/src/user_entity.cpp | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index e6a9c50a0..0ef01f2e4 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1407,6 +1407,13 @@ bool mainLoop() NLMISC::CMatrix mat = ((camMatrix * hmdMatrix) * posMatrix); MainCam.setPos(mat.getPos()); MainCam.setRotQuat(mat.getRot()); + + if (true) // TODO: ClientCfg.Headphone + { + // NOTE: non-(StereoHMD+Headphone) impl in user_entity.cpp + SoundMngr->setListenerPos(mat.getPos()); // TODO: Move ears back ... :) + SoundMngr->setListenerOrientation(mat.getJ(), mat.getK()); + } } if (StereoDisplay) { diff --git a/code/ryzom/client/src/user_entity.cpp b/code/ryzom/client/src/user_entity.cpp index c8652fd43..bb632cf4e 100644 --- a/code/ryzom/client/src/user_entity.cpp +++ b/code/ryzom/client/src/user_entity.cpp @@ -2384,10 +2384,13 @@ void CUserEntity::updateSound(const TTime &time) if (SoundMngr == 0) return; - SoundMngr->setListenerPos(pos()); - const CMatrix &camMat = MainCam.getMatrix(); - SoundMngr->setListenerOrientation(camMat.getJ(), camMat.getK()); - + if (!(StereoHMD && true)) // TODO: ClientCfg.Headphone + { + // NOTE: StereoHMD+Headphone impl in main_loop.cpp + SoundMngr->setListenerPos(pos()); + const CMatrix &camMat = MainCam.getMatrix(); + SoundMngr->setListenerOrientation(camMat.getJ(), camMat.getK()); + } if (ClientCfg.Light) return; From f2dd6083fa8e5fa230aec1deca227180e871243a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 2 Aug 2014 19:50:26 +0200 Subject: [PATCH 042/240] Cylindrical GUI --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr.cpp | 62 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 789d48926..a8dfffe50 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -692,6 +692,9 @@ void CStereoOVR::renderGUI() m_Driver->getWindowSize(winw, winh); float width = height * (float)winw / (float)winh; + float bottom = -(height * 0.5f); + float top = (height * 0.5f); + NLMISC::CQuadUV quadUV; quadUV.V0 = CVector(-(width * 0.5f), distance, -(height * 0.5f)); quadUV.V1 = CVector((width * 0.5f), distance, -(height * 0.5f)); @@ -701,8 +704,63 @@ void CStereoOVR::renderGUI() quadUV.Uv1 = CUV(1.f, 0.f); quadUV.Uv2 = CUV(1.f, 1.f); quadUV.Uv3 = CUV(0.f, 1.f); + + const uint nbQuads = 128; + static CVertexBuffer vb; + static CIndexBuffer ib; + + vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag); + vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false); + vb.setNumVertices((nbQuads + 1) * 2); + + { + CVertexBufferReadWrite vba; + vb.lock(vba); + float relWidth = width / distance; + float quadWidth = relWidth / (float)nbQuads; + for (uint i = 0; i < nbQuads + 1; ++i) + { + uint vi0 = i * 2; + uint vi1 = vi0 + 1; + float lineH = -(relWidth * 0.5f) + quadWidth * (float)i; + float lineUV = (float)i / (float)(nbQuads + 1); + float left = sin(lineH) * distance; + float forward = cos(lineH) * distance; + vba.setVertexCoord(vi0, left, forward, bottom); + vba.setTexCoord(vi0, 0, lineUV, 0.0f); + vba.setVertexCoord(vi1, left, forward, top); + vba.setTexCoord(vi1, 0, lineUV, 1.0f); + } + } + + ib.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); + ib.setPreferredMemory(CIndexBuffer::RAMVolatile, false); + ib.setNumIndexes(nbQuads * 6); + + { + CIndexBufferReadWrite iba; + ib.lock(iba); + for (uint i = 0; i < nbQuads; ++i) + { + uint ti0 = i * 2; + uint ti1 = ti0 + 1; + uint bl = ti0; + uint tl = ti0 + 1; + uint br = ti0 + 2; + uint tr = ti0 + 3; + iba.setTri(ti0 * 3, bl, tl, br); + iba.setTri(ti1 * 3, br, tl, tr); + } + } + + IDriver *driver = static_cast(m_Driver)->getDriver(); + // m_Driver->setPolygonMode(UDriver::Line); + driver->activeVertexBuffer(vb); + driver->activeIndexBuffer(ib); + driver->renderTriangles(*umat.getObjectPtr(), 0, nbQuads * 2); //renderRawQuads(umat, 0, 128); + // m_Driver->setPolygonMode(UDriver::Filled); - m_Driver->drawQuad(quadUV, umat); + // m_Driver->drawQuad(quadUV, umat); m_Driver->deleteMaterial(umat); } @@ -712,7 +770,7 @@ void CStereoOVR::renderGUI() NL3D::UMaterial mat = m_Driver->createMaterial(); mat.setZWrite(false); - mat.setZFunc(UMaterial::always); + // mat.setZFunc(UMaterial::always); // Not nice! mat.setDoubleSided(true); mat.setColor(NLMISC::CRGBA::Red); mat.setBlend(false); From 1965d46dceb05afd42f886ab435994a5bd669e7e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 2 Aug 2014 20:11:28 +0200 Subject: [PATCH 043/240] Off-center GUI cylinder --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr.cpp | 48 ++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index a8dfffe50..943828f1b 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -664,6 +664,21 @@ void CStereoOVR::renderGUI() mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); m_Driver->setModelMatrix(mat);*/ m_Driver->setModelMatrix(m_InterfaceCameraMatrix); + + { + NLMISC::CLine line(NLMISC::CVector(0, 5, 2), NLMISC::CVector(0, 5, 3)); + + NL3D::UMaterial mat = m_Driver->createMaterial(); + mat.setZWrite(false); + // mat.setZFunc(UMaterial::always); // Not nice! + mat.setDoubleSided(true); + mat.setColor(NLMISC::CRGBA::Red); + mat.setBlend(false); + + m_Driver->drawLine(line, mat); + + m_Driver->deleteMaterial(mat); + } { nlassert(m_GUITexture); @@ -685,8 +700,9 @@ void CStereoOVR::renderGUI() mat->setTexture(0, m_GUITexture->getITexture()); // user options - float height = 6.0f; - float distance = 3.0f; + float height = 3.0f; + float distance = 1.5f; + float offcenter = 0.75f; //1.5f; uint32 winw, winh; m_Driver->getWindowSize(winw, winh); @@ -716,19 +732,20 @@ void CStereoOVR::renderGUI() { CVertexBufferReadWrite vba; vb.lock(vba); - float relWidth = width / distance; + float radius = distance + offcenter; + float relWidth = width / radius; float quadWidth = relWidth / (float)nbQuads; for (uint i = 0; i < nbQuads + 1; ++i) { uint vi0 = i * 2; uint vi1 = vi0 + 1; float lineH = -(relWidth * 0.5f) + quadWidth * (float)i; - float lineUV = (float)i / (float)(nbQuads + 1); - float left = sin(lineH) * distance; - float forward = cos(lineH) * distance; - vba.setVertexCoord(vi0, left, forward, bottom); + float lineUV = (float)i / (float)(nbQuads); + float left = sin(lineH) * radius; + float forward = cos(lineH) * radius; + vba.setVertexCoord(vi0, left, forward - offcenter, bottom); vba.setTexCoord(vi0, 0, lineUV, 0.0f); - vba.setVertexCoord(vi1, left, forward, top); + vba.setVertexCoord(vi1, left, forward - offcenter, top); vba.setTexCoord(vi1, 0, lineUV, 1.0f); } } @@ -764,21 +781,6 @@ void CStereoOVR::renderGUI() m_Driver->deleteMaterial(umat); } - - { - NLMISC::CLine line(NLMISC::CVector(0, 3, -3), NLMISC::CVector(0, 3, 3)); - - NL3D::UMaterial mat = m_Driver->createMaterial(); - mat.setZWrite(false); - // mat.setZFunc(UMaterial::always); // Not nice! - mat.setDoubleSided(true); - mat.setColor(NLMISC::CRGBA::Red); - mat.setBlend(false); - - m_Driver->drawLine(line, mat); - - m_Driver->deleteMaterial(mat); - } } /// Returns true if a render target was fully drawn From 503292065c98593636b78486084021549a37baa7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 00:56:26 +0200 Subject: [PATCH 044/240] Simplify GUI projection settings --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 943828f1b..8b8f8a90a 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -700,9 +700,11 @@ void CStereoOVR::renderGUI() mat->setTexture(0, m_GUITexture->getITexture()); // user options - float height = 3.0f; + float scale = 1.0f; float distance = 1.5f; - float offcenter = 0.75f; //1.5f; + float offcenter = 0.75f; + + float height = scale * distance * 2.0f; uint32 winw, winh; m_Driver->getWindowSize(winw, winh); From 78ce8f4f25cb55828705f0f61e31b8e04bf0a965 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 18:59:19 +0200 Subject: [PATCH 045/240] GL: Share depth and stencil to get similar behaviour to D3D driver --HG-- branch : multipass-stereo --- .../src/3d/driver/opengl/driver_opengl.cpp | 2 + code/nel/src/3d/driver/opengl/driver_opengl.h | 28 +++- .../driver/opengl/driver_opengl_texture.cpp | 136 ++++++++++-------- 3 files changed, 101 insertions(+), 65 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index da047ad20..2152d718f 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -1032,6 +1032,8 @@ bool CDriverGL::release() // Call IDriver::release() before, to destroy textures, shaders and VBs... IDriver::release(); + nlassert(_DepthStencilFBOs.empty()); + _SwapBufferCounter = 0; // delete querries diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index ffefafdee..67a5895dc 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -146,6 +146,23 @@ public: virtual uint getVisibleCount(); }; +// *************************************************************************** +class CDepthStencilFBO : public NLMISC::CRefCount +{ +public: + CDepthStencilFBO(CDriverGL *driver, uint width, uint height); + ~CDepthStencilFBO(); + + uint Width; + uint Height; + + GLuint DepthFBOId; + GLuint StencilFBOId; + +private: + CDriverGL *m_Driver; +}; + // *************************************************************************** class CTextureDrvInfosGL : public ITextureDrvInfos { @@ -173,12 +190,9 @@ public: GLuint FBOId; // depth stencil FBO id - GLuint DepthFBOId; - GLuint StencilFBOId; - - bool InitFBO; bool AttachDepthStencil; - bool UsePackedDepthStencil; + NLMISC::CSmartPtr DepthStencilFBO; + bool InitFBO; // The current wrap modes assigned to the texture. ITexture::TWrapMode WrapS; @@ -685,6 +699,7 @@ private: friend class CTextureDrvInfosGL; friend class CVertexProgamDrvInfosGL; friend class CPixelProgamDrvInfosGL; + friend class CDepthStencilFBO; private: // Version of the driver. Not the interface version!! Increment when implementation of the driver change. @@ -880,8 +895,11 @@ private: // viewport before call to setRenderTarget, if BFO extension is supported CViewport _OldViewport; + // Current FBO render target CSmartPtr _RenderTargetFBO; + // Share the same backbuffer for FBO render targets with window size + std::vector _DepthStencilFBOs; // Num lights return by GL_MAX_LIGHTS uint _MaxDriverLight; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 58d708b09..9b798ae51 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -73,12 +73,8 @@ CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDri #endif FBOId = 0; - DepthFBOId = 0; - StencilFBOId = 0; - InitFBO = false; AttachDepthStencil = true; - UsePackedDepthStencil = drvGl->supportPackedDepthStencil(); TextureUsedIdx = 0; } @@ -98,9 +94,9 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL() _Driver->_TextureUsed[TextureUsedIdx] = NULL; } - if(InitFBO) - { #ifdef USE_OPENGLES + if (InitFBO) + { nglDeleteFramebuffersOES(1, &FBOId); if(AttachDepthStencil) { @@ -108,24 +104,73 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL() if(!UsePackedDepthStencil) nglDeleteRenderbuffersOES(1, &StencilFBOId); } -#else - nglDeleteFramebuffersEXT(1, &FBOId); - if(AttachDepthStencil) - { - nglDeleteRenderbuffersEXT(1, &DepthFBOId); - if(!UsePackedDepthStencil) - nglDeleteRenderbuffersEXT(1, &StencilFBOId); - } + } #endif +} + +CDepthStencilFBO::CDepthStencilFBO(CDriverGL *driver, uint width, uint height) +{ + nldebug("3D: Init shared FBO"); + + m_Driver = driver; + Width = width; + Height = height; + + bool packedDepthStencil = driver->supportPackedDepthStencil(); + nglGenRenderbuffersEXT(1, &DepthFBOId); + if (packedDepthStencil) + StencilFBOId = DepthFBOId; + else + nglGenRenderbuffersEXT(1, &StencilFBOId); + + if (packedDepthStencil) + { + //nldebug("3D: using packed depth stencil"); + nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId); + nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height); + } + else + { + nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId); + nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height); + /* + nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId); + nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, width, height); + */ + } + + nlassert(DepthFBOId); + nlassert(StencilFBOId); + + driver->_DepthStencilFBOs.push_back(this); +} + +CDepthStencilFBO::~CDepthStencilFBO() +{ + // driver remove + m_Driver->_DepthStencilFBOs.erase(std::find(m_Driver->_DepthStencilFBOs.begin(), m_Driver->_DepthStencilFBOs.end(), this)); + + if (DepthFBOId) + { + nldebug("3D: Release shared FBO"); + nglDeleteRenderbuffersEXT(1, &DepthFBOId); + if (StencilFBOId == DepthFBOId) + StencilFBOId = 0; + DepthFBOId = 0; + } + if (StencilFBOId) + { + nglDeleteRenderbuffersEXT(1, &StencilFBOId); + StencilFBOId = 0; } } // *************************************************************************** bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) { - if(!InitFBO) + if (!InitFBO) { - if(tex->isBloomTexture()) + if (tex->isBloomTexture()) { AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D(); } @@ -179,49 +224,33 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) #else // generate IDs nglGenFramebuffersEXT(1, &FBOId); - if(AttachDepthStencil) - { - nglGenRenderbuffersEXT(1, &DepthFBOId); - if(UsePackedDepthStencil) - StencilFBOId = DepthFBOId; - else - nglGenRenderbuffersEXT(1, &StencilFBOId); - } - + //nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId); // initialize FBO nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId); nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureMode, ID, 0); - // attach depth/stencil render to FBO - // note: for some still unkown reason it's impossible to add - // a stencil buffer as shown in the respective docs (see - // opengl.org extension registry). Until a safe approach to add - // them is found, there will be no attached stencil for the time - // being, aside of using packed depth+stencil buffers. - if(AttachDepthStencil) + // attach depth stencil + if (AttachDepthStencil) { - if(UsePackedDepthStencil) + for (std::vector::iterator it(_Driver->_DepthStencilFBOs.begin()), end(_Driver->_DepthStencilFBOs.end()); it != end; ++it) { - //nldebug("3D: using packed depth stencil"); - nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId); - nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, tex->getWidth(), tex->getHeight()); + if ((*it)->Width == tex->getWidth() && (*it)->Height == tex->getHeight()) + { + DepthStencilFBO = (*it); + break; + } } - else + if (!DepthStencilFBO) { - nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId); - nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, tex->getWidth(), tex->getHeight()); - /* - nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId); - nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, tex->getWidth(), tex->getHeight()); - */ + DepthStencilFBO = new CDepthStencilFBO(_Driver, tex->getWidth(), tex->getHeight()); } nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, DepthFBOId); + GL_RENDERBUFFER_EXT, DepthStencilFBO->DepthFBOId); nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, StencilFBOId); + GL_RENDERBUFFER_EXT, DepthStencilFBO->StencilFBOId); nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); } #endif @@ -339,17 +368,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex) #endif if (AttachDepthStencil) { -#ifdef USE_OPENGLES - nglDeleteRenderbuffersOES(1, &DepthFBOId); -#else - nglDeleteRenderbuffersEXT(1, &DepthFBOId); -#endif - if(!UsePackedDepthStencil) -#ifdef USE_OPENGLES - nglDeleteRenderbuffersOES(1, &StencilFBOId); -#else - nglDeleteRenderbuffersEXT(1, &StencilFBOId); -#endif + DepthStencilFBO = NULL; } } @@ -2260,11 +2279,8 @@ void CDriverGL::swapTextureHandle(ITexture &tex0, ITexture &tex1) swap(t0->MinFilter, t1->MinFilter); swap(t0->TextureMode, t1->TextureMode); swap(t0->FBOId, t1->FBOId); - swap(t0->DepthFBOId, t1->DepthFBOId); - swap(t0->StencilFBOId, t1->StencilFBOId); + swap(t0->DepthStencilFBO, t1->DepthStencilFBO); swap(t0->InitFBO, t1->InitFBO); - swap(t0->AttachDepthStencil, t1->AttachDepthStencil); - swap(t0->UsePackedDepthStencil, t1->UsePackedDepthStencil); } From 8af686f7ef9c9f50fb39b55ee020dd29f27d7e52 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 20:35:05 +0200 Subject: [PATCH 046/240] 3D: Cleanup bloom effect --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/bloom_effect.h | 44 +- code/nel/src/3d/bloom_effect.cpp | 386 +++++------------- code/ryzom/client/src/init.cpp | 2 +- code/ryzom/client/src/main_loop.cpp | 42 +- .../client/src/snowballs_client.cpp | 14 +- 5 files changed, 169 insertions(+), 319 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index c10967254..cb577f5bd 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -31,6 +31,7 @@ namespace NL3D class UDriver; class UScene; +class CTextureUser; //----------------------------------------------------------------------------------------------------------- //---------------------------------------- CBloomEffect ----------------------------------------------------- @@ -52,19 +53,14 @@ public: // Destructor ~CBloomEffect(); - // Called after the Driver initialization to indicate if OpenGL or Direct3D is used. - // They are some differences in bloom algorithm depending on this API choice. - // If bloom effect is activated and supported, private method init() is called to initialize - // textures and materials. - // initBloomEffect = false => directx - // initBloomEffect = true => opengl - void init(bool initBloomEffect); + // Called after the Driver initialization. + void init(); // must be called before init void setDriver(UDriver *driver) { _Driver = driver; } UDriver* getDriver() const { return _Driver; } - // must be called before initBloom + // must be called before applyBloom void setScene(UScene *scene) { _Scene = scene; } UScene* getScene() const { return _Scene; } @@ -76,6 +72,9 @@ public: void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; } uint8 getDensityBloom() const { return _DensityBloom; } + // Applies bloom to the current render target, if backbuffer is true the final image is rendered to the backbuffer instead of to a render target + void applyBloom(bool backbuffer); + // Called at the beginning of renderAll method in the main loop, if window has been resized, // reinitialize bloom textures according to new window size. // The bloom texture (_InitText attribute) which is used as render target during scene render @@ -83,11 +82,11 @@ public: // If window size exceeds 256*256 the textures used to apply blur are reinitialized with // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // power of 2, lower than this window dimension. - void initBloom(); + // void initBloom(); // Called at the end of renderAll method in the main loop, recover stretched texture, apply // both blur passes, and the blending operation between initial render target and the blured one. - void endBloom(); + // void endBloom(); // In OpenGL, the use of FBO implies that Z buffer values of scene render have been stored in // a depth render target. Then, to display 3D interfaces, we must display them in the same FBO, @@ -95,15 +94,12 @@ public: // This method is called at the end of interfaces display in the main loop, to display final render target // (with added interfaces) in the color frame buffer. // NB : In Direct3D, the final render target is displayed at the end of endBloom call. - void endInterfacesDisplayBloom(); + // void endInterfacesDisplayBloom(); private: - // Initialize textures and materials. - void init(); - // Initialize a bloom texture with new dimensions. - void initTexture(NLMISC::CSmartPtr & tex, bool isMode2D, uint32 width, uint32 height); + // void initTexture(NLMISC::CSmartPtr & tex, bool isMode2D, uint32 width, uint32 height); // Called in endBloom method to build a blurred texture. Two passes (then two calls) // are necessary : horizontal and vertical. @@ -130,6 +126,7 @@ private: // density of bloom uint8 _DensityBloom; +/* // render target textures // used to display scene NLMISC::CSmartPtr _InitText; @@ -140,12 +137,13 @@ private: NLMISC::CSmartPtr _BlurHorizontalTex; // original render target NLMISC::CSmartPtr _OriginalRenderTarget; +*/ // materials // used to display first texture in doBlur passes. NL3D::UMaterial _BlurMat; - // used to display final render target texture in endInterfacesDisplayBloom call (OpenGL). + // used to display final render target texture onto the backbuffer NL3D::UMaterial _DisplayInitMat; // used to blend initial scene render target texture and blur texture according to a // dest+src - dest*src blend operation. @@ -158,19 +156,23 @@ private: NLMISC::CQuadUV _BlurQuad; NLMISC::CQuadUV _DisplayQuad; - // openGL or Direct3D? - bool _InitBloomEffect; - // textures and materials already initialized? bool _Init; // current window dimensions - uint32 _WndWidth; - uint32 _WndHeight; + /*uint32 _WndWidth; + uint32 _WndHeight;*/ + // Temporary variables used during applyBloom(...) -> // current blur texture dimensions uint32 _BlurWidth; uint32 _BlurHeight; + // used as stretched texture from _InitText, as displayed texture in first blur pass, + // and as render target in second blur pass. + CTextureUser *_BlurFinalTex; + // used as render target in first blur pass, and as displayed texture on second blur pass. + CTextureUser *_BlurHorizontalTex; + // <- }; } // NL3D diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 7809aba2c..5bc6a2bf4 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -72,79 +72,49 @@ CBloomEffect::CBloomEffect() _SquareBloom = true; _DensityBloom = 128; _Init = false; - _InitBloomEffect = false; + + _BlurFinalTex = NULL; + _BlurHorizontalTex = NULL; } //----------------------------------------------------------------------------------------------------------- CBloomEffect::~CBloomEffect() { - if(_Init) + if (_Init) { - if(!_DisplayInitMat.empty()) + if (!_DisplayInitMat.empty()) { - _DisplayInitMat.getObjectPtr()->setTexture(0, NULL); if (_Driver) _Driver->deleteMaterial(_DisplayInitMat); } - _InitText = NULL; - if(!_DisplayBlurMat.empty()) + if (!_DisplayBlurMat.empty()) { - _DisplayBlurMat.getObjectPtr()->setTexture(0, NULL); if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat); } - if(!_DisplaySquareBlurMat.empty()) + + if (!_DisplaySquareBlurMat.empty()) { - _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL); - _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL); if (_Driver) _Driver->deleteMaterial(_DisplaySquareBlurMat); } - if(!_BlurMat.empty()) + if (!_BlurMat.empty()) { - _BlurMat.getObjectPtr()->setTexture(0, NULL); - _BlurMat.getObjectPtr()->setTexture(1, NULL); - _BlurMat.getObjectPtr()->setTexture(2, NULL); - _BlurMat.getObjectPtr()->setTexture(3, NULL); if (_Driver) _Driver->deleteMaterial(_BlurMat); } - - _BlurHorizontalTex = NULL; - _BlurFinalTex = NULL; } } //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::init(bool initBloomEffect) -{ - _InitBloomEffect = initBloomEffect; - - if(((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) - init(); -} - -//----------------------------------------------------------------------------------------------------------- - void CBloomEffect::init() { - _WndWidth = _Driver->getWindowWidth(); - _WndHeight = _Driver->getWindowHeight(); + if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) + return; _BlurWidth = 256; _BlurHeight = 256; - // initialize textures - _InitText = NULL; - _BlurHorizontalTex = NULL; - _BlurFinalTex = NULL; - if(_InitBloomEffect) - { - initTexture(_InitText, false, _WndWidth, _WndHeight); - } - initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight); - initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight); - // initialize blur material _BlurMat = _Driver->createMaterial(); CMaterial * matObject = _BlurMat.getObjectPtr(); @@ -188,20 +158,16 @@ void CBloomEffect::init() matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor); // initialize display materials - if(_InitBloomEffect) - { - _DisplayInitMat = _Driver->createMaterial(); - CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); - _DisplayInitMat.initUnlit(); - _DisplayInitMat.setColor(CRGBA::White); - _DisplayInitMat.setBlend (false); - _DisplayInitMat.setAlphaTest (false); - matObjectInit->setBlendFunc (CMaterial::one, CMaterial::zero); - matObjectInit->setZWrite(false); - matObjectInit->setZFunc(CMaterial::always); - matObjectInit->setDoubleSided(true); - matObjectInit->setTexture(0, _InitText); - } + _DisplayInitMat = _Driver->createMaterial(); + CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); + _DisplayInitMat.initUnlit(); + _DisplayInitMat.setColor(CRGBA::White); + _DisplayInitMat.setBlend(false); + _DisplayInitMat.setAlphaTest (false); + matObjectInit->setBlendFunc(CMaterial::one, CMaterial::zero); + matObjectInit->setZWrite(false); + matObjectInit->setZFunc(CMaterial::always); + matObjectInit->setDoubleSided(true); // initialize linear blur material _DisplayBlurMat = _Driver->createMaterial(); @@ -214,7 +180,7 @@ void CBloomEffect::init() matObjectFinal->setZFunc(CMaterial::always); matObjectFinal->setDoubleSided(true); - matObjectFinal->setTexture(0, _BlurFinalTex); + // matObjectFinal->setTexture(0, _BlurFinalTex); matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate); matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor); @@ -230,12 +196,10 @@ void CBloomEffect::init() matObjectFinal->setZFunc(CMaterial::always); matObjectFinal->setDoubleSided(true); - matObjectFinal->setTexture(0, _BlurFinalTex); matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate); matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor); - matObjectFinal->setTexture(1, _BlurFinalTex); matObjectFinal->texEnvOpRGB(1, CMaterial::Modulate); matObjectFinal->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor); @@ -245,148 +209,74 @@ void CBloomEffect::init() _DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f); _DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f); _DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f); + _DisplayQuad.Uv0 = CUV(0.f, 0.f); + _DisplayQuad.Uv1 = CUV(1.f, 0.f); + _DisplayQuad.Uv2 = CUV(1.f, 1.f); + _DisplayQuad.Uv3 = CUV(0.f, 1.f); _BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f); _BlurQuad.V1 = CVector(1.f, -1.f, 0.5f); _BlurQuad.V2 = CVector(1.f, 1.f, 0.5f); _BlurQuad.V3 = CVector(-1.f, 1.f, 0.5f); + _BlurQuad.Uv0 = CUV(0.f, 0.f); + _BlurQuad.Uv1 = CUV(1.f, 0.f); + _BlurQuad.Uv2 = CUV(1.f, 1.f); + _BlurQuad.Uv3 = CUV(0.f, 1.f); _Init = true; } //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::initTexture(CSmartPtr & tex, bool isMode2D, uint32 width, uint32 height) +void CBloomEffect::applyBloom(bool backbuffer) { - NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - - tex = new CTextureBloom(); - tex->setReleasable(false); - tex->resize(width, height); - tex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - tex->setWrapS(ITexture::Clamp); - tex->setWrapT(ITexture::Clamp); - ((CTextureBloom *)tex.getPtr())->mode2D(isMode2D); - if(tex->TextureDrvShare==NULL || tex->TextureDrvShare->DrvTexture.getPtr()==NULL) - { - tex->setRenderTarget(true); - drvInternal->setupTexture(*tex); - } -} - -//----------------------------------------------------------------------------------------------------------- - -void CBloomEffect::initBloom() // clientcfg -{ - if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) + if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; // don't activate bloom when PolygonMode is different from Filled if (_Driver->getPolygonMode() != UDriver::Filled) return; - if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) + if (_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) return; - if(!_Init) + if (!_Init) init(); - _OriginalRenderTarget = static_cast(_Driver)->getDriver()->getRenderTarget(); + CDriverUser *dru = static_cast(_Driver); + IDriver *drv = dru->getDriver(); - // if window resize, reinitialize textures - if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight()) - { - _WndWidth = _Driver->getWindowWidth(); - _WndHeight = _Driver->getWindowHeight(); + NL3D::ITexture *renderTarget = drv->getRenderTarget(); + nlassert(renderTarget); + nlassert(renderTarget->isBloomTexture()); - if(_InitBloomEffect) - { - // release old SmartPtr - _DisplayInitMat.getObjectPtr()->setTexture(0, NULL); - _InitText = NULL; + uint width = renderTarget->getWidth(); + uint height = renderTarget->getHeight(); + bool mode2D = static_cast(renderTarget)->isMode2D(); + nlassert(renderTarget->getUploadFormat() == ITexture::Auto); - initTexture(_InitText, false, _WndWidth, _WndHeight); + if (width >= 256) _BlurWidth = 256; + else _BlurWidth = raiseToNextPowerOf2(width) / 2; + if (height >= 256) _BlurHeight = 256; + else _BlurHeight = raiseToNextPowerOf2(height) / 2; - _DisplayInitMat.getObjectPtr()->setTexture(0, _InitText); - } - - bool reinitBlurTextures = false; - if(_WndWidth<_BlurWidth || _WndHeight<_BlurHeight) - { - _BlurWidth = raiseToNextPowerOf2(_WndWidth)/2; - _BlurHeight = raiseToNextPowerOf2(_WndHeight)/2; - - reinitBlurTextures = true; - } - - if(_WndWidth>256 && _BlurWidth!=256) - { - _BlurWidth = 256; - reinitBlurTextures = true; - } - - if(_WndHeight>256 && _BlurHeight!=256) - { - _BlurHeight = 256; - reinitBlurTextures = true; - } - - if(reinitBlurTextures) - { - // release old SmartPtr - _DisplayBlurMat.getObjectPtr()->setTexture(0, NULL); - - _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL); - _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL); - - _BlurMat.getObjectPtr()->setTexture(0, NULL); - _BlurMat.getObjectPtr()->setTexture(1, NULL); - _BlurMat.getObjectPtr()->setTexture(2, NULL); - _BlurMat.getObjectPtr()->setTexture(3, NULL); + nlassert(!_BlurFinalTex); + _BlurFinalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true); + nlassert(!_BlurHorizontalTex); + _BlurHorizontalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true); - _BlurHorizontalTex = NULL; - _BlurFinalTex = NULL; + _DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture()); + _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture()); + _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex->getITexture()); - initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight); - initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight); - - _DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex); - - _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex); - _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex); - } - } - - if (!_OriginalRenderTarget) - { - NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); - if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) - { - nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); - return; - } - } -} - -//----------------------------------------------------------------------------------------------------------- - -void CBloomEffect::endBloom() // clientcfg -{ - if(!_Driver->supportBloomEffect() || !_Init) - return; + CTextureUser texNull; + dru->setRenderTarget(texNull); - // don't activate bloom when PolygonMode is different from Filled - if (_Driver->getPolygonMode() != UDriver::Filled) return; - - if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) - return; - - CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); - CTextureUser txt2(_BlurFinalTex); - CRect rect1(0, 0, _WndWidth, _WndHeight); + // Stretch original render target into blur texture + CTextureUser txt1(renderTarget); + CTextureUser txt2(_BlurFinalTex->getITexture()); + CRect rect1(0, 0, width, height); CRect rect2(0, 0, _BlurWidth, _BlurHeight); - // stretch rect - ((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1, - txt2, rect2); + dru->stretchRect(_Scene, txt1, rect1, txt2, rect2); // horizontal blur pass doBlur(true); @@ -395,7 +285,38 @@ void CBloomEffect::endBloom() // clientcfg doBlur(false); // apply blur with a blend operation + drv->setRenderTarget(renderTarget); applyBlur(); + + // draw final result to backbuffer if last effect + if (backbuffer) + { + CTextureUser texNull; + dru->setRenderTarget(texNull); + + _DisplayInitMat.getObjectPtr()->setTexture(0, renderTarget); + + UCamera pCam = _Scene->getCam(); + _Driver->setMatrixMode2D11(); + _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); + _Driver->setMatrixMode3D(pCam); + } + + // cleanup material texture references + _DisplayInitMat.getObjectPtr()->setTexture(0, NULL); + _DisplayBlurMat.getObjectPtr()->setTexture(0, NULL); + _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL); + _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL); + _BlurMat.getObjectPtr()->setTexture(0, NULL); + _BlurMat.getObjectPtr()->setTexture(1, NULL); + _BlurMat.getObjectPtr()->setTexture(2, NULL); + _BlurMat.getObjectPtr()->setTexture(3, NULL); + + // recycle render targets + _Driver->getRenderTargetManager().recycleRenderTarget(_BlurFinalTex); + _BlurFinalTex = NULL; + _Driver->getRenderTargetManager().recycleRenderTarget(_BlurHorizontalTex); + _BlurHorizontalTex = NULL; } //----------------------------------------------------------------------------------------------------------- @@ -404,49 +325,6 @@ void CBloomEffect::applyBlur() { NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - /*if (_OriginalRenderTarget) - { - CTextureUser txt(_OriginalRenderTarget); - if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) - { - nlwarning("setRenderTarget return false with original render target for bloom effect\n"); - return; - } - } - // in opengl, display in init texture - else if(_InitBloomEffect) - { - CTextureUser txt(_InitText); - if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) - { - nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); - return; - } - }*/ - CTextureUser txtApply = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); - if(!(static_cast(_Driver)->setRenderTarget(txtApply, 0, 0, _WndWidth, _WndHeight))) - { - nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); - return; - } - - // display blur texture - // initialize blur texture coordinates - if(_InitBloomEffect) - { - _BlurQuad.Uv0 = CUV(0.f, 0.f); - _BlurQuad.Uv1 = CUV(1.f, 0.f); - _BlurQuad.Uv2 = CUV(1.f, 1.f); - _BlurQuad.Uv3 = CUV(0.f, 1.f); - } - else - { - _BlurQuad.Uv0 = CUV(0.f, 1.f); - _BlurQuad.Uv1 = CUV(1.f, 1.f); - _BlurQuad.Uv2 = CUV(1.f, 0.f); - _BlurQuad.Uv3 = CUV(0.f, 0.f); - } - // initialize vertex program drvInternal->activeVertexProgram(TextureOffsetVertexProgram); drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); @@ -478,50 +356,6 @@ void CBloomEffect::applyBlur() drvInternal->activeVertexProgram(NULL); } -//----------------------------------------------------------------------------------------------------------- - -void CBloomEffect::endInterfacesDisplayBloom() // clientcfg -{ - // Render from render target to screen if necessary. - // Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget. - if ((_OriginalRenderTarget.getPtr() == NULL) && _InitBloomEffect) - { - if(!_Driver->supportBloomEffect() || !_Init) - return; - - // don't activate bloom when PolygonMode is different from Filled - if (_Driver->getPolygonMode() != UDriver::Filled) return; - - if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) - return; - - NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - CTextureUser txtNull; - ((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0); - - // initialize texture coordinates - float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f; - float newV = drvInternal->isTextureRectangle(_InitText) ? (float)_WndHeight : 1.f; - - _DisplayQuad.Uv0 = CUV(0.f, 0.f); - _DisplayQuad.Uv1 = CUV(newU, 0.f); - _DisplayQuad.Uv2 = CUV(newU, newV); - _DisplayQuad.Uv3 = CUV(0.f, newV); - - // init material texture -// CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); - - // display - UCamera pCam = _Scene->getCam(); - _Driver->setMatrixMode2D11(); - _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); - _Driver->setMatrixMode3D(pCam); - } - - _OriginalRenderTarget = NULL; -} - - //----------------------------------------------------------------------------------------------------------- void CBloomEffect::doBlur(bool horizontalBlur) @@ -531,17 +365,17 @@ void CBloomEffect::doBlur(bool horizontalBlur) ITexture * endTexture; // set displayed texture and render target texture of the pass - if(horizontalBlur) + if (horizontalBlur) { blurVec = CVector2f(1.f, 0.f); - startTexture = _BlurFinalTex; - endTexture = _BlurHorizontalTex; + startTexture = _BlurFinalTex->getITexture(); + endTexture = _BlurHorizontalTex->getITexture(); } else { blurVec = CVector2f(0.f, 1.f); - startTexture = _BlurHorizontalTex; - endTexture = _BlurFinalTex; + startTexture = _BlurHorizontalTex->getITexture(); + endTexture = _BlurFinalTex->getITexture(); } NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); @@ -561,20 +395,20 @@ void CBloomEffect::doBlur(bool horizontalBlur) // set several decal constants in order to obtain in the render target texture a mix of color // of a texel and its neighbored texels on the axe of the pass. float decalL, decal2L, decalR, decal2R; - if(_InitBloomEffect) - { + // if(_InitBloomEffect) + // { decalL = -0.5f; decal2L = -1.5f; decalR = 0.5f; decal2R = 1.5f; - } - else - { - decalL = 0.f; - decal2L = -1.f; - decalR = 1.f; - decal2R = 2.f; - } + // } + // else + // { + // decalL = 0.f; + // decal2L = -1.f; + // decalR = 1.f; + // decal2R = 2.f; + // } drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y); @@ -587,12 +421,6 @@ void CBloomEffect::doBlur(bool horizontalBlur) matObject->setTexture(2, startTexture); matObject->setTexture(3, startTexture); - // initialize quad - _BlurQuad.Uv0 = CUV(0.0f, 0.0f); - _BlurQuad.Uv1 = CUV(1.f, 0.0f); - _BlurQuad.Uv2 = CUV(1.f, 1.f); - _BlurQuad.Uv3 = CUV(0.0f, 1.f); - // display UCamera pCam = _Scene->getCam(); _Driver->setMatrixMode2D11(); diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index e985c958f..5f0da0136 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1161,7 +1161,7 @@ void prelogInit() CBloomEffect::getInstance().setDriver(Driver); // init bloom effect - CBloomEffect::getInstance().init(driver != UDriver::Direct3d); + CBloomEffect::getInstance().init(); if (StereoDisplay) // VR_CONFIG { diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 0ef01f2e4..6fd494093 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -43,6 +43,8 @@ #include "nel/3d/u_instance_material.h" #include "nel/3d/u_cloud_scape.h" #include "nel/3d/stereo_hmd.h" +#include "nel/3d/render_target_manager.h" +#include "nel/3d/driver_user.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" @@ -561,13 +563,18 @@ void clearBuffers() void renderScene(bool forceFullDetail, bool bloom) { + CTextureUser *effectRenderTarget = NULL; if (bloom) { // set bloom parameters before applying bloom effect CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); // init bloom - CBloomEffect::getInstance().initBloom(); + // CBloomEffect::getInstance().initBloom(); + uint32 winw, winh; + Driver->getWindowSize(winw, winh); + effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); + static_cast(Driver)->setRenderTarget(*effectRenderTarget); } if (forceFullDetail) { @@ -583,8 +590,9 @@ void renderScene(bool forceFullDetail, bool bloom) if (bloom) { // apply bloom effect - CBloomEffect::getInstance().endBloom(); - CBloomEffect::getInstance().endInterfacesDisplayBloom(); + // CBloomEffect::getInstance().endBloom(); + // CBloomEffect::getInstance().endInterfacesDisplayBloom(); + CBloomEffect::getInstance().applyBloom(effectRenderTarget != NULL); // TODO } } @@ -1622,6 +1630,7 @@ bool mainLoop() uint i = 0; uint bloomStage = 0; + CTextureUser *effectRenderTarget = NULL; while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; @@ -1664,14 +1673,20 @@ bool mainLoop() { if (Render) { - if (!StereoDisplay && ClientCfg.Bloom) // NO VR BLOOMZ + if (ClientCfg.Bloom && bloomStage == 0) { - nlassert(bloomStage == 0); // set bloom parameters before applying bloom effect CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); // start bloom effect (just before the first scene element render) - CBloomEffect::instance().initBloom(); + if (!StereoDisplay) // FIXME: Assumes rendering to render target...! + { + uint32 winw, winh; + Driver->getWindowSize(winw, winh); + effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); + static_cast(Driver)->setRenderTarget(*effectRenderTarget); + } + // CBloomEffect::instance().initBloom(); bloomStage = 1; } } @@ -1714,13 +1729,18 @@ bool mainLoop() // Render if (Render) { - if (!StereoDisplay && ClientCfg.Bloom && bloomStage == 1) // NO VR BLOOMZ + if (ClientCfg.Bloom && bloomStage == 1) { // End the actual bloom effect visible in the scene. if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().endBloom(); + CBloomEffect::instance().applyBloom(effectRenderTarget != NULL); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - bloomStage = 2; + if (effectRenderTarget) + { + Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); + effectRenderTarget = NULL; + } + bloomStage = 0; } // for that frame and @@ -1841,14 +1861,14 @@ bool mainLoop() // special case in OpenGL : all scene has been display in render target, // now, final texture is display with a quad - if (!StereoDisplay && !ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ + /*if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ { // End bloom effect system after drawing the 3d interface (z buffer related). if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endInterfacesDisplayBloom(); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 0; - } + }*/ } { diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index b401d80bc..dc8239c8c 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -373,7 +373,7 @@ void initIngame() // initialize bloom effect CBloomEffect::instance().setDriver(Driver); CBloomEffect::instance().setScene(Scene); - CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); + CBloomEffect::instance().init(); CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); CConfiguration::setAndCallback("EnableBloom", cbEnableBloom); @@ -763,12 +763,12 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantClear()) { - if (s_EnableBloom) + /*if (s_EnableBloom) { nlassert(bloomStage == 0); CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) bloomStage = 1; - } + }*/ // 01. Render Driver (background color) Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering @@ -788,14 +788,14 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantInterface3D()) { - if (s_EnableBloom && bloomStage == 1) + /*if (s_EnableBloom && bloomStage == 1) { // End the actual bloom effect visible in the scene. if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endBloom(); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 2; - } + }*/ // 06. Render Interface 3D (player names) // ... @@ -803,14 +803,14 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantInterface2D()) { - if (s_EnableBloom && bloomStage == 2) + /*if (s_EnableBloom && bloomStage == 2) { // End bloom effect system after drawing the 3d interface (z buffer related). if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endInterfacesDisplayBloom(); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 0; - } + }*/ // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) updateCompass(); // Update the compass From 6a21d0503ca83bb39883102367881a3a00c8b854 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 21:09:55 +0200 Subject: [PATCH 047/240] 3D: Cleanup bloom effect --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/driver.h | 3 ++ code/nel/src/3d/bloom_effect.cpp | 51 ++++++++++++++----- code/nel/src/3d/driver.cpp | 2 +- .../src/3d/driver/direct3d/driver_direct3d.h | 1 + code/nel/src/3d/driver/opengl/driver_opengl.h | 2 + 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index cb6ec349c..f19428cfb 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -974,6 +974,9 @@ public: ) = 0; // @} + /// Hack for bloom + virtual bool textureCoordinateAlternativeMode() const = 0; + /// \name Render state: Polygon mode diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 5bc6a2bf4..7d009e29b 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -112,6 +112,9 @@ void CBloomEffect::init() if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; + CDriverUser *dru = static_cast(_Driver); + IDriver *drv = dru->getDriver(); + _BlurWidth = 256; _BlurHeight = 256; @@ -218,10 +221,20 @@ void CBloomEffect::init() _BlurQuad.V1 = CVector(1.f, -1.f, 0.5f); _BlurQuad.V2 = CVector(1.f, 1.f, 0.5f); _BlurQuad.V3 = CVector(-1.f, 1.f, 0.5f); - _BlurQuad.Uv0 = CUV(0.f, 0.f); - _BlurQuad.Uv1 = CUV(1.f, 0.f); - _BlurQuad.Uv2 = CUV(1.f, 1.f); - _BlurQuad.Uv3 = CUV(0.f, 1.f); + if (drv->textureCoordinateAlternativeMode()) + { + _BlurQuad.Uv0 = CUV(0.f, 1.f); + _BlurQuad.Uv1 = CUV(1.f, 1.f); + _BlurQuad.Uv2 = CUV(1.f, 0.f); + _BlurQuad.Uv3 = CUV(0.f, 0.f); + } + else + { + _BlurQuad.Uv0 = CUV(0.f, 0.f); + _BlurQuad.Uv1 = CUV(1.f, 0.f); + _BlurQuad.Uv2 = CUV(1.f, 1.f); + _BlurQuad.Uv3 = CUV(0.f, 1.f); + } _Init = true; } @@ -395,20 +408,30 @@ void CBloomEffect::doBlur(bool horizontalBlur) // set several decal constants in order to obtain in the render target texture a mix of color // of a texel and its neighbored texels on the axe of the pass. float decalL, decal2L, decalR, decal2R; - // if(_InitBloomEffect) - // { + if (drvInternal->textureCoordinateAlternativeMode()) + { + if (horizontalBlur) + { + decalL = 0.5f; + decal2L = -0.5f; + decalR = 1.5f; + decal2R = 2.5f; + } + else + { + decalL = 0.0f; + decal2L = -1.0f; + decalR = 1.0f; + decal2R = 2.0f; + } + } + else + { decalL = -0.5f; decal2L = -1.5f; decalR = 0.5f; decal2R = 1.5f; - // } - // else - // { - // decalL = 0.f; - // decal2L = -1.f; - // decalR = 1.f; - // decal2R = 2.f; - // } + } drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y); diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 2bfb0ea1f..134c24410 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -32,7 +32,7 @@ namespace NL3D { // *************************************************************************** -const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface +const uint32 IDriver::InterfaceVersion = 0x6e; // gpu program interface // *************************************************************************** IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 8b8ac62df..039b6f3ed 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -944,6 +944,7 @@ public: virtual ITexture *getRenderTarget() const; virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); + virtual bool textureCoordinateAlternativeMode() const { return true; }; virtual bool getRenderTargetSize (uint32 &width, uint32 &height); virtual bool fillBuffer (CBitmap &bitmap); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 67a5895dc..c4540b9da 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -572,6 +572,8 @@ public: virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); + virtual bool textureCoordinateAlternativeMode() const { return false; }; + virtual bool getRenderTargetSize (uint32 &width, uint32 &height); From e88dedf00c4906ef39d804a92e5c58c46be76141 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 22:15:44 +0200 Subject: [PATCH 048/240] Adjust render target handling for effects --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/bloom_effect.h | 7 +- code/nel/src/3d/bloom_effect.cpp | 43 +--------- code/ryzom/client/src/init_main_loop.cpp | 27 ++++++ code/ryzom/client/src/main_loop.cpp | 100 ++++++++++++++++------- code/ryzom/client/src/release.cpp | 4 + 5 files changed, 103 insertions(+), 78 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index cb577f5bd..49c959e23 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -72,8 +72,8 @@ public: void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; } uint8 getDensityBloom() const { return _DensityBloom; } - // Applies bloom to the current render target, if backbuffer is true the final image is rendered to the backbuffer instead of to a render target - void applyBloom(bool backbuffer); + // Applies bloom to the current render target + void applyBloom(); // Called at the beginning of renderAll method in the main loop, if window has been resized, // reinitialize bloom textures according to new window size. @@ -143,8 +143,6 @@ private: // materials // used to display first texture in doBlur passes. NL3D::UMaterial _BlurMat; - // used to display final render target texture onto the backbuffer - NL3D::UMaterial _DisplayInitMat; // used to blend initial scene render target texture and blur texture according to a // dest+src - dest*src blend operation. NL3D::UMaterial _DisplayBlurMat; @@ -154,7 +152,6 @@ private: // quads NLMISC::CQuadUV _BlurQuad; - NLMISC::CQuadUV _DisplayQuad; // textures and materials already initialized? bool _Init; diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 7d009e29b..842423661 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -83,11 +83,6 @@ CBloomEffect::~CBloomEffect() { if (_Init) { - if (!_DisplayInitMat.empty()) - { - if (_Driver) _Driver->deleteMaterial(_DisplayInitMat); - } - if (!_DisplayBlurMat.empty()) { if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat); @@ -160,18 +155,6 @@ void CBloomEffect::init() matObject->texEnvArg1RGB(3, CMaterial::Constant, CMaterial::SrcColor); matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor); - // initialize display materials - _DisplayInitMat = _Driver->createMaterial(); - CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); - _DisplayInitMat.initUnlit(); - _DisplayInitMat.setColor(CRGBA::White); - _DisplayInitMat.setBlend(false); - _DisplayInitMat.setAlphaTest (false); - matObjectInit->setBlendFunc(CMaterial::one, CMaterial::zero); - matObjectInit->setZWrite(false); - matObjectInit->setZFunc(CMaterial::always); - matObjectInit->setDoubleSided(true); - // initialize linear blur material _DisplayBlurMat = _Driver->createMaterial(); CMaterial * matObjectFinal = _DisplayBlurMat.getObjectPtr(); @@ -208,15 +191,6 @@ void CBloomEffect::init() matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor); // initialize quads - _DisplayQuad.V0 = CVector(0.f, 0.f, 0.5f); - _DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f); - _DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f); - _DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f); - _DisplayQuad.Uv0 = CUV(0.f, 0.f); - _DisplayQuad.Uv1 = CUV(1.f, 0.f); - _DisplayQuad.Uv2 = CUV(1.f, 1.f); - _DisplayQuad.Uv3 = CUV(0.f, 1.f); - _BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f); _BlurQuad.V1 = CVector(1.f, -1.f, 0.5f); _BlurQuad.V2 = CVector(1.f, 1.f, 0.5f); @@ -241,7 +215,7 @@ void CBloomEffect::init() //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::applyBloom(bool backbuffer) +void CBloomEffect::applyBloom() { if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; @@ -301,22 +275,7 @@ void CBloomEffect::applyBloom(bool backbuffer) drv->setRenderTarget(renderTarget); applyBlur(); - // draw final result to backbuffer if last effect - if (backbuffer) - { - CTextureUser texNull; - dru->setRenderTarget(texNull); - - _DisplayInitMat.getObjectPtr()->setTexture(0, renderTarget); - - UCamera pCam = _Scene->getCam(); - _Driver->setMatrixMode2D11(); - _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); - _Driver->setMatrixMode3D(pCam); - } - // cleanup material texture references - _DisplayInitMat.getObjectPtr()->setTexture(0, NULL); _DisplayBlurMat.getObjectPtr()->setTexture(0, NULL); _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL); _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL); diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index c0da76a32..a2db91b4f 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -40,6 +40,7 @@ #include "nel/3d/u_cloud_scape.h" #include "nel/3d/u_shape_bank.h" #include "nel/3d/u_water_env_map.h" +#include "nel/3d/material.h" // Sound #include "nel/sound/u_audio_mixer.h" // Client @@ -136,6 +137,9 @@ std::string LoadingBitmapFilename; uint64 StartInitTime = 0; uint64 StartPlayTime = 0; +UMaterial EffectMaterial; +NLMISC::CQuadUV EffectQuad; + // texture for the logos std::vector LogoBitmaps; @@ -568,6 +572,29 @@ void initMainLoop() // use this scene for bloom effect CBloomEffect::getInstance().setScene(Scene); + if (EffectMaterial.empty()) + { + EffectMaterial = Driver->createMaterial(); + CMaterial *mat = EffectMaterial.getObjectPtr(); + EffectMaterial.initUnlit(); + EffectMaterial.setColor(CRGBA::White); + EffectMaterial.setBlend(false); + EffectMaterial.setAlphaTest (false); + mat->setBlendFunc(CMaterial::one, CMaterial::zero); + mat->setZWrite(false); + mat->setZFunc(CMaterial::always); + mat->setDoubleSided(true); + } + + EffectQuad.V0 = CVector(0.f, 0.f, 0.5f); + EffectQuad.V1 = CVector(1.f, 0.f, 0.5f); + EffectQuad.V2 = CVector(1.f, 1.f, 0.5f); + EffectQuad.V3 = CVector(0.f, 1.f, 0.5f); + EffectQuad.Uv0 = CUV(0.f, 0.f); + EffectQuad.Uv1 = CUV(1.f, 0.f); + EffectQuad.Uv2 = CUV(1.f, 1.f); + EffectQuad.Uv3 = CUV(0.f, 1.f); + CLandscapePolyDrawer::getInstance().initLandscapePolyDrawingCallback(); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 6fd494093..1a67866ec 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -185,6 +185,9 @@ extern std::vector LogoBitmaps; extern bool IsInRingSession; extern std::string UsedFSAddr; +extern UMaterial EffectMaterial; +extern NLMISC::CQuadUV EffectQuad; + // temp extern NLMISC::CValueSmoother smoothFPS; extern NLMISC::CValueSmoother moreSmoothFPS; @@ -569,8 +572,8 @@ void renderScene(bool forceFullDetail, bool bloom) // set bloom parameters before applying bloom effect CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // init bloom - // CBloomEffect::getInstance().initBloom(); + + // init effect render target uint32 winw, winh; Driver->getWindowSize(winw, winh); effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); @@ -590,9 +593,25 @@ void renderScene(bool forceFullDetail, bool bloom) if (bloom) { // apply bloom effect - // CBloomEffect::getInstance().endBloom(); - // CBloomEffect::getInstance().endInterfacesDisplayBloom(); - CBloomEffect::getInstance().applyBloom(effectRenderTarget != NULL); // TODO + CBloomEffect::getInstance().applyBloom(); + + // draw final result to backbuffer + CDriverUser *dru = static_cast(Driver); + + CTextureUser texNull; + dru->setRenderTarget(texNull); + + EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); + + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + Driver->drawQuad(EffectQuad, EffectMaterial); + Driver->setMatrixMode3D(pCam); + + EffectMaterial.getObjectPtr()->setTexture(0, NULL); + + Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); + effectRenderTarget = NULL; } } @@ -1629,8 +1648,24 @@ bool mainLoop() } uint i = 0; - uint bloomStage = 0; + bool effectRender = false; CTextureUser *effectRenderTarget = NULL; + bool haveEffects = Render && ClientCfg.Bloom; + if (haveEffects) + { + if (!StereoDisplay) + { + uint32 winw, winh; + Driver->getWindowSize(winw, winh); + effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); + static_cast(Driver)->setRenderTarget(*effectRenderTarget); + } + if (ClientCfg.Bloom) + { + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + } + } while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; @@ -1673,22 +1708,7 @@ bool mainLoop() { if (Render) { - if (ClientCfg.Bloom && bloomStage == 0) - { - // set bloom parameters before applying bloom effect - CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); - CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // start bloom effect (just before the first scene element render) - if (!StereoDisplay) // FIXME: Assumes rendering to render target...! - { - uint32 winw, winh; - Driver->getWindowSize(winw, winh); - effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); - static_cast(Driver)->setRenderTarget(*effectRenderTarget); - } - // CBloomEffect::instance().initBloom(); - bloomStage = 1; - } + effectRender = haveEffects; } // Clear buffers @@ -1729,18 +1749,15 @@ bool mainLoop() // Render if (Render) { - if (ClientCfg.Bloom && bloomStage == 1) + if (effectRender) { - // End the actual bloom effect visible in the scene. - if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().applyBloom(effectRenderTarget != NULL); - if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - if (effectRenderTarget) + if (ClientCfg.Bloom) { - Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); - effectRenderTarget = NULL; + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().applyBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); } - bloomStage = 0; + effectRender = false; } // for that frame and @@ -2182,6 +2199,27 @@ bool mainLoop() } } /* stereo pass */ + if (effectRenderTarget) + { + // draw final result to backbuffer + CDriverUser *dru = static_cast(Driver); + + CTextureUser texNull; + dru->setRenderTarget(texNull); + + EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); + + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + Driver->drawQuad(EffectQuad, EffectMaterial); + Driver->setMatrixMode3D(pCam); + + EffectMaterial.getObjectPtr()->setTexture(0, NULL); + + Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); + effectRenderTarget = NULL; + } + // Draw to screen. static CQuat MainCamOri; if (FirstFrame) diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 3f36bca5d..c5b422fc0 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -120,6 +120,7 @@ extern bool userChar; extern bool serverReceivedReady; extern bool CharNameValidArrived; +extern UMaterial EffectMaterial; extern void releaseContextualCursor(); extern void selectTipsOfTheDay (uint tips); @@ -585,6 +586,9 @@ void release() // Delete the driver. if(Driver) { + if (!EffectMaterial.empty()) + Driver->deleteMaterial(EffectMaterial); + // Release the prim PrimFiles.release (*Driver); From d98f1ede47ea4e951a4ef86ad2699fb6e3f9d4f7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 00:57:43 +0200 Subject: [PATCH 049/240] Move default render target handling to CDriverUser --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/driver_user.h | 17 +- code/nel/include/nel/3d/fxaa.h | 82 ++++++++ code/nel/include/nel/3d/u_driver.h | 12 +- code/nel/src/3d/driver_user.cpp | 2 + code/nel/src/3d/driver_user2.cpp | 57 +++++ code/nel/src/3d/fxaa.cpp | 196 ++++++++++++++++++ code/nel/src/3d/fxaa_program.h | 168 +++++++++++++++ code/ryzom/client/src/init_main_loop.cpp | 26 --- code/ryzom/client/src/main_loop.cpp | 54 +---- code/ryzom/client/src/release.cpp | 5 - code/snowballs2/client/src/commands.cpp | 27 ++- .../client/src/snowballs_client.cpp | 66 ++++-- 12 files changed, 605 insertions(+), 107 deletions(-) create mode 100644 code/nel/include/nel/3d/fxaa.h create mode 100644 code/nel/src/3d/fxaa.cpp create mode 100644 code/nel/src/3d/fxaa_program.h diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index 0c323a38b..1d3c0b516 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -109,6 +109,11 @@ protected: CMaterial _MatTextInternal; CMaterial _MatTextStretchInternal; + // Default render target for effect pipeline + CTextureUser *_EffectRenderTarget; + UMaterial _MatRenderTarget; + CMaterial _MatRenderTargetInt; + NLMISC::CQuadUV _RenderTargetQuad; // StaticInit static bool _StaticInit; @@ -242,6 +247,16 @@ public: // @} + /// Get the render target manager + virtual CRenderTargetManager &getRenderTargetManager() { return _RenderTargetManager; } + + /// Set a texture the size of the window as render target + virtual void beginDefaultRenderTarget(); + + /// Draw the render target to the back buffer + virtual void endDefaultRenderTarget(UScene *scene); + + /// \name Components gestion for Interface 2D/3D. // @{ @@ -254,8 +269,6 @@ public: /// get cahce information. virtual std::string getFontManagerCacheInformation() const ; - virtual CRenderTargetManager &getRenderTargetManager() { return _RenderTargetManager; } - /** Create a new texture file, searching in CPath. * \param file filename, local to CPath paths. diff --git a/code/nel/include/nel/3d/fxaa.h b/code/nel/include/nel/3d/fxaa.h new file mode 100644 index 000000000..b4c710b0c --- /dev/null +++ b/code/nel/include/nel/3d/fxaa.h @@ -0,0 +1,82 @@ +/** + * \file fxaa.h + * \brief CFXAA + * \date 2014-08-03 21:41GMT + * \author Jan Boon (Kaetemi) + * CFXAA + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_FXAA_H +#define NL3D_FXAA_H +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CPixelProgram; + +/** + * \brief CFXAA + * \date 2014-08-03 21:41GMT + * \author Jan Boon (Kaetemi) + * CFXAA + */ +class CFXAA +{ +public: + CFXAA(NL3D::UDriver *driver); + virtual ~CFXAA(); + + /// Apply effect to current render target. Render target must be managed by render target manager + virtual void applyEffect(); + +private: + UDriver *m_Driver; + + NL3D::UMaterial m_Mat; + NL3D::CVertexBuffer m_VB; + NLMISC::CQuadUV m_QuadUV; + CPixelProgram *m_PP; + + uint m_Width; + uint m_Height; + +}; /* class CFXAA */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_FXAA_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index b9716e931..247fdff75 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -307,6 +307,16 @@ public: // @} + /// Get the render target manager + virtual CRenderTargetManager &getRenderTargetManager() =0; + + /// Set a texture the size of the window as render target + virtual void beginDefaultRenderTarget() =0; + + /// Draw the render target to the back buffer + virtual void endDefaultRenderTarget(UScene *scene) =0; + + /// \name Components gestion for Interface 2D/3D. // @{ @@ -320,8 +330,6 @@ public: /// get cahce information. virtual std::string getFontManagerCacheInformation() const =0; - virtual CRenderTargetManager &getRenderTargetManager() =0; - /** Create a new texture file, searching in CPath. NB: by default a textureFile created with this * method has a setAllowDegradation() at false. diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 4b9501f45..d366d6d21 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -195,6 +195,8 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu _RenderTargetManager.m_Driver = this; _ShapeBank._DriverUser = this; + _EffectRenderTarget = NULL; + NL_SET_IB_NAME(_PBLine, "CDriverUser::_PBLine"); NL_SET_IB_NAME(_PBTri, "CDriverUser::_PBTri"); } diff --git a/code/nel/src/3d/driver_user2.cpp b/code/nel/src/3d/driver_user2.cpp index 990175dd4..2398db906 100644 --- a/code/nel/src/3d/driver_user2.cpp +++ b/code/nel/src/3d/driver_user2.cpp @@ -73,6 +73,63 @@ void CDriverUser::deleteScene(UScene *scene) _Scenes.erase((CSceneUser*)scene, "deleteScene(): Bad scene ptr"); } +// *************************************************************************** + +void CDriverUser::beginDefaultRenderTarget() +{ + if (_MatRenderTarget.empty()) + { + _MatRenderTarget.attach(&_MatRenderTargetInt); + UMaterial &umat = _MatRenderTarget; + CMaterial &mat = _MatRenderTargetInt; + umat.initUnlit(); + umat.setColor(CRGBA::White); + umat.setBlend(false); + umat.setAlphaTest(false); + mat.setBlendFunc(CMaterial::one, CMaterial::zero); + mat.setZWrite(false); + mat.setZFunc(CMaterial::always); + mat.setDoubleSided(true); + + _RenderTargetQuad.V0 = CVector(0.f, 0.f, 0.5f); + _RenderTargetQuad.V1 = CVector(1.f, 0.f, 0.5f); + _RenderTargetQuad.V2 = CVector(1.f, 1.f, 0.5f); + _RenderTargetQuad.V3 = CVector(0.f, 1.f, 0.5f); + _RenderTargetQuad.Uv0 = CUV(0.f, 0.f); + _RenderTargetQuad.Uv1 = CUV(1.f, 0.f); + _RenderTargetQuad.Uv2 = CUV(1.f, 1.f); + _RenderTargetQuad.Uv3 = CUV(0.f, 1.f); + } + + nlassert(!_EffectRenderTarget); + uint32 winw, winh; + getWindowSize(winw, winh); + _EffectRenderTarget = getRenderTargetManager().getRenderTarget(winw, winh); + setRenderTarget(*_EffectRenderTarget); +} + +// *************************************************************************** + +void CDriverUser::endDefaultRenderTarget(UScene *scene) +{ + nlassert(_EffectRenderTarget); + + CTextureUser texNull; + setRenderTarget(texNull); + + _MatRenderTarget.getObjectPtr()->setTexture(0, _EffectRenderTarget->getITexture()); + + UCamera pCam = scene->getCam(); + setMatrixMode2D11(); + drawQuad(_RenderTargetQuad, _MatRenderTarget); + setMatrixMode3D(pCam); + + _MatRenderTarget.getObjectPtr()->setTexture(0, NULL); + + getRenderTargetManager().recycleRenderTarget(_EffectRenderTarget); + _EffectRenderTarget = NULL; +} + // *************************************************************************** UTextContext *CDriverUser::createTextContext(const std::string fontFileName, const std::string fontExFileName) { diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp new file mode 100644 index 000000000..d8a145fca --- /dev/null +++ b/code/nel/src/3d/fxaa.cpp @@ -0,0 +1,196 @@ +/** + * \file fxaa.cpp + * \brief CFXAA + * \date 2014-08-03 21:41GMT + * \author Jan Boon (Kaetemi) + * CFXAA + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +namespace { + +#include "fxaa_program.h" + +} /* anonymous namespace */ + +CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_Width(~0), m_Height(~0) +{ + nldebug("3D: Create FXAA"); + + CDriverUser *dru = static_cast(driver); + NL3D::IDriver *drv = (dru)->getDriver(); + + if (drv->supportBloomEffect() && drv->supportNonPowerOfTwoTextures()) + { + m_PP = new CPixelProgram(); + // arbfp1 + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::arbfp1; + source->setSourcePtr(a_arbfp1); + m_PP->addSource(source); + } + // ps_2_0 + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::ps_2_0; + source->setSourcePtr(a_ps_2_0); + m_PP->addSource(source); + } + if (!drv->compilePixelProgram(m_PP)) + { + nlwarning("No supported pixel program for FXAA effect"); + + delete m_PP; + m_PP = NULL; + } + } + + if (m_PP) + { + m_Mat = m_Driver->createMaterial(); + m_Mat.initUnlit(); + m_Mat.setColor(CRGBA::White); + m_Mat.setBlend (false); + m_Mat.setAlphaTest (false); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::Normal); + mat->setBlendFunc(CMaterial::one, CMaterial::zero); + mat->setZWrite(false); + mat->setZFunc(CMaterial::always); + mat->setDoubleSided(true); + + m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); + m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); + m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); + m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); + + m_QuadUV.Uv0 = CUV(0.f, 0.f); + m_QuadUV.Uv1 = CUV(1.f, 0.f); + m_QuadUV.Uv2 = CUV(1.f, 1.f); + m_QuadUV.Uv3 = CUV(0.f, 1.f); + + CVertexBuffer &vb = m_VB; + vb.clearValueEx(); + vb.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3); + vb.addValueEx(CVertexBuffer::TexCoord0, CVertexBuffer::Float2); + vb.addValueEx(CVertexBuffer::TexCoord1, CVertexBuffer::Float4); + vb.initEx(); + vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false); + vb.setNumVertices(4); + /*CVertexBufferReadWrite vba; + vb.lock(vba); + vba.setVertexCoord(0, 0.f, 0.f, 0.5f); + vba.setVertexCoord(1, 1.f, 0.f, 0.5f); + vba.setVertexCoord(2, 1.f, 1.f, 0.5f); + vba.setVertexCoord(3, 0.f, 1.f, 0.5f); + vba.setTexCoord(0, 0, 0.f, 0.f); + vba.setTexCoord(1, 0, 1.f, 0.f); + vba.setTexCoord(2, 0, 1.f, 1.f); + vba.setTexCoord(3, 0, 0.f, 1.f);*/ + /*vba.setTexCoord(0, 1, 0.f, 0.f); + vba.setTexCoord(1, 1, 1.f, 0.f); + vba.setTexCoord(2, 1, 1.f, 1.f); + vba.setTexCoord(3, 1, 0.f, 1.f);*/ + } +} + +CFXAA::~CFXAA() +{ + nldebug("3D: Destroy FXAA"); + + if (!m_Mat.empty()) + { + m_Driver->deleteMaterial(m_Mat); + } + + delete m_PP; + m_PP = NULL; + + m_Driver = NULL; +} + +void CFXAA::applyEffect() +{ + if (!m_PP) + return; + + CDriverUser *dru = static_cast(m_Driver); + IDriver *drv = dru->getDriver(); + + NL3D::ITexture *renderTarget = drv->getRenderTarget(); + nlassert(renderTarget); + nlassert(renderTarget->isBloomTexture()); + + uint width = renderTarget->getWidth(); + uint height = renderTarget->getHeight(); + bool mode2D = static_cast(renderTarget)->isMode2D(); + nlassert(renderTarget->getUploadFormat() == ITexture::Auto); + + float fwidth = (float)width; + float fheight = (float)height; + + // create render target + CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D); + + // swap render target + CTextureUser texNull; + dru->setRenderTarget(texNull); + drv->swapTextureHandle(*renderTarget, *otherRenderTarget->getITexture()); + drv->setRenderTarget(renderTarget); + + // render effect + m_Mat.getObjectPtr()->setTexture(0, otherRenderTarget->getITexture()); + m_Driver->drawQuad(m_QuadUV, m_Mat); + m_Mat.getObjectPtr()->setTexture(0, NULL); + + // recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(otherRenderTarget); +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/fxaa_program.h b/code/nel/src/3d/fxaa_program.h new file mode 100644 index 000000000..5a7f4a709 --- /dev/null +++ b/code/nel/src/3d/fxaa_program.h @@ -0,0 +1,168 @@ + +const char *a_arbfp1 = + "!!ARBfp1.0\n" + //"# cgc version 3.1.0013, build date Apr 18 2012\n" + //"# command line args: -profile arbfp1\n" + //"# source file: fxaa_fp.cg\n" + //"#vendor NVIDIA Corporation\n" + //"#version 3.1.0.13\n" + //"#profile arbfp1\n" + //"#program fxaa_fp\n" + //"#semantic fxaa_fp.fxaaConsoleRcpFrameOpt\n" + //"#semantic fxaa_fp.fxaaConsoleRcpFrameOpt2\n" + //"#semantic fxaa_fp.nlTex0 : TEX0\n" + //"#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n" + //"#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1\n" + //"#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1\n" + //"#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1\n" + //"#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1\n" + //"#var float4 oCol : $vout.COLOR : COL : 5 : 1\n" + //"#const c[2] = 0.125 0 8 0.001953125\n" + //"#const c[3] = -2 2 0.5\n" + "PARAM c[4] = { program.env[0..1],\n" + " { 0.125, 0, 8, 0.001953125 },\n" + " { -2, 2, 0.5 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "TEMP R2;\n" + "TEMP R3;\n" + "TEMP R4;\n" + "TEMP R5;\n" + "TEX R0.w, fragment.texcoord[1].zyzw, texture[0], 2D;\n" + "ADD R0.x, R0.w, c[2].w;\n" + "TEX R1.w, fragment.texcoord[1].xwzw, texture[0], 2D;\n" + "TEX R0.w, fragment.texcoord[1], texture[0], 2D;\n" + "ADD R0.y, R1.w, -R0.x;\n" + "ADD R0.z, R0.w, R0.y;\n" + "TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D;\n" + "ADD R0.y, -R0.w, R0;\n" + "ADD R1.z, -R2.w, R0;\n" + "ADD R1.x, R2.w, R0.y;\n" + "MOV R1.y, c[2];\n" + "DP3 R0.y, R1, R1;\n" + "RSQ R0.y, R0.y;\n" + "MUL R2.xy, R0.y, R1.xzzw;\n" + "MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0];\n" + "ABS R0.z, R2.y;\n" + "ABS R0.y, R2.x;\n" + "MIN R0.y, R0, R0.z;\n" + "RCP R0.y, R0.y;\n" + "MUL R1.xy, R0.y, R2;\n" + "MUL R1.xy, R1, c[2].x;\n" + "MIN R1.xy, R1, c[3].y;\n" + "MIN R0.y, R0.w, R1.w;\n" + "TEX R4, R3, texture[0], 2D;\n" + "MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0];\n" + "TEX R3, R2, texture[0], 2D;\n" + "ADD R3, R3, R4;\n" + "MAX R1.xy, R1, c[3].x;\n" + "MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0];\n" + "MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0];\n" + "MUL R5, R3, c[3].z;\n" + "TEX R4, R2, texture[0], 2D;\n" + "TEX R3, R1, texture[0], 2D;\n" + "MIN R0.z, R0.x, R2.w;\n" + "MIN R1.x, R0.y, R0.z;\n" + "MAX R0.y, R0.x, R2.w;\n" + "MAX R0.x, R0.w, R1.w;\n" + "MAX R2.x, R0, R0.y;\n" + "ADD R3, R3, R4;\n" + "MAD R3, R3, c[3].z, R5;\n" + "MUL R3, R3, c[3].z;\n" + "SLT R1.z, R2.x, R3.w;\n" + "SLT R1.y, R3.w, R1.x;\n" + "TEX R0, fragment.texcoord[0], texture[0], 2D;\n" + "ADD_SAT R1.y, R1, R1.z;\n" + "MIN R1.z, R0.w, R1.x;\n" + "MAX R1.x, R2, R0.w;\n" + "ADD R2.y, R1.x, -R1.z;\n" + "CMP R1, -R1.y, R5, R3;\n" + "MAD R2.x, R2.y, c[2].z, -R2;\n" + "CMP result.color, R2.x, R0, R1;\n" + "END\n"; + //"# 51 instructions, 6 R-regs\n" + +const char *a_ps_2_0 = + "ps_2_x\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_x + // source file: fxaa_fp.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_x + //program fxaa_fp + //semantic fxaa_fp.fxaaConsoleRcpFrameOpt + //semantic fxaa_fp.fxaaConsoleRcpFrameOpt2 + //semantic fxaa_fp.nlTex0 : TEX0 + //var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 + //var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 + //var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 + //var float4 oCol : $vout.COLOR : COL : 5 : 1 + //const c[2] = 0.001953125 0 0.125 2 + //const c[3] = -2 0.5 0 1 + //const c[4] = 8 + "dcl_2d s0\n" + "def c2, 0.00195313, 0.00000000, 0.12500000, 2.00000000\n" + "def c3, -2.00000000, 0.50000000, 0.00000000, 1.00000000\n" + "def c4, 8.00000000, 0, 0, 0\n" + "dcl t1\n" + "dcl t0.xy\n" + "mov r0.xy, t1.zyzw\n" + "texld r0, r0, s0\n" + "mov r0.xy, t1.xwzw\n" + "texld r5, t1, s0\n" + "texld r4, r0, s0\n" + "add r4.x, r0.w, c2\n" + "mov r0.xy, t1.zwzw\n" + "texld r3, r0, s0\n" + "add r0.w, r4, -r4.x\n" + "add r0.x, r5.w, r0.w\n" + "add r0.z, -r3.w, r0.x\n" + "add r0.x, -r5.w, r0.w\n" + "add r0.x, r3.w, r0\n" + "mov r0.y, c2\n" + "dp3 r0.y, r0, r0\n" + "rsq r0.y, r0.y\n" + "mul r0.zw, r0.y, r0.xyxz\n" + "mad r1.xy, -r0.zwzw, c0.zwzw, t0\n" + "texld r1, r1, s0\n" + "abs r0.y, r0.w\n" + "abs r0.x, r0.z\n" + "min r0.x, r0, r0.y\n" + "rcp r0.x, r0.x\n" + "mul r0.xy, r0.x, r0.zwzw\n" + "mul r0.xy, r0, c2.z\n" + "min r2.xy, r0, c2.w\n" + "mad r0.xy, r0.zwzw, c0.zwzw, t0\n" + "texld r0, r0, s0\n" + "add r0, r1, r0\n" + "max r1.xy, r2, c3.x\n" + "mul r2, r0, c3.y\n" + "mad r0.xy, r1, c1.zwzw, t0\n" + "mad r1.xy, -r1, c1.zwzw, t0\n" + "texld r0, r0, s0\n" + "texld r1, r1, s0\n" + "add r0, r1, r0\n" + "mad r0, r0, c3.y, r2\n" + "mul r1, r0, c3.y\n" + "min r0.y, r4.x, r3.w\n" + "min r0.x, r5.w, r4.w\n" + "min r3.y, r0.x, r0\n" + "add r0.x, -r3.y, r1.w\n" + "max r0.z, r4.x, r3.w\n" + "max r0.y, r5.w, r4.w\n" + "max r3.x, r0.y, r0.z\n" + "cmp r3.z, r0.x, c3, c3.w\n" + "add r3.w, r3.x, -r1\n" + "cmp r3.w, r3, c3.z, c3\n" + "add_pp_sat r3.z, r3, r3.w\n" + "texld r0, t0, s0\n" + "min r3.w, r0, r3.y\n" + "max r3.y, r3.x, r0.w\n" + "cmp r1, -r3.z, r1, r2\n" + "add r3.y, r3, -r3.w\n" + "mad r2.x, r3.y, c4, -r3\n" + "cmp r0, r2.x, r1, r0\n" + "mov oC0, r0\n"; diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index a2db91b4f..3f1f25f4c 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -137,9 +137,6 @@ std::string LoadingBitmapFilename; uint64 StartInitTime = 0; uint64 StartPlayTime = 0; -UMaterial EffectMaterial; -NLMISC::CQuadUV EffectQuad; - // texture for the logos std::vector LogoBitmaps; @@ -572,29 +569,6 @@ void initMainLoop() // use this scene for bloom effect CBloomEffect::getInstance().setScene(Scene); - if (EffectMaterial.empty()) - { - EffectMaterial = Driver->createMaterial(); - CMaterial *mat = EffectMaterial.getObjectPtr(); - EffectMaterial.initUnlit(); - EffectMaterial.setColor(CRGBA::White); - EffectMaterial.setBlend(false); - EffectMaterial.setAlphaTest (false); - mat->setBlendFunc(CMaterial::one, CMaterial::zero); - mat->setZWrite(false); - mat->setZFunc(CMaterial::always); - mat->setDoubleSided(true); - } - - EffectQuad.V0 = CVector(0.f, 0.f, 0.5f); - EffectQuad.V1 = CVector(1.f, 0.f, 0.5f); - EffectQuad.V2 = CVector(1.f, 1.f, 0.5f); - EffectQuad.V3 = CVector(0.f, 1.f, 0.5f); - EffectQuad.Uv0 = CUV(0.f, 0.f); - EffectQuad.Uv1 = CUV(1.f, 0.f); - EffectQuad.Uv2 = CUV(1.f, 1.f); - EffectQuad.Uv3 = CUV(0.f, 1.f); - CLandscapePolyDrawer::getInstance().initLandscapePolyDrawingCallback(); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 1a67866ec..4dfb2870a 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -185,9 +185,6 @@ extern std::vector LogoBitmaps; extern bool IsInRingSession; extern std::string UsedFSAddr; -extern UMaterial EffectMaterial; -extern NLMISC::CQuadUV EffectQuad; - // temp extern NLMISC::CValueSmoother smoothFPS; extern NLMISC::CValueSmoother moreSmoothFPS; @@ -574,10 +571,7 @@ void renderScene(bool forceFullDetail, bool bloom) CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); // init effect render target - uint32 winw, winh; - Driver->getWindowSize(winw, winh); - effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); - static_cast(Driver)->setRenderTarget(*effectRenderTarget); + Driver->beginDefaultRenderTarget(); } if (forceFullDetail) { @@ -596,22 +590,7 @@ void renderScene(bool forceFullDetail, bool bloom) CBloomEffect::getInstance().applyBloom(); // draw final result to backbuffer - CDriverUser *dru = static_cast(Driver); - - CTextureUser texNull; - dru->setRenderTarget(texNull); - - EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); - - UCamera pCam = Scene->getCam(); - Driver->setMatrixMode2D11(); - Driver->drawQuad(EffectQuad, EffectMaterial); - Driver->setMatrixMode3D(pCam); - - EffectMaterial.getObjectPtr()->setTexture(0, NULL); - - Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); - effectRenderTarget = NULL; + Driver->endDefaultRenderTarget(Scene); } } @@ -1650,15 +1629,15 @@ bool mainLoop() uint i = 0; bool effectRender = false; CTextureUser *effectRenderTarget = NULL; - bool haveEffects = Render && ClientCfg.Bloom; + bool haveEffects = Render && Driver->getPolygonMode() == UDriver::Filled + && ClientCfg.Bloom; + bool defaultRenderTarget = false; if (haveEffects) { if (!StereoDisplay) { - uint32 winw, winh; - Driver->getWindowSize(winw, winh); - effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); - static_cast(Driver)->setRenderTarget(*effectRenderTarget); + Driver->beginDefaultRenderTarget(); + defaultRenderTarget = true; } if (ClientCfg.Bloom) { @@ -2199,25 +2178,10 @@ bool mainLoop() } } /* stereo pass */ - if (effectRenderTarget) + if (defaultRenderTarget) { // draw final result to backbuffer - CDriverUser *dru = static_cast(Driver); - - CTextureUser texNull; - dru->setRenderTarget(texNull); - - EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); - - UCamera pCam = Scene->getCam(); - Driver->setMatrixMode2D11(); - Driver->drawQuad(EffectQuad, EffectMaterial); - Driver->setMatrixMode3D(pCam); - - EffectMaterial.getObjectPtr()->setTexture(0, NULL); - - Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); - effectRenderTarget = NULL; + Driver->endDefaultRenderTarget(Scene); } // Draw to screen. diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index c5b422fc0..3659d034d 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -120,8 +120,6 @@ extern bool userChar; extern bool serverReceivedReady; extern bool CharNameValidArrived; -extern UMaterial EffectMaterial; - extern void releaseContextualCursor(); extern void selectTipsOfTheDay (uint tips); @@ -586,9 +584,6 @@ void release() // Delete the driver. if(Driver) { - if (!EffectMaterial.empty()) - Driver->deleteMaterial(EffectMaterial); - // Release the prim PrimFiles.release (*Driver); diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 41faeab1e..f04748d3d 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -296,7 +296,7 @@ void initCommands() CommandsMaterial.setBlend(true); #if SBCLIENT_DEV_PIXEL_PROGRAM - CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); + CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::Program); a_NelLogo = Driver->createTextureFile("nel128.tga"); CommandsMaterial.setTexture(dynamic_cast(a_NelLogo)); static const char *program_arbfp1 = @@ -340,7 +340,24 @@ void initCommands() "mov oC0.xzw, c0.xyyx\n" "texld oC0.y, v0, s0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); - if (d->supportPixelProgram(CPixelProgram::fp40)) + a_DevPixelProgram = new CPixelProgram(); + // arbfp1 + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::arbfp1; + source->setSourcePtr(program_arbfp1); + a_DevPixelProgram->addSource(source); + } + // ps_2_0 + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::ps_2_0; + source->setSourcePtr(program_ps_2_0); + a_DevPixelProgram->addSource(source); + } + /*if (d->supportPixelProgram(CPixelProgram::fp40)) { nldebug("fp40"); a_DevPixelProgram = new CPixelProgram(program_fp40); @@ -349,14 +366,14 @@ void initCommands() { nldebug("arbfp1"); a_DevPixelProgram = new CPixelProgram(program_arbfp1); - } + }*/ /*else if (d->supportPixelProgram(CPixelProgram::ps_3_0)) { nldebug("ps_3_0"); a_DevPixelProgram = new CPixelProgram(program_ps_3_0); // Textures do not seem to work with ps_3_0... }*/ - else if (d->supportPixelProgram(CPixelProgram::ps_2_0)) + /*else if (d->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("ps_2_0"); a_DevPixelProgram = new CPixelProgram(program_ps_2_0); @@ -365,7 +382,7 @@ void initCommands() { nldebug("ps_1_1"); a_DevPixelProgram = new CPixelProgram(program_ps_1_1); - } + }*/ #endif } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index dc8239c8c..2d53bf65e 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #if SBCLIENT_DEV_STEREO # include #endif /* #if SBCLIENT_DEV_STEREO */ @@ -153,6 +154,7 @@ static IStereoRender *_StereoRender = NULL; #endif /* #if SBCLIENT_DEV_STEREO */ static bool s_EnableBloom = false; +static CFXAA *s_FXAA = NULL; // // Prototypes @@ -185,6 +187,7 @@ void cbGraphicsDriver(CConfigFile::CVar &var); void cbSquareBloom(CConfigFile::CVar &var); void cbDensityBloom(CConfigFile::CVar &var); void cbEnableBloom(CConfigFile::CVar &var); +void cbEnableFXAA(CConfigFile::CVar &var); // // Functions @@ -377,6 +380,7 @@ void initIngame() CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); CConfiguration::setAndCallback("EnableBloom", cbEnableBloom); + CConfiguration::setAndCallback("EnableFXAA", cbEnableFXAA); // Init the landscape using the previously created UScene displayLoadingState("Initialize Landscape"); initLandscape(); @@ -740,7 +744,19 @@ void loopIngame() else { uint i = 0; - uint bloomStage = 0; + bool effectRender = false; + CTextureUser *effectRenderTarget = NULL; + bool haveEffects = Driver->getPolygonMode() == UDriver::Filled + && (s_EnableBloom || s_FXAA); + bool defaultRenderTarget = false; + if (haveEffects) + { + if (!StereoDisplay) + { + Driver->beginDefaultRenderTarget(); + defaultRenderTarget = true; + } + } while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; @@ -762,13 +778,7 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantClear()) { - - /*if (s_EnableBloom) - { - nlassert(bloomStage == 0); - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) - bloomStage = 1; - }*/ + effectRender = haveEffects; // 01. Render Driver (background color) Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering @@ -788,14 +798,14 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantInterface3D()) { - /*if (s_EnableBloom && bloomStage == 1) + if (effectRender) { - // End the actual bloom effect visible in the scene. if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().endBloom(); + if (s_EnableBloom) CBloomEffect::instance().applyBloom(); + if (s_FXAA) s_FXAA->applyEffect(); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - bloomStage = 2; - }*/ + effectRender = false; + } // 06. Render Interface 3D (player names) // ... @@ -803,15 +813,6 @@ void loopIngame() if (!StereoDisplay || StereoDisplay->wantInterface2D()) { - /*if (s_EnableBloom && bloomStage == 2) - { - // End bloom effect system after drawing the 3d interface (z buffer related). - if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().endInterfacesDisplayBloom(); - if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - bloomStage = 0; - }*/ - // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) updateCompass(); // Update the compass updateRadar(); // Update the radar @@ -833,6 +834,11 @@ void loopIngame() } // 09. Render Buffer + if (defaultRenderTarget) + { + // draw final result to backbuffer + Driver->endDefaultRenderTarget(Scene); + } Driver->swapBuffers(); } @@ -965,6 +971,22 @@ void cbEnableBloom(CConfigFile::CVar &var) s_EnableBloom = var.asBool(); } +void cbEnableFXAA(CConfigFile::CVar &var) +{ + bool enable = var.asBool(); + if (enable != (s_FXAA != NULL)) + { + if (enable) + { + s_FXAA = new CFXAA(Driver); + } + else + { + delete s_FXAA; + } + } +} + // // Loading state procedure // From f59de199cfe66daee1985158eced601278dffd53 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 01:05:53 +0200 Subject: [PATCH 050/240] Fix crash on AMD with legacy clouds --HG-- branch : multipass-stereo --- code/nel/src/3d/driver/opengl/driver_opengl_material.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp index ed43fe8c3..986dd6303 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp @@ -2087,14 +2087,16 @@ void CDriverGL::setupCloudPass (uint /* pass */) glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA); activateTexEnvColor (1, mat.getColor()); } - else + else if (ATICloudShaderHandle) { // TODO : for now the state is not cached in _CurrentTexEnvSpecial nglBindFragmentShaderATI(ATICloudShaderHandle); glEnable(GL_FRAGMENT_SHADER_ATI); float cst[4] = { 0.f, 0.f, 0.f, mat.getColor().A / 255.f }; nglSetFragmentShaderConstantATI(GL_CON_0_ATI, cst); - /* + } + else + { _DriverGLStates.activeTextureARB(0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); // Operator. @@ -2130,7 +2132,6 @@ void CDriverGL::setupCloudPass (uint /* pass */) glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_CONSTANT_EXT ); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); - */ } #endif } From ec4762f669538b4c8ace44d2640208dc96194c5c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 04:44:27 +0200 Subject: [PATCH 051/240] 3D: Add FXAA --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/fxaa.h | 4 +- code/nel/src/3d/bloom_effect.cpp | 7 +- code/nel/src/3d/fxaa.cpp | 114 +- code/nel/src/3d/fxaa_program.h | 215 ++ code/nel/src/3d/shaders/compile.bat | 3 + code/nel/src/3d/shaders/fxaa3_11.h | 2042 +++++++++++++++++ code/nel/src/3d/shaders/fxaa_pp.cg | 70 + code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt | 76 + code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt | 92 + code/nel/src/3d/shaders/fxaa_vp.cg | 20 + code/nel/src/3d/shaders/fxaa_vp_arbvp1.txt | 31 + code/nel/src/3d/shaders/readme.txt | 4 + code/ryzom/client/src/main_loop.cpp | 12 +- .../client/src/snowballs_client.cpp | 5 +- 14 files changed, 2661 insertions(+), 34 deletions(-) create mode 100644 code/nel/src/3d/shaders/compile.bat create mode 100644 code/nel/src/3d/shaders/fxaa3_11.h create mode 100644 code/nel/src/3d/shaders/fxaa_pp.cg create mode 100644 code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt create mode 100644 code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt create mode 100644 code/nel/src/3d/shaders/fxaa_vp.cg create mode 100644 code/nel/src/3d/shaders/fxaa_vp_arbvp1.txt create mode 100644 code/nel/src/3d/shaders/readme.txt diff --git a/code/nel/include/nel/3d/fxaa.h b/code/nel/include/nel/3d/fxaa.h index b4c710b0c..f7ccf4866 100644 --- a/code/nel/include/nel/3d/fxaa.h +++ b/code/nel/include/nel/3d/fxaa.h @@ -46,6 +46,7 @@ namespace NL3D { class ITexture; class CTextureUser; class CPixelProgram; +class CVertexProgram; /** * \brief CFXAA @@ -66,8 +67,9 @@ private: UDriver *m_Driver; NL3D::UMaterial m_Mat; - NL3D::CVertexBuffer m_VB; + // NL3D::CVertexBuffer m_VB; NLMISC::CQuadUV m_QuadUV; + CVertexProgram *m_VP; CPixelProgram *m_PP; uint m_Width; diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 842423661..fe82e43c6 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -264,6 +264,7 @@ void CBloomEffect::applyBloom() CRect rect1(0, 0, width, height); CRect rect2(0, 0, _BlurWidth, _BlurHeight); dru->stretchRect(_Scene, txt1, rect1, txt2, rect2); + _Driver->setMatrixMode2D11(); // horizontal blur pass doBlur(true); @@ -319,10 +320,7 @@ void CBloomEffect::applyBlur() matObjectFinal->texConstantColor(0, constCoeff); // display quad - UCamera pCam = _Scene->getCam(); - _Driver->setMatrixMode2D11(); _Driver->drawQuad(_BlurQuad, displayBlurMat); - _Driver->setMatrixMode3D(pCam); // disable vertex program drvInternal->activeVertexProgram(NULL); @@ -404,15 +402,12 @@ void CBloomEffect::doBlur(bool horizontalBlur) matObject->setTexture(3, startTexture); // display - UCamera pCam = _Scene->getCam(); - _Driver->setMatrixMode2D11(); _Driver->drawQuad(_BlurQuad, _BlurMat); // disable render target and vertex program drvInternal->activeVertexProgram(NULL); CTextureUser cu; ((CDriverUser *)_Driver)->setRenderTarget(cu, 0, 0, 0, 0); - _Driver->setMatrixMode3D(pCam); } }; // NL3D diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index d8a145fca..c1eb57607 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -54,7 +54,7 @@ namespace { } /* anonymous namespace */ -CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_Width(~0), m_Height(~0) +CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_Width(~0), m_Height(~0) { nldebug("3D: Create FXAA"); @@ -82,14 +82,54 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_Width(~0), } if (!drv->compilePixelProgram(m_PP)) { - nlwarning("No supported pixel program for FXAA effect"); + nlwarning("3D: No supported pixel program for FXAA effect"); delete m_PP; m_PP = NULL; } + else + { + nldebug("3D: FXAA pixel program available"); + } + } + + if (!m_PP) + { + return; } - if (m_PP) + // create vp + { + m_VP = new CVertexProgram(); + // nelvp + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::nelvp; + source->setSourcePtr(a_nelvp); + m_VP->addSource(source); + } + if (!drv->compileVertexProgram(m_VP)) + { + nlwarning("3D: No supported vertex program for FXAA effect"); + + delete m_VP; + m_VP = NULL; + delete m_PP; + m_PP = NULL; + } + else + { + nldebug("3D: FXAA vertex program available"); + } + } + + if (!m_VP) + { + return; + } + + // create material and vb { m_Mat = m_Driver->createMaterial(); m_Mat.initUnlit(); @@ -113,28 +153,14 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_Width(~0), m_QuadUV.Uv2 = CUV(1.f, 1.f); m_QuadUV.Uv3 = CUV(0.f, 1.f); - CVertexBuffer &vb = m_VB; + /*CVertexBuffer &vb = m_VB; vb.clearValueEx(); vb.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3); vb.addValueEx(CVertexBuffer::TexCoord0, CVertexBuffer::Float2); vb.addValueEx(CVertexBuffer::TexCoord1, CVertexBuffer::Float4); vb.initEx(); - vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false); - vb.setNumVertices(4); - /*CVertexBufferReadWrite vba; - vb.lock(vba); - vba.setVertexCoord(0, 0.f, 0.f, 0.5f); - vba.setVertexCoord(1, 1.f, 0.f, 0.5f); - vba.setVertexCoord(2, 1.f, 1.f, 0.5f); - vba.setVertexCoord(3, 0.f, 1.f, 0.5f); - vba.setTexCoord(0, 0, 0.f, 0.f); - vba.setTexCoord(1, 0, 1.f, 0.f); - vba.setTexCoord(2, 0, 1.f, 1.f); - vba.setTexCoord(3, 0, 0.f, 1.f);*/ - /*vba.setTexCoord(0, 1, 0.f, 0.f); - vba.setTexCoord(1, 1, 1.f, 0.f); - vba.setTexCoord(2, 1, 1.f, 1.f); - vba.setTexCoord(3, 1, 0.f, 1.f);*/ + vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false); + vb.setNumVertices(4);*/ } } @@ -147,6 +173,8 @@ CFXAA::~CFXAA() m_Driver->deleteMaterial(m_Mat); } + delete m_VP; + m_VP = NULL; delete m_PP; m_PP = NULL; @@ -172,6 +200,33 @@ void CFXAA::applyEffect() float fwidth = (float)width; float fheight = (float)height; + nldebug("%f, %f", fwidth, fheight); + float pwidth = 1.0f / fwidth; + float pheight = 1.0f / fheight; + float hpwidth = pwidth * 0.5f; + float hpheight = pheight * 0.5f; + float n = 0.5f; + + //if (width != m_Width || height != m_Height) + /*{ + // Build VB + m_Width = width; + m_Height = height; + CVertexBufferReadWrite vba; + m_VB.lock(vba); + vba.setValueFloat3Ex(CVertexBuffer::Position, 0, 0.f, 0.f, 0.5f); // BL + vba.setValueFloat3Ex(CVertexBuffer::Position, 1, 1.f, 0.f, 0.5f); // BR + vba.setValueFloat3Ex(CVertexBuffer::Position, 2, 1.f, 1.f, 0.5f); // TR + vba.setValueFloat3Ex(CVertexBuffer::Position, 3, 0.f, 1.f, 0.5f); // TL + vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 0, 0.f, 0.f); + vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 1, 1.f, 0.f); + vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 2, 1.f, 1.f); + vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 3, 0.f, 1.f); + vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 0, 0.f - hpwidth, 0.f - hpheight, 0.f + hpwidth, 0.f + hpheight); + vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 1, 1.f - hpwidth, 0.f - hpheight, 1.f + hpwidth, 0.f + hpheight); + vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 2, 1.f - hpwidth, 1.f - hpheight, 1.f + hpwidth, 1.f + hpheight); + vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 3, 0.f - hpwidth, 1.f - hpheight, 0.f + hpwidth, 1.f + hpheight); + }*/ // create render target CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D); @@ -182,11 +237,30 @@ void CFXAA::applyEffect() drv->swapTextureHandle(*renderTarget, *otherRenderTarget->getITexture()); drv->setRenderTarget(renderTarget); + // debug + m_Driver->clearBuffers(CRGBA(128, 128, 128, 128)); + + // activate program + bool vpok = drv->activeVertexProgram(m_VP); + nlassert(vpok); + bool ppok = drv->activePixelProgram(m_PP); + nlassert(ppok); + drv->setUniform4f(IDriver::PixelProgram, 0, -n / fwidth, -n / fheight, n / fwidth, n / fheight); // fxaaConsoleRcpFrameOpt + drv->setUniform4f(IDriver::PixelProgram, 1, -2.0f / fwidth, -2.0f / fheight, 2.0f / fwidth, 2.0f / fheight); // fxaaConsoleRcpFrameOpt2 + drv->setUniformMatrix(IDriver::VertexProgram, 0, IDriver::ModelViewProjection, IDriver::Identity); + drv->setUniform4f(IDriver::VertexProgram, 9, -hpwidth, -hpheight, hpwidth, hpheight); + // render effect m_Mat.getObjectPtr()->setTexture(0, otherRenderTarget->getITexture()); + /*drv->activeVertexBuffer(m_VB); + drv->renderRawQuads(*m_Mat.getObjectPtr(), 0, 1);*/ m_Driver->drawQuad(m_QuadUV, m_Mat); m_Mat.getObjectPtr()->setTexture(0, NULL); + // deactivate program + drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); + // recycle render target m_Driver->getRenderTargetManager().recycleRenderTarget(otherRenderTarget); } diff --git a/code/nel/src/3d/fxaa_program.h b/code/nel/src/3d/fxaa_program.h index 5a7f4a709..6002a09a4 100644 --- a/code/nel/src/3d/fxaa_program.h +++ b/code/nel/src/3d/fxaa_program.h @@ -1,6 +1,101 @@ +const char *a_nelvp = + "!!VP1.0\n" + "DP4 o[HPOS].x, c[0], v[OPOS];\n" + "DP4 o[HPOS].y, c[1], v[OPOS];\n" + "DP4 o[HPOS].z, c[2], v[OPOS];\n" + "DP4 o[HPOS].w, c[3], v[OPOS];\n" + "MOV o[TEX0].xy, v[TEX0];\n" + "ADD o[TEX1], v[TEX0].xyxy, c[9];\n" + "END\n"; + +const char *a_arbfp1_test = + "!!ARBfp1.0\n" + "OPTION ARB_precision_hint_fastest;\n" + "TEX result.color, fragment.texcoord[1].zwzw, texture[0], 2D;\n" + "END\n"; + const char *a_arbfp1 = "!!ARBfp1.0\n" + "OPTION ARB_precision_hint_fastest;\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile arbfp1 -O3 -fastmath -fastprecision + //# source file: fxaa_fp.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile arbfp1 + //#program fxaa_fp + //#semantic fxaa_fp.fxaaConsoleRcpFrameOpt + //#semantic fxaa_fp.fxaaConsoleRcpFrameOpt2 + //#semantic fxaa_fp.nlTex0 : TEX0 + //#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 + //#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 + //#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 + //#var float4 oCol : $vout.COLOR : COL : 5 : 1 + //#const c[2] = 0.125 0 -2 2 + //#const c[3] = 0.001953125 0.5 + "PARAM c[4] = { program.env[0..1],\n" + " { 0.125, 0, -2, 2 },\n" + " { 0.001953125, 0.5 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "TEMP R2;\n" + "TEMP R3;\n" + "TEMP R4;\n" + "TEMP R5;\n" + "TEX R1.w, fragment.texcoord[1].zyzw, texture[0], 2D;\n" + "ADD R0.x, R1.w, c[3];\n" + "TEX R0.w, fragment.texcoord[1].xwzw, texture[0], 2D;\n" + "TEX R1.w, fragment.texcoord[1], texture[0], 2D;\n" + "ADD R0.y, -R0.x, R0.w;\n" + "ADD R0.z, R1.w, R0.y;\n" + "TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D;\n" + "ADD R0.y, -R1.w, R0;\n" + "ADD R1.x, R2.w, R0.y;\n" + "ADD R1.y, R0.z, -R2.w;\n" + "MUL R2.xy, R1, R1;\n" + "ADD R0.y, R2.x, R2;\n" + "RSQ R0.y, R0.y;\n" + "MUL R2.xy, R0.y, R1;\n" + "MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0];\n" + "ABS R0.z, R2.y;\n" + "ABS R0.y, R2.x;\n" + "MIN R0.y, R0, R0.z;\n" + "RCP R0.y, R0.y;\n" + "MUL R1.xy, R0.y, R2;\n" + "MUL R1.xy, R1, c[2].x;\n" + "MIN R1.xy, R1, c[2].w;\n" + "TEX R4, R3, texture[0], 2D;\n" + "MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0];\n" + "TEX R3, R2, texture[0], 2D;\n" + "ADD R3, R3, R4;\n" + "MAX R1.xy, R1, c[2].z;\n" + "MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0];\n" + "MUL R5, R3, c[3].y;\n" + "MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0];\n" + "MIN R0.z, R0.x, R2.w;\n" + "MIN R0.y, R0.w, R1.w;\n" + "MIN R0.y, R0, R0.z;\n" + "MAX R0.z, R0.x, R2.w;\n" + "MAX R0.x, R0.w, R1.w;\n" + "MAX R0.x, R0, R0.z;\n" + "TEX R4, R2, texture[0], 2D;\n" + "TEX R3, R1, texture[0], 2D;\n" + "ADD R3, R3, R4;\n" + "MAD R3, R3, c[3].y, R5;\n" + "MUL R3, R3, c[3].y;\n" + "SLT R0.z, R0.x, R3.w;\n" + "SLT R0.x, R3.w, R0.y;\n" + "ADD_SAT R0.x, R0, R0.z;\n" + "CMP result.color, -R0.x, R5, R3;\n" + "END\n"; + //# 45 instructions, 6 R-regs + +const char *a_arbfp1_earlyexit = + "!!ARBfp1.0\n" + "OPTION ARB_precision_hint_fastest;\n" //"# cgc version 3.1.0013, build date Apr 18 2012\n" //"# command line args: -profile arbfp1\n" //"# source file: fxaa_fp.cg\n" @@ -82,7 +177,127 @@ const char *a_arbfp1 = "END\n"; //"# 51 instructions, 6 R-regs\n" +const char *a_ps_2_0_test_t0 = + "ps_2_x\n" + "dcl_2d s0\n" + "dcl t0.xyz\n" + "mov r0.xy, t0.xy\n" + "texld r0, r0, s0\n" + "mov oC0, r0\n"; + +const char *a_ps_2_0_test_avg = + "ps_2_x\n" + "dcl_2d s0\n" + "def c0, 0.25000000, 0, 0, 0\n" + "dcl t1\n" + "mov r0.xy, t1.xwzw\n" + "mov r1.xy, t1.zyzw\n" + "texld r0, r0, s0\n" + "texld r1, r1, s0\n" + "add r2, r1, r0\n" + "mov r0.xy, t1.zwzw\n" + "texld r1, t1, s0\n" + "texld r0, r0, s0\n" + "add r1, r2, r1\n" + "add r0, r1, r0\n" + "mul r0, r0, c0.x\n" + "mov oC0, r0\n"; + const char *a_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 -O3 -fastmath -fastprecision + // source file: fxaa_pp.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program fxaa_pp + //semantic fxaa_pp.fxaaConsoleRcpFrameOpt + //semantic fxaa_pp.fxaaConsoleRcpFrameOpt2 + //semantic fxaa_pp.nlTex0 : TEX0 + //var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 + //var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 + //var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 + //var float4 oCol : $vout.COLOR : COL : 5 : 1 + //const c[2] = 0.001953125 0.125 2 -2 + //const c[3] = 0.5 0 1 + "dcl_2d s0\n" + "def c2, 0.00195313, 0.12500000, 2.00000000, -2.00000000\n" + "def c3, 0.50000000, 0.00000000, 1.00000000, 0\n" + "dcl t1\n" + "dcl t0.xy\n" + "texld r5, t1, s0\n" + "mov r1.y, t1.w\n" + "mov r1.x, t1.z\n" + "mov r2.xy, r1\n" + "mov r0.y, t1.w\n" + "mov r0.x, t1\n" + "mov r1.y, t1\n" + "mov r1.x, t1.z\n" + "texld r1, r1, s0\n" + "texld r0, r0, s0\n" + "texld r6, r2, s0\n" + "add r0.x, r1.w, c2\n" + "add r2.x, -r0, r0.w\n" + "add r1.x, r5.w, r2\n" + "add r2.z, r1.x, -r6.w\n" + "add r2.x, -r5.w, r2\n" + "add r2.x, r6.w, r2\n" + "mov r3.x, r2\n" + "mov r3.y, r2.z\n" + "mov r2.y, r2.z\n" + "mov r1.y, r2.z\n" + "mov r1.x, r2\n" + "mul r1.xy, r3, r1\n" + "add r1.x, r1, r1.y\n" + "rsq r1.x, r1.x\n" + "mul r4.xy, r1.x, r2\n" + "abs r2.x, r4.y\n" + "abs r1.x, r4\n" + "min r1.x, r1, r2\n" + "rcp r1.x, r1.x\n" + "mul r1.xy, r1.x, r4\n" + "mul r1.xy, r1, c2.y\n" + "min r1.xy, r1, c2.z\n" + "max r2.xy, r1, c2.w\n" + "mov r1.y, c1.w\n" + "mov r1.x, c1.z\n" + "mad r3.xy, r2, r1, t0\n" + "mov r1.y, c1.w\n" + "mov r1.x, c1.z\n" + "mad r5.xy, -r2, r1, t0\n" + "mov r1.y, c0.w\n" + "mov r1.x, c0.z\n" + "mad r2.xy, -r4, r1, t0\n" + "mov r1.y, c0.w\n" + "mov r1.x, c0.z\n" + "mad r1.xy, r4, r1, t0\n" + "texld r4, r5, s0\n" + "texld r3, r3, s0\n" + "texld r1, r1, s0\n" + "texld r2, r2, s0\n" + "add r1, r2, r1\n" + "mul r2, r1, c3.x\n" + "add r1, r4, r3\n" + "max r3.x, r0, r6.w\n" + "mad r1, r1, c3.x, r2\n" + "mul r4, r1, c3.x\n" + "max r1.x, r0.w, r5.w\n" + "max r1.x, r1, r3\n" + "add r1.x, -r4.w, r1\n" + "min r3.x, r0.w, r5.w\n" + "min r0.x, r0, r6.w\n" + "min r0.x, r3, r0\n" + "add r0.x, r4.w, -r0\n" + "cmp r1.x, r1, c3.y, c3.z\n" + "cmp r0.x, r0, c3.y, c3.z\n" + "add_pp_sat r0.x, r0, r1\n" + "cmp r0, -r0.x, r4, r2\n" + "mov oC0, r0\n"; + +const char *a_ps_2_0_earlyexit = "ps_2_x\n" // cgc version 3.1.0013, build date Apr 18 2012 // command line args: -profile ps_2_x diff --git a/code/nel/src/3d/shaders/compile.bat b/code/nel/src/3d/shaders/compile.bat new file mode 100644 index 000000000..a1d660d9d --- /dev/null +++ b/code/nel/src/3d/shaders/compile.bat @@ -0,0 +1,3 @@ +cgc -entry fxaa_pp fxaa_pp.cg -profile arbfp1 -O3 -fastmath -fastprecision -o fxaa_pp_arbfp1.txt +cgc -entry fxaa_pp fxaa_pp.cg -profile ps_2_0 -O3 -fastmath -fastprecision -o fxaa_pp_ps_2_0.txt +cgc -entry fxaa_vp fxaa_vp.cg -profile arbvp1 -fastmath -fastprecision -o fxaa_vp_arbvp1.txt \ No newline at end of file diff --git a/code/nel/src/3d/shaders/fxaa3_11.h b/code/nel/src/3d/shaders/fxaa3_11.h new file mode 100644 index 000000000..0443fd6e2 --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa3_11.h @@ -0,0 +1,2042 @@ +/*============================================================================ + + +NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ +INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + +#define FXAA_PC 1 +#define FXAA_HLSL_5 1 +#define FXAA_QUALITY__PRESET 12 + +Or, + +#define FXAA_360 1 +Or, + +#define FXAA_PS3 1 +Etc. + +(2.) +Then include this file, + +#include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + +return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + +#define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + +FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2, +FxaaFloat4 fxaaConsole360RcpFrameOpt2, +FxaaFloat fxaaQualitySubpix, +FxaaFloat fxaaQualityEdgeThreshold, +FxaaFloat fxaaQualityEdgeThresholdMin, +FxaaFloat fxaaConsoleEdgeSharpness, +FxaaFloat fxaaConsoleEdgeThreshold, +FxaaFloat fxaaConsoleEdgeThresholdMin, +FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + +// {xy} = center of pixel +FxaaFloat2 pos, + +// {xy__} = upper left of pixel +// {__zw} = lower right of pixel +FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ +INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + +#define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + +color.rgb = ToneMap(color.rgb); // linear color output +color.rgb = sqrt(color.rgb); // gamma 2.0 color output +return color; + +To use FXAA, + +color.rgb = ToneMap(color.rgb); // linear color output +color.rgb = sqrt(color.rgb); // gamma 2.0 color output +color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma +return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + +color.rgb = ToneMap(color.rgb); // linear color output +return color; + +To use FXAA, + +color.rgb = ToneMap(color.rgb); // linear color output +color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma +return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ +BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ +COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, +have the pass write out luma into alpha. +Then blend into RGB only. +FXAA should be able to run ok +assuming the blending pass did not any add aliasing. +This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + +INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 +#define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 +#define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT +#define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC +// +// FXAA Quality +// The high quality PC algorithm. +// +#define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE +// +// The console algorithm for PC is included +// for developers targeting really low spec machines. +// Likely better to just run FXAA_PC, and use a really low preset. +// +#define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 +#define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 +#define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 +#define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 +#define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 +#define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA +// +// For those using non-linear color, +// and either not able to get luma in alpha, or not wanting to, +// this enables FXAA to run using green as a proxy for luma. +// So with this enabled, no need to pack luma in alpha. +// +// This will turn off AA on anything which lacks some amount of green. +// Pure red and blue or combination of only R and B, will get no AA. +// +// Might want to lower the settings for both, +// fxaaConsoleEdgeThresholdMin +// fxaaQualityEdgeThresholdMin +// In order to insure AA does not get turned off on colors +// which contain a minor amount of green. +// +// 1 = On. +// 0 = Off. +// +#define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT +// +// Controls algorithm's early exit path. +// On PS3 turning this ON adds 2 cycles to the shader. +// On 360 turning this OFF adds 10ths of a millisecond to the shader. +// Turning this off on console will result in a more blurry image. +// So this defaults to on. +// +// 1 = On. +// 0 = Off. +// +#define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD +// +// Only valid for PC OpenGL currently. +// Probably will not work when FXAA_GREEN_AS_LUMA = 1. +// +// 1 = Use discard on pixels which don't need AA. +// For APIs which enable concurrent TEX+ROP from same surface. +// 0 = Return unchanged color on pixels which don't need AA. +// +#define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET +// +// Used for GLSL 120 only. +// +// 1 = GL API supports fast pixel offsets +// 0 = do not use fast pixel offsets +// +#ifdef GL_EXT_gpu_shader4 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifdef GL_NV_gpu_shader5 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifdef GL_ARB_gpu_shader5 +#define FXAA_FAST_PIXEL_OFFSET 1 +#endif +#ifndef FXAA_FAST_PIXEL_OFFSET +#define FXAA_FAST_PIXEL_OFFSET 0 +#endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA +// +// 1 = API supports gather4 on alpha channel. +// 0 = API does not support gather4 on alpha channel. +// +#if (FXAA_HLSL_5 == 1) +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifdef GL_ARB_gpu_shader5 +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifdef GL_NV_gpu_shader5 +#define FXAA_GATHER4_ALPHA 1 +#endif +#ifndef FXAA_GATHER4_ALPHA +#define FXAA_GATHER4_ALPHA 0 +#endif +#endif + +/*============================================================================ +FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS +// +// Consoles the sharpness of edges on PS3 only. +// Non-PS3 tuning is done with shader input. +// +// Due to the PS3 being ALU bound, +// there are only two safe values here: 4 and 8. +// These options use the shaders ability to a free *|/ by 2|4|8. +// +// 8.0 is sharper +// 4.0 is softer +// 2.0 is really soft (good for vector graphics inputs) +// +#if 1 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 +#endif +#if 0 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 +#endif +#if 0 +#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 +#endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD +// +// Only effects PS3. +// Non-PS3 tuning is done with shader input. +// +// The minimum amount of local contrast required to apply algorithm. +// The console setting has a different mapping than the quality setting. +// +// This only applies when FXAA_EARLY_EXIT is 1. +// +// Due to the PS3 being ALU bound, +// there are only two safe values here: 0.25 and 0.125. +// These options use the shaders ability to a free *|/ by 2|4|8. +// +// 0.125 leaves less aliasing, but is softer +// 0.25 leaves more aliasing, and is sharper +// +#if 1 +#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 +#else +#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 +#endif +#endif + +/*============================================================================ +FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET +// +// Choose the quality preset. +// This needs to be compiled into the shader as it effects code. +// Best option to include multiple presets is to +// in each shader define the preset, then include this file. +// +// OPTIONS +// ----------------------------------------------------------------------- +// 10 to 15 - default medium dither (10=fastest, 15=highest quality) +// 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) +// 39 - no dither, very expensive +// +// NOTES +// ----------------------------------------------------------------------- +// 12 = slightly faster then FXAA 3.9 and higher edge quality (default) +// 13 = about same speed as FXAA 3.9 and better than 12 +// 23 = closest to FXAA 3.9 visually and performance wise +// _ = the lowest digit is directly related to performance +// _ = the highest digit is directly related to style +// +#define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + +FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ +FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) +#define FXAA_QUALITY__PS 3 +#define FXAA_QUALITY__P0 1.5 +#define FXAA_QUALITY__P1 3.0 +#define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) +#define FXAA_QUALITY__PS 4 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 3.0 +#define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) +#define FXAA_QUALITY__PS 5 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 4.0 +#define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) +#define FXAA_QUALITY__PS 6 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 4.0 +#define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) +#define FXAA_QUALITY__PS 7 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 4.0 +#define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) +#define FXAA_QUALITY__PS 8 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 4.0 +#define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ +FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) +#define FXAA_QUALITY__PS 3 +#define FXAA_QUALITY__P0 1.5 +#define FXAA_QUALITY__P1 2.0 +#define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) +#define FXAA_QUALITY__PS 4 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) +#define FXAA_QUALITY__PS 5 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) +#define FXAA_QUALITY__PS 6 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) +#define FXAA_QUALITY__PS 7 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 3.0 +#define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) +#define FXAA_QUALITY__PS 8 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 4.0 +#define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) +#define FXAA_QUALITY__PS 9 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 4.0 +#define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) +#define FXAA_QUALITY__PS 10 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 4.0 +#define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) +#define FXAA_QUALITY__PS 11 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 4.0 +#define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) +#define FXAA_QUALITY__PS 12 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.5 +#define FXAA_QUALITY__P2 2.0 +#define FXAA_QUALITY__P3 2.0 +#define FXAA_QUALITY__P4 2.0 +#define FXAA_QUALITY__P5 2.0 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 2.0 +#define FXAA_QUALITY__P10 4.0 +#define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ +FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) +#define FXAA_QUALITY__PS 12 +#define FXAA_QUALITY__P0 1.0 +#define FXAA_QUALITY__P1 1.0 +#define FXAA_QUALITY__P2 1.0 +#define FXAA_QUALITY__P3 1.0 +#define FXAA_QUALITY__P4 1.0 +#define FXAA_QUALITY__P5 1.5 +#define FXAA_QUALITY__P6 2.0 +#define FXAA_QUALITY__P7 2.0 +#define FXAA_QUALITY__P8 2.0 +#define FXAA_QUALITY__P9 2.0 +#define FXAA_QUALITY__P10 4.0 +#define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + +API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) +#define FxaaBool bool +#define FxaaDiscard discard +#define FxaaFloat float +#define FxaaFloat2 vec2 +#define FxaaFloat3 vec3 +#define FxaaFloat4 vec4 +#define FxaaHalf float +#define FxaaHalf2 vec2 +#define FxaaHalf3 vec3 +#define FxaaHalf4 vec4 +#define FxaaInt2 ivec2 +#define FxaaSat(x) clamp(x, 0.0, 1.0) +#define FxaaTex sampler2D +#else +#define FxaaBool bool +#define FxaaDiscard clip(-1) +#define FxaaFloat float +#define FxaaFloat2 float2 +#define FxaaFloat3 float3 +#define FxaaFloat4 float4 +#define FxaaHalf half +#define FxaaHalf2 half2 +#define FxaaHalf3 half3 +#define FxaaHalf4 half4 +#define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) +// Requires, +// #version 120 +// And at least, +// #extension GL_EXT_gpu_shader4 : enable +// (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) +#define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) +#if (FXAA_FAST_PIXEL_OFFSET == 1) +#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) +#else +#define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) +#endif +#if (FXAA_GATHER4_ALPHA == 1) +// use #extension GL_ARB_gpu_shader5 : enable +#define FxaaTexAlpha4(t, p) textureGather(t, p, 3) +#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) +#define FxaaTexGreen4(t, p) textureGather(t, p, 1) +#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) +#endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) +// Requires "#version 130" or better +#define FxaaTexTop(t, p) textureLod(t, p, 0.0) +#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) +#if (FXAA_GATHER4_ALPHA == 1) +// use #extension GL_ARB_gpu_shader5 : enable +#define FxaaTexAlpha4(t, p) textureGather(t, p, 3) +#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) +#define FxaaTexGreen4(t, p) textureGather(t, p, 1) +#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) +#endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) +#define FxaaInt2 float2 +#define FxaaTex sampler2D +#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) +#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) +#define FxaaInt2 int2 +struct FxaaTex { SamplerState smpl; Texture2D tex; }; +#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) +#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) +#define FxaaInt2 int2 +struct FxaaTex { SamplerState smpl; Texture2D tex; }; +#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) +#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) +#define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) +#define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) +#define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ +GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) +FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else +FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + +FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( +// +// Use noperspective interpolation here (turn off perspective interpolation). +// {xy} = center of pixel +FxaaFloat2 pos, +// +// Used only for FXAA Console, and not used on the 360 version. +// Use noperspective interpolation here (turn off perspective interpolation). +// {xy__} = upper left of pixel +// {__zw} = lower right of pixel +FxaaFloat4 fxaaConsolePosPos, +// +// Input color texture. +// {rgb_} = color in linear or perceptual color space +// if (FXAA_GREEN_AS_LUMA == 0) +// {___a} = luma in perceptual color space (not linear) +FxaaTex tex, +// +// Only used on the optimized 360 version of FXAA Console. +// For everything but 360, just use the same input here as for "tex". +// For 360, same texture, just alias with a 2nd sampler. +// This sampler needs to have an exponent bias of -1. +FxaaTex fxaaConsole360TexExpBiasNegOne, +// +// Only used on the optimized 360 version of FXAA Console. +// For everything but 360, just use the same input here as for "tex". +// For 360, same texture, just alias with a 3nd sampler. +// This sampler needs to have an exponent bias of -2. +FxaaTex fxaaConsole360TexExpBiasNegTwo, +// +// Only used on FXAA Quality. +// This must be from a constant/uniform. +// {x_} = 1.0/screenWidthInPixels +// {_y} = 1.0/screenHeightInPixels +FxaaFloat2 fxaaQualityRcpFrame, +// +// Only used on FXAA Console. +// This must be from a constant/uniform. +// This effects sub-pixel AA quality and inversely sharpness. +// Where N ranges between, +// N = 0.50 (default) +// N = 0.33 (sharper) +// {x___} = -N/screenWidthInPixels +// {_y__} = -N/screenHeightInPixels +// {__z_} = N/screenWidthInPixels +// {___w} = N/screenHeightInPixels +FxaaFloat4 fxaaConsoleRcpFrameOpt, +// +// Only used on FXAA Console. +// Not used on 360, but used on PS3 and PC. +// This must be from a constant/uniform. +// {x___} = -2.0/screenWidthInPixels +// {_y__} = -2.0/screenHeightInPixels +// {__z_} = 2.0/screenWidthInPixels +// {___w} = 2.0/screenHeightInPixels +FxaaFloat4 fxaaConsoleRcpFrameOpt2, +// +// Only used on FXAA Console. +// Only used on 360 in place of fxaaConsoleRcpFrameOpt2. +// This must be from a constant/uniform. +// {x___} = 8.0/screenWidthInPixels +// {_y__} = 8.0/screenHeightInPixels +// {__z_} = -4.0/screenWidthInPixels +// {___w} = -4.0/screenHeightInPixels +FxaaFloat4 fxaaConsole360RcpFrameOpt2, +// +// Only used on FXAA Quality. +// This used to be the FXAA_QUALITY__SUBPIX define. +// It is here now to allow easier tuning. +// Choose the amount of sub-pixel aliasing removal. +// This can effect sharpness. +// 1.00 - upper limit (softer) +// 0.75 - default amount of filtering +// 0.50 - lower limit (sharper, less sub-pixel aliasing removal) +// 0.25 - almost off +// 0.00 - completely off +FxaaFloat fxaaQualitySubpix, +// +// Only used on FXAA Quality. +// This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. +// It is here now to allow easier tuning. +// The minimum amount of local contrast required to apply algorithm. +// 0.333 - too little (faster) +// 0.250 - low quality +// 0.166 - default +// 0.125 - high quality +// 0.063 - overkill (slower) +FxaaFloat fxaaQualityEdgeThreshold, +// +// Only used on FXAA Quality. +// This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. +// It is here now to allow easier tuning. +// Trims the algorithm from processing darks. +// 0.0833 - upper limit (default, the start of visible unfiltered edges) +// 0.0625 - high quality (faster) +// 0.0312 - visible limit (slower) +// Special notes when using FXAA_GREEN_AS_LUMA, +// Likely want to set this to zero. +// As colors that are mostly not-green +// will appear very dark in the green channel! +// Tune by looking at mostly non-green content, +// then start at zero and increase until aliasing is a problem. +FxaaFloat fxaaQualityEdgeThresholdMin, +// +// Only used on FXAA Console. +// This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. +// It is here now to allow easier tuning. +// This does not effect PS3, as this needs to be compiled in. +// Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. +// Due to the PS3 being ALU bound, +// there are only three safe values here: 2 and 4 and 8. +// These options use the shaders ability to a free *|/ by 2|4|8. +// For all other platforms can be a non-power of two. +// 8.0 is sharper (default!!!) +// 4.0 is softer +// 2.0 is really soft (good only for vector graphics inputs) +FxaaFloat fxaaConsoleEdgeSharpness, +// +// Only used on FXAA Console. +// This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. +// It is here now to allow easier tuning. +// This does not effect PS3, as this needs to be compiled in. +// Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. +// Due to the PS3 being ALU bound, +// there are only two safe values here: 1/4 and 1/8. +// These options use the shaders ability to a free *|/ by 2|4|8. +// The console setting has a different mapping than the quality setting. +// Other platforms can use other values. +// 0.125 leaves less aliasing, but is softer (default!!!) +// 0.25 leaves more aliasing, and is sharper +FxaaFloat fxaaConsoleEdgeThreshold, +// +// Only used on FXAA Console. +// This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. +// It is here now to allow easier tuning. +// Trims the algorithm from processing darks. +// The console setting has a different mapping than the quality setting. +// This only applies when FXAA_EARLY_EXIT is 1. +// This does not apply to PS3, +// PS3 was simplified to avoid more shader instructions. +// 0.06 - faster but more aliasing in darks +// 0.05 - default +// 0.04 - slower and less aliasing in darks +// Special notes when using FXAA_GREEN_AS_LUMA, +// Likely want to set this to zero. +// As colors that are mostly not-green +// will appear very dark in the green channel! +// Tune by looking at mostly non-green content, +// then start at zero and increase until aliasing is a problem. +FxaaFloat fxaaConsoleEdgeThresholdMin, +// +// Extra constants for 360 FXAA Console only. +// Use zeros or anything else for other platforms. +// These must be in physical constant registers and NOT immedates. +// Immedates will result in compiler un-optimizing. +// {xyzw} = float4(1.0, -1.0, 0.25, -0.25) +FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +FxaaFloat2 posM; +posM.x = pos.x; +posM.y = pos.y; +#if (FXAA_GATHER4_ALPHA == 1) +#if (FXAA_DISCARD == 0) +FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); +#if (FXAA_GREEN_AS_LUMA == 0) +#define lumaM rgbyM.w +#else +#define lumaM rgbyM.y +#endif +#endif +#if (FXAA_GREEN_AS_LUMA == 0) +FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); +FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); +#else +FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); +FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); +#endif +#if (FXAA_DISCARD == 1) +#define lumaM luma4A.w +#endif +#define lumaE luma4A.z +#define lumaS luma4A.x +#define lumaSE luma4A.y +#define lumaNW luma4B.w +#define lumaN luma4B.z +#define lumaW luma4B.x +#else +FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); +#if (FXAA_GREEN_AS_LUMA == 0) +#define lumaM rgbyM.w +#else +#define lumaM rgbyM.y +#endif +FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); +#endif +/*--------------------------------------------------------------------------*/ +FxaaFloat maxSM = max(lumaS, lumaM); +FxaaFloat minSM = min(lumaS, lumaM); +FxaaFloat maxESM = max(lumaE, maxSM); +FxaaFloat minESM = min(lumaE, minSM); +FxaaFloat maxWN = max(lumaN, lumaW); +FxaaFloat minWN = min(lumaN, lumaW); +FxaaFloat rangeMax = max(maxWN, maxESM); +FxaaFloat rangeMin = min(minWN, minESM); +FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; +FxaaFloat range = rangeMax - rangeMin; +FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); +FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ +if(earlyExit) +#if (FXAA_DISCARD == 1) +FxaaDiscard; +#else +return rgbyM; +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GATHER4_ALPHA == 0) +FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); +#else +FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); +FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); +#endif +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaNS = lumaN + lumaS; +FxaaFloat lumaWE = lumaW + lumaE; +FxaaFloat subpixRcpRange = 1.0/range; +FxaaFloat subpixNSWE = lumaNS + lumaWE; +FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; +FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaNESE = lumaNE + lumaSE; +FxaaFloat lumaNWNE = lumaNW + lumaNE; +FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; +FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaNWSW = lumaNW + lumaSW; +FxaaFloat lumaSWSE = lumaSW + lumaSE; +FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); +FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); +FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; +FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; +FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; +FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ +FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; +FxaaFloat lengthSign = fxaaQualityRcpFrame.x; +FxaaBool horzSpan = edgeHorz >= edgeVert; +FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ +if(!horzSpan) lumaN = lumaW; +if(!horzSpan) lumaS = lumaE; +if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; +FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ +FxaaFloat gradientN = lumaN - lumaM; +FxaaFloat gradientS = lumaS - lumaM; +FxaaFloat lumaNN = lumaN + lumaM; +FxaaFloat lumaSS = lumaS + lumaM; +FxaaBool pairN = abs(gradientN) >= abs(gradientS); +FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); +if(pairN) lengthSign = -lengthSign; +FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ +FxaaFloat2 posB; +posB.x = posM.x; +posB.y = posM.y; +FxaaFloat2 offNP; +offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; +offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; +if(!horzSpan) posB.x += lengthSign * 0.5; +if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ +FxaaFloat2 posN; +posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; +posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; +FxaaFloat2 posP; +posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; +posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; +FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; +FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); +FxaaFloat subpixE = subpixC * subpixC; +FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ +if(!pairN) lumaNN = lumaSS; +FxaaFloat gradientScaled = gradient * 1.0/4.0; +FxaaFloat lumaMM = lumaM - lumaNN * 0.5; +FxaaFloat subpixF = subpixD * subpixE; +FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ +lumaEndN -= lumaNN * 0.5; +lumaEndP -= lumaNN * 0.5; +FxaaBool doneN = abs(lumaEndN) >= gradientScaled; +FxaaBool doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; +FxaaBool doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 3) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 4) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 5) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 6) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 7) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 8) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 9) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 10) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 11) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PS > 12) +if(doneNP) { +if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); +if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); +if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; +if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; +doneN = abs(lumaEndN) >= gradientScaled; +doneP = abs(lumaEndP) >= gradientScaled; +if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; +if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; +doneNP = (!doneN) || (!doneP); +if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; +if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +#endif +/*--------------------------------------------------------------------------*/ +} +/*--------------------------------------------------------------------------*/ +FxaaFloat dstN = posM.x - posN.x; +FxaaFloat dstP = posP.x - posM.x; +if(!horzSpan) dstN = posM.y - posN.y; +if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ +FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; +FxaaFloat spanLength = (dstP + dstN); +FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; +FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ +FxaaBool directionN = dstN < dstP; +FxaaFloat dst = min(dstN, dstP); +FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; +FxaaFloat subpixG = subpixF * subpixF; +FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; +FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ +FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; +FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); +if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; +if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; +#if (FXAA_DISCARD == 1) +return FxaaTexTop(tex, posM); +#else +return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); +#endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + +FXAA3 CONSOLE - PC VERSION +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with +#define FXAA_QUALITY__PRESET 10 +Or +#define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( +// See FXAA Quality FxaaPixelShader() source for docs on Inputs! +FxaaFloat2 pos, +FxaaFloat4 fxaaConsolePosPos, +FxaaTex tex, +FxaaTex fxaaConsole360TexExpBiasNegOne, +FxaaTex fxaaConsole360TexExpBiasNegTwo, +FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2, +FxaaFloat4 fxaaConsole360RcpFrameOpt2, +FxaaFloat fxaaQualitySubpix, +FxaaFloat fxaaQualityEdgeThreshold, +FxaaFloat fxaaQualityEdgeThresholdMin, +FxaaFloat fxaaConsoleEdgeSharpness, +FxaaFloat fxaaConsoleEdgeThreshold, +FxaaFloat fxaaConsoleEdgeThresholdMin, +FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); +FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); +FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); +FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ +FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); +#if (FXAA_GREEN_AS_LUMA == 0) +FxaaFloat lumaM = rgbyM.w; +#else +FxaaFloat lumaM = rgbyM.y; +#endif +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); +lumaNe += 1.0/384.0; +FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); +FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); +FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ +FxaaFloat lumaMinM = min(lumaMin, lumaM); +FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); +FxaaFloat lumaMaxM = max(lumaMax, lumaM); +FxaaFloat dirSwMinusNe = lumaSw - lumaNe; +FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; +FxaaFloat dirSeMinusNw = lumaSe - lumaNw; +if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ +FxaaFloat2 dir; +dir.x = dirSwMinusNe + dirSeMinusNw; +dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ +FxaaFloat2 dir1 = normalize(dir.xy); +FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); +FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ +FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; +FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ +FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); +FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ +FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; +FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ +#if (FXAA_GREEN_AS_LUMA == 0) +FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); +#else +FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); +#endif +if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; +return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( +// See FXAA Quality FxaaPixelShader() source for docs on Inputs! +FxaaFloat2 pos, +FxaaFloat4 fxaaConsolePosPos, +FxaaTex tex, +FxaaTex fxaaConsole360TexExpBiasNegOne, +FxaaTex fxaaConsole360TexExpBiasNegTwo, +FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2, +FxaaFloat4 fxaaConsole360RcpFrameOpt2, +FxaaFloat fxaaQualitySubpix, +FxaaFloat fxaaQualityEdgeThreshold, +FxaaFloat fxaaQualityEdgeThresholdMin, +FxaaFloat fxaaConsoleEdgeSharpness, +FxaaFloat fxaaConsoleEdgeThreshold, +FxaaFloat fxaaConsoleEdgeThresholdMin, +FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +float4 lumaNwNeSwSe; +#if (FXAA_GREEN_AS_LUMA == 0) +asm { +tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false +}; +#else +asm { +tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false +tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false +}; +#endif +/*--------------------------------------------------------------------------*/ +lumaNwNeSwSe.y += 1.0/384.0; +float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); +float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); +float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); +float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ +float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); +#if (FXAA_GREEN_AS_LUMA == 0) +float lumaMinM = min(lumaMin, rgbyM.w); +float lumaMaxM = max(lumaMax, rgbyM.w); +#else +float lumaMinM = min(lumaMin, rgbyM.y); +float lumaMaxM = max(lumaMax, rgbyM.y); +#endif +if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ +float2 dir; +dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); +dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); +dir = normalize(dir); +/*--------------------------------------------------------------------------*/ +float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ +float4 dir2; +float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; +dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); +dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ +float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); +float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); +float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); +float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +float4 rgbyA = rgbyN1 + rgbyP1; +float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; +/*--------------------------------------------------------------------------*/ +float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; +rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; +return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + +--fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ +NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: +0: texpkb h0.w(TRUE), v5.zyxx, #0 +2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x +4: texpkb h0.w(TRUE), v5.xwxx, #0 +6: addh h0.z(TRUE), -h2, h0.w +7: texpkb h1.w(TRUE), v5, #0 +9: addh h0.x(TRUE), h0.z, -h1.w +10: addh h3.w(TRUE), h0.z, h1 +11: texpkb h2.w(TRUE), v5.zwzz, #0 +13: addh h0.z(TRUE), h3.w, -h2.w +14: addh h0.x(TRUE), h2.w, h0 +15: nrmh h1.xz(TRUE), h0_n +16: minh_m8 h0.x(TRUE), |h1|, |h1.z| +17: maxh h4.w(TRUE), h0, h1 +18: divx h2.xy(TRUE), h1_n.xzzw, h0_n +19: movr r1.zw(TRUE), v4.xxxy +20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww +22: minh h5.w(TRUE), h0, h1 +23: texpkb h0(TRUE), r2.xzxx, #0 +25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 +27: maxh h4.x(TRUE), h2.z, h2.w +28: texpkb h1(TRUE), r0.zwzz, #0 +30: addh_d2 h1(TRUE), h0, h1 +31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +33: texpkb h0(TRUE), r0, #0 +35: minh h4.z(TRUE), h2, h2.w +36: fenct TRUE +37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +39: texpkb h2(TRUE), r1, #0 +41: addh_d2 h0(TRUE), h0, h2 +42: maxh h2.w(TRUE), h4, h4.x +43: minh h2.x(TRUE), h5.w, h4.z +44: addh_d2 h0(TRUE), h0, h1 +45: slth h2.x(TRUE), h0.w, h2 +46: sgth h2.w(TRUE), h0, h2 +47: movh h0(TRUE), h0 +48: addx.c0 rc(TRUE), h2, h2.w +49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- +1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; +| | | +2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; +| TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; +| SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; +| | | +3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; +| TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; +| SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; +| SCB1 | add | 10: ADDh h3.w, h0.---z, h1; +| | | +4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| SCB0 | add | 14: ADDh h0.x, h2.w---, h0; +| SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; +| | | +5 | SCT1 | mov | 15: NRMh h1.xz, h0; +| SRB | nrm | 15: NRMh h1.xz, h0; +| SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; +| SCB1 | max | 17: MAXh h4.w, h0, h1; +| | | +6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; +| SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; +| SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; +| SCB1 | min | 22: MINh h5.w, h0, h1; +| | | +7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; +| TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; +| SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; +| SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; +| | | +8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; +| TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; +| SCB0/1 | add | 30: ADDh/2 h1, h0, h1; +| | | +9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; +| SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; +| TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; +| SCB1 | min | 35: MINh h4.z, h2, h2.--w-; +| | | +10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; +| SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; +| TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; +| SCB0/1 | add | 41: ADDh/2 h0, h0, h2; +| | | +11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; +| SCT1 | max | 42: MAXh h2.w, h4, h4.---x; +| SCB0/1 | add | 44: ADDh/2 h0, h0, h1; +| | | +12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; +| SCT1 | set | 46: SGTh h2.w, h0, h2; +| SCB0/1 | mul | 47: MOVh h0, h0; +| | | +13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; +| SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; +Pass SCT TEX SCB +1: 0% 100% 25% +2: 0% 100% 25% +3: 0% 100% 50% +4: 0% 100% 50% +5: 0% 0% 50% +6: 100% 0% 75% +7: 0% 100% 75% +8: 0% 100% 100% +9: 0% 100% 25% +10: 0% 100% 100% +11: 50% 0% 100% +12: 50% 0% 100% +13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 +1: 0% 0% 100% 0% 100% +2: 0% 0% 100% 0% 100% +3: 0% 0% 100% 100% 100% +4: 0% 0% 100% 100% 100% +5: 0% 0% 0% 100% 100% +6: 100% 100% 0% 100% 100% +7: 0% 0% 100% 100% 100% +8: 0% 0% 100% 100% 100% +9: 0% 0% 100% 0% 100% +10: 0% 0% 100% 100% 100% +11: 100% 100% 0% 100% 100% +12: 100% 100% 0% 100% 100% +13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +//#pragma option O3 +//#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( +// See FXAA Quality FxaaPixelShader() source for docs on Inputs! +FxaaFloat2 pos, +FxaaFloat4 fxaaConsolePosPos, +FxaaTex tex, +//FxaaTex fxaaConsole360TexExpBiasNegOne, +//FxaaTex fxaaConsole360TexExpBiasNegTwo, +//FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2 +//FxaaFloat4 fxaaConsole360RcpFrameOpt2, +//FxaaFloat fxaaQualitySubpix, +//FxaaFloat fxaaQualityEdgeThreshold, +//FxaaFloat fxaaQualityEdgeThresholdMin, +//FxaaFloat fxaaConsoleEdgeSharpness, +//FxaaFloat fxaaConsoleEdgeThreshold, +//FxaaFloat fxaaConsoleEdgeThresholdMin, +//FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) +half4 dir; +half4 lumaNe = tex2D(tex, fxaaConsolePosPos.zy); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +lumaNe.w += half(1.0/512.0); +dir.x = -lumaNe.w; +dir.z = -lumaNe.w; +#else +lumaNe.y += half(1.0/512.0); +dir.x = -lumaNe.y; +dir.z = -lumaNe.y; +#endif +/*--------------------------------------------------------------------------*/ +// (2) +half4 lumaSw = tex2D(tex, fxaaConsolePosPos.xw); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +dir.x += lumaSw.w; +dir.z += lumaSw.w; +#else +dir.x += lumaSw.y; +dir.z += lumaSw.y; +#endif +/*--------------------------------------------------------------------------*/ +// (3) +half4 lumaNw = tex2D(tex, fxaaConsolePosPos.xy); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +dir.x -= lumaNw.w; +dir.z += lumaNw.w; +#else +dir.x -= lumaNw.y; +dir.z += lumaNw.y; +#endif +/*--------------------------------------------------------------------------*/ +// (4) +half4 lumaSe = tex2D(tex, fxaaConsolePosPos.zw); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +dir.x += lumaSe.w; +dir.z -= lumaSe.w; +#else +dir.x += lumaSe.y; +dir.z -= lumaSe.y; +#endif +/*--------------------------------------------------------------------------*/ +// (5) +half4 dir1_pos; +dir1_pos.xy = normalize(dir.xz); +half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) +half4 dir2_pos; +dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); +dir1_pos.zw = pos.xy; +dir2_pos.zw = pos.xy; +half4 temp1N; +temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) +temp1N = tex2D(tex, temp1N.xy); // h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); +half4 rgby1; +rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) +rgby1 = tex2D(tex, rgby1.xy); // h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); +rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) +half4 temp2N; +temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; +temp2N = tex2D(tex, temp2N.xy); // h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) +half4 rgby2; +rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; +rgby2 = tex2D(tex, rgby2.xy); // h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); +rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) +// compilier moves these scalar ops up to other cycles +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); +half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); +#else +half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); +half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); +#endif +rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) +#if (FXAA_GREEN_AS_LUMA == 0) +bool twoTapLt = rgby2.w < lumaMin; +bool twoTapGt = rgby2.w > lumaMax; +#else +bool twoTapLt = rgby2.y < lumaMin; +bool twoTapGt = rgby2.y > lumaMax; +#endif +/*--------------------------------------------------------------------------*/ +// (13) +if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ +return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + +FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + +--fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ +NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: +0: texpkb h0.w(TRUE), v5.zyxx, #0 +2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x +4: texpkb h1.w(TRUE), v5.xwxx, #0 +6: addh h0.x(TRUE), h1.w, -h2.y +7: texpkb h2.w(TRUE), v5.zwzz, #0 +9: minh h4.w(TRUE), h2.y, h2 +10: maxh h5.x(TRUE), h2.y, h2.w +11: texpkb h0.w(TRUE), v5, #0 +13: addh h3.w(TRUE), -h0, h0.x +14: addh h0.x(TRUE), h0.w, h0 +15: addh h0.z(TRUE), -h2.w, h0.x +16: addh h0.x(TRUE), h2.w, h3.w +17: minh h5.y(TRUE), h0.w, h1.w +18: nrmh h2.xz(TRUE), h0_n +19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| +20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w +21: movr r1.zw(TRUE), v4.xxxy +22: maxh h2.w(TRUE), h0, h1 +23: fenct TRUE +24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz +26: texpkb h0(TRUE), r0, #0 +28: maxh h5.x(TRUE), h2.w, h5 +29: minh h5.w(TRUE), h5.y, h4 +30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz +32: texpkb h2(TRUE), r1, #0 +34: addh_d2 h2(TRUE), h0, h2 +35: texpkb h1(TRUE), v4, #0 +37: maxh h5.y(TRUE), h5.x, h1.w +38: minh h4.w(TRUE), h1, h5 +39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +41: texpkb h0(TRUE), r0, #0 +43: addh_m8 h5.z(TRUE), h5.y, -h4.w +44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz +46: texpkb h3(TRUE), r2, #0 +48: addh_d2 h0(TRUE), h0, h3 +49: addh_d2 h3(TRUE), h0, h2 +50: movh h0(TRUE), h3 +51: slth h3.x(TRUE), h3.w, h5.w +52: sgth h3.w(TRUE), h3, h5.x +53: addx.c0 rc(TRUE), h3.x, h3 +54: slth.c0 rc(TRUE), h5.z, h5 +55: movh h0(c0.NE.w), h2 +56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- +1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; +| SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; +| | | +2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; +| TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; +| SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; +| | | +3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; +| SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; +| SCB1 | min | 9: MINh h4.w, h2.---y, h2; +| | | +4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; +| TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; +| SCB0 | add | 14: ADDh h0.x, h0.w---, h0; +| SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; +| | | +5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; +| SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; +| SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; +| | | +6 | SCT1 | mov | 18: NRMh h2.xz, h0; +| SRB | nrm | 18: NRMh h2.xz, h0; +| SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; +| | | +7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; +| SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; +| SCB1 | max | 22: MAXh h2.w, h0, h1; +| | | +8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; +| SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; +| TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; +| SCB0 | max | 28: MAXh h5.x, h2.w---, h5; +| SCB1 | min | 29: MINh h5.w, h5.---y, h4; +| | | +9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; +| SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; +| TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; +| SCB0/1 | add | 34: ADDh/2 h2, h0, h2; +| | | +10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; +| TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; +| SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; +| SCB1 | min | 38: MINh h4.w, h1, h5; +| | | +11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; +| SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; +| TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; +| SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; +| SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; +| | | +12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; +| TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; +| SCB0/1 | add | 48: ADDh/2 h0, h0, h3; +| | | +13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; +| SCB0/1 | mul | 50: MOVh h0, h3; +| | | +14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; +| SCT1 | set | 52: SGTh h3.w, h3, h5.---x; +| SCB0 | set | 54: SLThc0 rc, h5.z---, h5; +| SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; +| | | +15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; +| SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; +Pass SCT TEX SCB +1: 0% 100% 25% +2: 0% 100% 25% +3: 0% 100% 50% +4: 0% 100% 50% +5: 50% 0% 25% +6: 0% 0% 25% +7: 100% 0% 25% +8: 0% 100% 50% +9: 0% 100% 100% +10: 0% 100% 50% +11: 0% 100% 75% +12: 0% 100% 100% +13: 100% 0% 100% +14: 50% 0% 50% +15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 +1: 0% 0% 100% 100% 0% +2: 0% 0% 100% 100% 0% +3: 0% 0% 100% 100% 100% +4: 0% 0% 100% 100% 100% +5: 100% 100% 0% 100% 0% +6: 0% 0% 0% 0% 100% +7: 100% 100% 0% 0% 100% +8: 0% 0% 100% 100% 100% +9: 0% 0% 100% 100% 100% +10: 0% 0% 100% 100% 100% +11: 0% 0% 100% 100% 100% +12: 0% 0% 100% 100% 100% +13: 100% 100% 0% 100% 100% +14: 100% 100% 0% 100% 100% +15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +//#pragma option O2 +//#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( +// See FXAA Quality FxaaPixelShader() source for docs on Inputs! +FxaaFloat2 pos, +FxaaFloat4 fxaaConsolePosPos, +FxaaTex tex, +//FxaaTex fxaaConsole360TexExpBiasNegOne, +//FxaaTex fxaaConsole360TexExpBiasNegTwo, +//FxaaFloat2 fxaaQualityRcpFrame, +FxaaFloat4 fxaaConsoleRcpFrameOpt, +FxaaFloat4 fxaaConsoleRcpFrameOpt2 +//FxaaFloat4 fxaaConsole360RcpFrameOpt, +//FxaaFloat fxaaQualitySubpix, +//FxaaFloat fxaaQualityEdgeThreshold, +//FxaaFloat fxaaQualityEdgeThresholdMin, +//FxaaFloat fxaaConsoleEdgeSharpness, +//FxaaFloat fxaaConsoleEdgeThreshold, +//FxaaFloat fxaaConsoleEdgeThresholdMin, +//FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) +half4 rgbyNe = tex2D(tex, fxaaConsolePosPos.zy); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaNe = rgbyNe.w + half(1.0/512.0); +#else +half lumaNe = rgbyNe.y + half(1.0/512.0); +#endif +/*--------------------------------------------------------------------------*/ +// (2) +half4 lumaSw = tex2D(tex, fxaaConsolePosPos.xw); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaSwNegNe = lumaSw.w - lumaNe; +#else +half lumaSwNegNe = lumaSw.y - lumaNe; +#endif +/*--------------------------------------------------------------------------*/ +// (3) +half4 lumaNw = tex2D(tex, fxaaConsolePosPos.xy); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); +half lumaMinNwSw = min(lumaNw.w, lumaSw.w); +#else +half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); +half lumaMinNwSw = min(lumaNw.y, lumaSw.y); +#endif +/*--------------------------------------------------------------------------*/ +// (4) +half4 lumaSe = tex2D(tex, fxaaConsolePosPos.zw); // h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); +#if (FXAA_GREEN_AS_LUMA == 0) +half dirZ = lumaNw.w + lumaSwNegNe; +half dirX = -lumaNw.w + lumaSwNegNe; +#else +half dirZ = lumaNw.y + lumaSwNegNe; +half dirX = -lumaNw.y + lumaSwNegNe; +#endif +/*--------------------------------------------------------------------------*/ +// (5) +half3 dir; +dir.y = 0.0; +#if (FXAA_GREEN_AS_LUMA == 0) +dir.x = lumaSe.w + dirX; +dir.z = -lumaSe.w + dirZ; +half lumaMinNeSe = min(lumaNe, lumaSe.w); +#else +dir.x = lumaSe.y + dirX; +dir.z = -lumaSe.y + dirZ; +half lumaMinNeSe = min(lumaNe, lumaSe.y); +#endif +/*--------------------------------------------------------------------------*/ +// (6) +half4 dir1_pos; +dir1_pos.xy = normalize(dir).xz; +half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) +half4 dir2_pos; +dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); +dir1_pos.zw = pos.xy; +dir2_pos.zw = pos.xy; +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaMaxNeSe = max(lumaNe, lumaSe.w); +#else +half lumaMaxNeSe = max(lumaNe, lumaSe.y); +#endif +/*--------------------------------------------------------------------------*/ +// (8) +half4 temp1N; +temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +temp1N = tex2D(tex, temp1N.xy); // h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); +half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); +half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) +half4 rgby1; +rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +rgby1 = tex2D(tex, rgby1.xy); // h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); +rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) +half4 rgbyM = tex2D(tex, pos.xy); // h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); +#if (FXAA_GREEN_AS_LUMA == 0) +half lumaMaxM = max(lumaMax, rgbyM.w); +half lumaMinM = min(lumaMin, rgbyM.w); +#else +half lumaMaxM = max(lumaMax, rgbyM.y); +half lumaMinM = min(lumaMin, rgbyM.y); +#endif +/*--------------------------------------------------------------------------*/ +// (11) +half4 temp2N; +temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; +temp2N = tex2D(tex, temp2N.xy); // h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +half4 rgby2; +rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; +half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) +rgby2 = tex2D(tex, rgby2.xy); // h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); +rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) +rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) +#if (FXAA_GREEN_AS_LUMA == 0) +bool twoTapLt = rgby2.w < lumaMin; +bool twoTapGt = rgby2.w > lumaMax; +#else +bool twoTapLt = rgby2.y < lumaMin; +bool twoTapGt = rgby2.y > lumaMax; +#endif +bool earlyExit = lumaRangeM < lumaMax; +bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) +if(twoTap) rgby2 = rgby1; +if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ +return rgby2; } +/*==========================================================================*/ +#endif \ No newline at end of file diff --git a/code/nel/src/3d/shaders/fxaa_pp.cg b/code/nel/src/3d/shaders/fxaa_pp.cg new file mode 100644 index 000000000..e4993ead8 --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa_pp.cg @@ -0,0 +1,70 @@ + +#define FXAA_PS3 1 +#define FXAA_HLSL_3 1 +#define FXAA_QUALITY__PRESET 12 +#define FXAA_EARLY_EXIT 0 + +#define h4tex2Dlod tex2Dlod +#define half4 float4 +#define half3 float3 +#define half2 float2 +#define half float + +#include "fxaa3_11.h" + +void fxaa_pp( + // Per fragment parameters + float2 pos : TEXCOORD0, + float4 fxaaConsolePosPos : TEXCOORD1, + + // Fragment program constants + uniform float4 fxaaConsoleRcpFrameOpt, + uniform float4 fxaaConsoleRcpFrameOpt2, + uniform sampler2D nlTex0 : TEX0, + + // Output color + out float4 oCol : COLOR +) +{ + oCol = FxaaPixelShader( + pos, + fxaaConsolePosPos, + nlTex0, + fxaaConsoleRcpFrameOpt, + fxaaConsoleRcpFrameOpt2 + ); +} + +/* +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + +// {xy} = center of pixel +FxaaFloat2 pos, + +// {xy__} = upper left of pixel +// {__zw} = lower right of pixel +FxaaFloat4 fxaaConsolePosPos, +*/ + +// fxaaConsoleRcpFrameOpt: +// Only used on FXAA Console. +// This must be from a constant/uniform. +// This effects sub-pixel AA quality and inversely sharpness. +// Where N ranges between, +// N = 0.50 (default) +// N = 0.33 (sharper) +// {x___} = -N/screenWidthInPixels +// {_y__} = -N/screenHeightInPixels +// {__z_} = N/screenWidthInPixels +// {___w} = N/screenHeightInPixels + +// fxaaConsoleRcpFrameOpt2: +// Only used on FXAA Console. +// Not used on 360, but used on PS3 and PC. +// This must be from a constant/uniform. +// {x___} = -2.0/screenWidthInPixels +// {_y__} = -2.0/screenHeightInPixels +// {__z_} = 2.0/screenWidthInPixels +// {___w} = 2.0/screenHeightInPixels diff --git a/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt b/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt new file mode 100644 index 000000000..73ecb767c --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt @@ -0,0 +1,76 @@ +!!ARBfp1.0 +OPTION ARB_precision_hint_fastest; +# cgc version 3.1.0013, build date Apr 18 2012 +# command line args: -profile arbfp1 -O3 -fastmath -fastprecision +# source file: fxaa_pp.cg +#vendor NVIDIA Corporation +#version 3.1.0.13 +#profile arbfp1 +#program fxaa_pp +#semantic fxaa_pp.fxaaConsoleRcpFrameOpt +#semantic fxaa_pp.fxaaConsoleRcpFrameOpt2 +#semantic fxaa_pp.nlTex0 : TEX0 +#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 +#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 +#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 +#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 +#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 +#var float4 oCol : $vout.COLOR : COL : 5 : 1 +#const c[2] = 0.125 0 -2 2 +#const c[3] = 0.001953125 0.5 +PARAM c[4] = { program.local[0..1], + { 0.125, 0, -2, 2 }, + { 0.001953125, 0.5 } }; +TEMP R0; +TEMP R1; +TEMP R2; +TEMP R3; +TEMP R4; +TEMP R5; +TEX R1.w, fragment.texcoord[1].zyzw, texture[0], 2D; +ADD R0.x, R1.w, c[3]; +TEX R0.w, fragment.texcoord[1].xwzw, texture[0], 2D; +TEX R1.w, fragment.texcoord[1], texture[0], 2D; +ADD R0.y, -R0.x, R0.w; +ADD R0.z, R1.w, R0.y; +TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D; +ADD R0.y, -R1.w, R0; +ADD R1.x, R2.w, R0.y; +ADD R1.y, R0.z, -R2.w; +MUL R2.xy, R1, R1; +ADD R0.y, R2.x, R2; +RSQ R0.y, R0.y; +MUL R2.xy, R0.y, R1; +MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0]; +ABS R0.z, R2.y; +ABS R0.y, R2.x; +MIN R0.y, R0, R0.z; +RCP R0.y, R0.y; +MUL R1.xy, R0.y, R2; +MUL R1.xy, R1, c[2].x; +MIN R1.xy, R1, c[2].w; +TEX R4, R3, texture[0], 2D; +MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0]; +TEX R3, R2, texture[0], 2D; +ADD R3, R3, R4; +MAX R1.xy, R1, c[2].z; +MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0]; +MUL R5, R3, c[3].y; +MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0]; +MIN R0.z, R0.x, R2.w; +MIN R0.y, R0.w, R1.w; +MIN R0.y, R0, R0.z; +MAX R0.z, R0.x, R2.w; +MAX R0.x, R0.w, R1.w; +MAX R0.x, R0, R0.z; +TEX R4, R2, texture[0], 2D; +TEX R3, R1, texture[0], 2D; +ADD R3, R3, R4; +MAD R3, R3, c[3].y, R5; +MUL R3, R3, c[3].y; +SLT R0.z, R0.x, R3.w; +SLT R0.x, R3.w, R0.y; +ADD_SAT R0.x, R0, R0.z; +CMP result.color, -R0.x, R5, R3; +END +# 45 instructions, 6 R-regs diff --git a/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt b/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt new file mode 100644 index 000000000..fcd16fcd0 --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt @@ -0,0 +1,92 @@ +ps_2_0 +// cgc version 3.1.0013, build date Apr 18 2012 +// command line args: -profile ps_2_0 -O3 -fastmath -fastprecision +// source file: fxaa_pp.cg +//vendor NVIDIA Corporation +//version 3.1.0.13 +//profile ps_2_0 +//program fxaa_pp +//semantic fxaa_pp.fxaaConsoleRcpFrameOpt +//semantic fxaa_pp.fxaaConsoleRcpFrameOpt2 +//semantic fxaa_pp.nlTex0 : TEX0 +//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 +//var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 +//var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 +//var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 +//var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 +//var float4 oCol : $vout.COLOR : COL : 5 : 1 +//const c[2] = 0.001953125 0.125 2 -2 +//const c[3] = 0.5 0 1 +dcl_2d s0 +def c2, 0.00195313, 0.12500000, 2.00000000, -2.00000000 +def c3, 0.50000000, 0.00000000, 1.00000000, 0 +dcl t1 +dcl t0.xy +texld r5, t1, s0 +mov r1.y, t1.w +mov r1.x, t1.z +mov r2.xy, r1 +mov r0.y, t1.w +mov r0.x, t1 +mov r1.y, t1 +mov r1.x, t1.z +texld r1, r1, s0 +texld r0, r0, s0 +texld r6, r2, s0 +add r0.x, r1.w, c2 +add r2.x, -r0, r0.w +add r1.x, r5.w, r2 +add r2.z, r1.x, -r6.w +add r2.x, -r5.w, r2 +add r2.x, r6.w, r2 +mov r3.x, r2 +mov r3.y, r2.z +mov r2.y, r2.z +mov r1.y, r2.z +mov r1.x, r2 +mul r1.xy, r3, r1 +add r1.x, r1, r1.y +rsq r1.x, r1.x +mul r4.xy, r1.x, r2 +abs r2.x, r4.y +abs r1.x, r4 +min r1.x, r1, r2 +rcp r1.x, r1.x +mul r1.xy, r1.x, r4 +mul r1.xy, r1, c2.y +min r1.xy, r1, c2.z +max r2.xy, r1, c2.w +mov r1.y, c1.w +mov r1.x, c1.z +mad r3.xy, r2, r1, t0 +mov r1.y, c1.w +mov r1.x, c1.z +mad r5.xy, -r2, r1, t0 +mov r1.y, c0.w +mov r1.x, c0.z +mad r2.xy, -r4, r1, t0 +mov r1.y, c0.w +mov r1.x, c0.z +mad r1.xy, r4, r1, t0 +texld r4, r5, s0 +texld r3, r3, s0 +texld r1, r1, s0 +texld r2, r2, s0 +add r1, r2, r1 +mul r2, r1, c3.x +add r1, r4, r3 +max r3.x, r0, r6.w +mad r1, r1, c3.x, r2 +mul r4, r1, c3.x +max r1.x, r0.w, r5.w +max r1.x, r1, r3 +add r1.x, -r4.w, r1 +min r3.x, r0.w, r5.w +min r0.x, r0, r6.w +min r0.x, r3, r0 +add r0.x, r4.w, -r0 +cmp r1.x, r1, c3.y, c3.z +cmp r0.x, r0, c3.y, c3.z +add_pp_sat r0.x, r0, r1 +cmp r0, -r0.x, r4, r2 +mov oC0, r0 diff --git a/code/nel/src/3d/shaders/fxaa_vp.cg b/code/nel/src/3d/shaders/fxaa_vp.cg new file mode 100644 index 000000000..13c9c9bcb --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa_vp.cg @@ -0,0 +1,20 @@ + +void fxaa_vp( + // Per vertex parameters + float3 position : POSITION, + float2 texCoord0 : TEXCOORD0, + + // Vertex program constants + uniform float4x4 modelViewProjection, + uniform float4 fxaaConsolePosPos, + + // Output position + out float4 oPosition : POSITION, + out float2 oTexCoord0 : TEXCOORD0, + out float4 oTexCoord1 : TEXCOORD1 +) +{ + oPosition = mul(modelViewProjection, float4(position, 0.0)); + oTexCoord0 = texCoord0; + oTexCoord1 = texCoord0.xyxy + fxaaConsolePosPos; +} diff --git a/code/nel/src/3d/shaders/fxaa_vp_arbvp1.txt b/code/nel/src/3d/shaders/fxaa_vp_arbvp1.txt new file mode 100644 index 000000000..6c8530ae0 --- /dev/null +++ b/code/nel/src/3d/shaders/fxaa_vp_arbvp1.txt @@ -0,0 +1,31 @@ +!!ARBvp1.0 +# cgc version 3.1.0013, build date Apr 18 2012 +# command line args: -profile arbvp1 -fastmath -fastprecision +# source file: fxaa_vp.cg +#vendor NVIDIA Corporation +#version 3.1.0.13 +#profile arbvp1 +#program fxaa_vp +#semantic fxaa_vp.modelViewProjection +#semantic fxaa_vp.fxaaConsolePosPos +#var float3 position : $vin.POSITION : POSITION : 0 : 1 +#var float2 texCoord0 : $vin.TEXCOORD0 : TEXCOORD0 : 1 : 1 +#var float4x4 modelViewProjection : : c[1], 4 : 2 : 1 +#var float4 fxaaConsolePosPos : : c[5] : 3 : 1 +#var float4 oPosition : $vout.POSITION : HPOS : 4 : 1 +#var float2 oTexCoord0 : $vout.TEXCOORD0 : TEX0 : 5 : 1 +#var float4 oTexCoord1 : $vout.TEXCOORD1 : TEX1 : 6 : 1 +#const c[0] = 0 +PARAM c[6] = { { 0 }, + program.local[1..5] }; +TEMP R0; +MOV R0.w, c[0].x; +MOV R0.xyz, vertex.position; +DP4 result.position.w, R0, c[4]; +DP4 result.position.z, R0, c[3]; +DP4 result.position.y, R0, c[2]; +DP4 result.position.x, R0, c[1]; +ADD result.texcoord[1], vertex.texcoord[0].xyxy, c[5]; +MOV result.texcoord[0].xy, vertex.texcoord[0]; +END +# 8 instructions, 1 R-regs diff --git a/code/nel/src/3d/shaders/readme.txt b/code/nel/src/3d/shaders/readme.txt new file mode 100644 index 000000000..fe657f6e5 --- /dev/null +++ b/code/nel/src/3d/shaders/readme.txt @@ -0,0 +1,4 @@ +Compiled shaders are embedded in the source. +Must compile and re-embed manually. + +FXAA is in public domain. \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 4dfb2870a..ad1cb403e 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1730,12 +1730,12 @@ bool mainLoop() { if (effectRender) { - if (ClientCfg.Bloom) - { - if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().applyBloom(); - if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - } + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom(); + Driver->setMatrixMode3D(pCam); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); effectRender = false; } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 2d53bf65e..68cdc47fa 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -801,8 +801,11 @@ void loopIngame() if (effectRender) { if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - if (s_EnableBloom) CBloomEffect::instance().applyBloom(); + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); if (s_FXAA) s_FXAA->applyEffect(); + if (s_EnableBloom) CBloomEffect::instance().applyBloom(); + Driver->setMatrixMode3D(pCam); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); effectRender = false; } From fb525e39114b8ad83543f881e5302ea241229086 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 05:24:40 +0200 Subject: [PATCH 052/240] Cleanup snowballs2 --HG-- branch : multipass-stereo --- code/snowballs2/client/src/commands.cpp | 11 ----------- code/snowballs2/client/src/compass.cpp | 12 ++---------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index f04748d3d..d1929ab49 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -402,17 +402,6 @@ void updateCommands() float CommandsBoxHeight = ((float)(sint32)((CommandsNbLines + 1) * CommandsLineHeight * width)) / width; float CommandsBoxBorderX = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * width)) / width; float CommandsBoxBorderY = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * height)) / height; - if (StereoHMD) - { - float xshift, yshift; - StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); - // snap to pixels - xshift = ((float)(sint32)(xshift * width)) / width; - yshift = ((float)(sint32)(yshift * height)) / height; - // adjust - CommandsBoxX += xshift; - CommandsBoxY += yshift; - } // Display the background Driver->setMatrixMode2D11 (); diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 27e0e27f1..1c36d1f6b 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -95,13 +95,6 @@ void updateCompass () { float x = CompassPosX; float y = CompassPosY; - if (StereoHMD) - { - float xshift, yshift; - StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); - x += xshift; - y += yshift; - } float radius = CompassRadius; // tri @@ -117,8 +110,7 @@ void updateCompass () quad.V2.set ( radius, radius, 0); quad.V3.set (-radius, radius, 0); - if (StereoHMD) Driver->setMatrixMode2D11(); - else Driver->setMatrixMode2D43(); + Driver->setMatrixMode2D43(); CMatrix mtx; @@ -161,7 +153,7 @@ void updateCompass () Driver->setModelMatrix (mtx); Driver->drawQuad (quad, CompassMaterial); - if (!StereoHMD) x *= 3.0/4.0f; + x *= 3.0/4.0f; // Print position TextContext->setHotSpot(UTextContext::MiddleTop); From 8a283ea518158c2accc818dd263dc3fe65fb2b2b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 06:11:47 +0200 Subject: [PATCH 053/240] 3D: User higher quality FXAA version --HG-- branch : multipass-stereo --- code/nel/src/3d/fxaa.cpp | 11 +- code/nel/src/3d/fxaa_program.h | 617 ++++++++++++++++++++- code/nel/src/3d/shaders/compile.bat | 2 +- code/nel/src/3d/shaders/fxaa3_11.h | 28 +- code/nel/src/3d/shaders/fxaa_pp.cg | 23 +- code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt | 340 ++++++++++-- code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt | 376 ++++++++++--- 7 files changed, 1237 insertions(+), 160 deletions(-) diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index c1eb57607..a1f07aaa1 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -200,7 +200,6 @@ void CFXAA::applyEffect() float fwidth = (float)width; float fheight = (float)height; - nldebug("%f, %f", fwidth, fheight); float pwidth = 1.0f / fwidth; float pheight = 1.0f / fheight; float hpwidth = pwidth * 0.5f; @@ -245,10 +244,14 @@ void CFXAA::applyEffect() nlassert(vpok); bool ppok = drv->activePixelProgram(m_PP); nlassert(ppok); - drv->setUniform4f(IDriver::PixelProgram, 0, -n / fwidth, -n / fheight, n / fwidth, n / fheight); // fxaaConsoleRcpFrameOpt - drv->setUniform4f(IDriver::PixelProgram, 1, -2.0f / fwidth, -2.0f / fheight, 2.0f / fwidth, 2.0f / fheight); // fxaaConsoleRcpFrameOpt2 + /*drv->setUniform4f(IDriver::PixelProgram, 0, -n / fwidth, -n / fheight, n / fwidth, n / fheight); // fxaaConsoleRcpFrameOpt + drv->setUniform4f(IDriver::PixelProgram, 1, -2.0f / fwidth, -2.0f / fheight, 2.0f / fwidth, 2.0f / fheight); // fxaaConsoleRcpFrameOpt2*/ + drv->setUniform2f(IDriver::PixelProgram, 0, 1.0f / fwidth, 1.0f / fheight); // fxaaQualityRcpFrame + drv->setUniform1f(IDriver::PixelProgram, 1, 0.75f); // fxaaQualitySubpix + drv->setUniform1f(IDriver::PixelProgram, 2, 0.166f); // fxaaQualityEdgeThreshold + drv->setUniform1f(IDriver::PixelProgram, 3, 0.0833f); // fxaaQualityEdgeThresholdMin drv->setUniformMatrix(IDriver::VertexProgram, 0, IDriver::ModelViewProjection, IDriver::Identity); - drv->setUniform4f(IDriver::VertexProgram, 9, -hpwidth, -hpheight, hpwidth, hpheight); + // drv->setUniform4f(IDriver::VertexProgram, 9, -hpwidth, -hpheight, hpwidth, hpheight); // render effect m_Mat.getObjectPtr()->setTexture(0, otherRenderTarget->getITexture()); diff --git a/code/nel/src/3d/fxaa_program.h b/code/nel/src/3d/fxaa_program.h index 6002a09a4..a6bf847ef 100644 --- a/code/nel/src/3d/fxaa_program.h +++ b/code/nel/src/3d/fxaa_program.h @@ -6,7 +6,7 @@ const char *a_nelvp = "DP4 o[HPOS].z, c[2], v[OPOS];\n" "DP4 o[HPOS].w, c[3], v[OPOS];\n" "MOV o[TEX0].xy, v[TEX0];\n" - "ADD o[TEX1], v[TEX0].xyxy, c[9];\n" + // "ADD o[TEX1], v[TEX0].xyxy, c[9];\n" "END\n"; const char *a_arbfp1_test = @@ -15,7 +15,310 @@ const char *a_arbfp1_test = "TEX result.color, fragment.texcoord[1].zwzw, texture[0], 2D;\n" "END\n"; -const char *a_arbfp1 = +const char *a_arbfp1 = + "!!ARBfp1.0\n" + "OPTION ARB_precision_hint_fastest;\n" + /*"# cgc version 3.1.0013, build date Apr 18 2012\n" + "# command line args: -profile arbfp1 -O3 -fastmath -fastprecision\n" + "# source file: fxaa_pp.cg\n" + "#vendor NVIDIA Corporation\n" + "#version 3.1.0.13\n" + "#profile arbfp1\n" + "#program fxaa_pp\n" + "#semantic fxaa_pp.fxaaQualityRcpFrame\n" + "#semantic fxaa_pp.fxaaQualitySubpix\n" + "#semantic fxaa_pp.fxaaQualityEdgeThreshold\n" + "#semantic fxaa_pp.fxaaQualityEdgeThresholdMin\n" + "#semantic fxaa_pp.nlTex0 : TEX0\n" + "#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n" + "#var float2 fxaaQualityRcpFrame : : c[0] : 2 : 1\n" + "#var float fxaaQualitySubpix : : c[1] : 3 : 1\n" + "#var float fxaaQualityEdgeThreshold : : c[2] : 4 : 1\n" + "#var float fxaaQualityEdgeThresholdMin : : c[3] : 5 : 1\n" + "#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1\n" + "#var float4 oCol : $vout.COLOR : COL : 7 : 1\n" + "#const c[4] = 0 -1 1 -2\n" + "#const c[5] = 2 0.5 0.25 1.5\n" + "#const c[6] = 4 12 0.083333336 3\n"*/ + "PARAM c[7] = { program.env[0..3],\n" + " { 0, -1, 1, -2 },\n" + " { 2, 0.5, 0.25, 1.5 },\n" + " { 4, 12, 0.083333336, 3 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "TEMP R2;\n" + "TEMP R3;\n" + "TEMP R4;\n" + "TEMP R5;\n" + "TEMP R6;\n" + "TEMP R7;\n" + "TEMP R8;\n" + "TEMP R9;\n" + "MOV R3.xyz, c[4];\n" + "MAD R2.zw, R3.xyyz, c[0].xyxy, fragment.texcoord[0].xyxy;\n" + "MAD R0.xy, R3, c[0], fragment.texcoord[0];\n" + "MAD R1.xy, R3.zyzw, c[0], fragment.texcoord[0];\n" + "TEX R5.y, R1, texture[0], 2D;\n" + "MAD R1.xy, R3.zxzw, c[0], fragment.texcoord[0];\n" + "ADD R0.zw, fragment.texcoord[0].xyxy, -c[0].xyxy;\n" + "TEX R4.y, R0.zwzw, texture[0], 2D;\n" + "TEX R6.y, R2.zwzw, texture[0], 2D;\n" + "TEX R8, fragment.texcoord[0], texture[0], 2D;\n" + "TEX R1.y, R1, texture[0], 2D;\n" + "TEX R0.y, R0, texture[0], 2D;\n" + "ADD R0.z, R4.y, R5.y;\n" + "MAD R1.z, R0.y, c[4].w, R0;\n" + "MAD R0.zw, R3.xyyx, c[0].xyxy, fragment.texcoord[0].xyxy;\n" + "TEX R2.y, R0.zwzw, texture[0], 2D;\n" + "ADD R0.x, R2.y, R1.y;\n" + "ABS R0.w, R1.z;\n" + "ADD R1.zw, fragment.texcoord[0].xyxy, c[0].xyxy;\n" + "TEX R7.y, R1.zwzw, texture[0], 2D;\n" + "MAD R0.z, R8.y, c[4].w, R0.x;\n" + "ABS R0.z, R0;\n" + "MAD R2.x, R0.z, c[5], R0.w;\n" + "MAD R0.zw, R3.xyxz, c[0].xyxy, fragment.texcoord[0].xyxy;\n" + "TEX R3.y, R0.zwzw, texture[0], 2D;\n" + "ADD R0.z, R0.y, R3.y;\n" + "ADD R1.x, R6.y, R7.y;\n" + "MAD R0.w, R3.y, c[4], R1.x;\n" + "MAD R1.x, R8.y, c[4].w, R0.z;\n" + "ABS R0.w, R0;\n" + "ADD R2.x, R0.w, R2;\n" + "ADD R2.w, R4.y, R6.y;\n" + "ADD R0.w, R5.y, R7.y;\n" + "ABS R1.z, R1.x;\n" + "MAD R1.x, R1.y, c[4].w, R0.w;\n" + "ABS R1.w, R1.x;\n" + "MAD R1.x, R2.y, c[4].w, R2.w;\n" + "MAD R1.z, R1, c[5].x, R1.w;\n" + "ABS R1.x, R1;\n" + "ADD R1.x, R1, R1.z;\n" + "SGE R4.x, R1, R2;\n" + "MAX R1.x, R3.y, R8.y;\n" + "MAX R1.z, R1.y, R1.x;\n" + "MAX R1.x, R0.y, R2.y;\n" + "MAX R1.x, R1, R1.z;\n" + "MIN R1.z, R3.y, R8.y;\n" + "MIN R1.w, R1.y, R1.z;\n" + "MIN R1.z, R0.y, R2.y;\n" + "MIN R1.z, R1, R1.w;\n" + "MUL R2.x, R1, c[2];\n" + "ADD R3.z, R1.x, -R1;\n" + "ABS R3.w, R4.x;\n" + "MAX R1.w, R2.x, c[3].x;\n" + "ADD R2.z, R3, -R1.w;\n" + "CMP R2.x, R2.z, c[4], c[4].z;\n" + "CMP R1.x, -R3.w, c[4], c[4].z;\n" + "MUL R3.w, R2.x, R1.x;\n" + "CMP R1.z, -R3.w, R1.y, R3.y;\n" + "ADD R1.y, -R8, R1.z;\n" + "CMP R1.w, -R3, R2.y, R0.y;\n" + "ADD R0.y, -R8, R1.w;\n" + "MUL R4.x, R2, R4;\n" + "CMP R3.y, -R3.w, c[0], R3.x;\n" + "ABS R4.w, R1.y;\n" + "ABS R4.z, R0.y;\n" + "SGE R0.y, R4.z, R4.w;\n" + "MUL R1.y, R2.x, R0;\n" + "ABS R0.y, R0;\n" + "CMP R4.y, -R0, c[4].x, c[4].z;\n" + "ABS R0.y, R1.x;\n" + "CMP R0.y, -R0, c[4].x, c[4].z;\n" + "MUL R1.x, R2, R0.y;\n" + "CMP R2.y, -R4.x, c[0], c[0].x;\n" + "CMP R2.y, -R1, -R2, R2;\n" + "MAD R1.y, R2, c[5], fragment.texcoord[0];\n" + "CMP R5.z, -R4.x, R1.y, fragment.texcoord[0].y;\n" + "ADD R5.y, R5.z, -R3;\n" + "MAD R0.y, R2, c[5], fragment.texcoord[0].x;\n" + "CMP R3.x, -R1, c[0], R3;\n" + "CMP R6.x, -R3.w, R0.y, fragment.texcoord[0];\n" + "ADD R5.w, R5.z, R3.y;\n" + "ADD R1.x, R6, -R3;\n" + "MOV R1.y, R5;\n" + "TEX R0.y, R1, texture[0], 2D;\n" + "MUL R1.y, R2.x, R4;\n" + "ADD R0.x, R0.z, R0;\n" + "ADD R0.w, R2, R0;\n" + "MAD R0.z, R0.x, c[5].x, R0.w;\n" + "ADD R1.w, R8.y, R1;\n" + "ADD R1.z, R8.y, R1;\n" + "CMP R4.y, -R1, R1.z, R1.w;\n" + "ADD R1.z, R6.x, R3.x;\n" + "MAD R5.x, -R4.y, c[5].y, R0.y;\n" + "MOV R1.w, R5;\n" + "TEX R0.y, R1.zwzw, texture[0], 2D;\n" + "MAX R1.w, R4.z, R4;\n" + "MAD R1.y, -R4, c[5], R0;\n" + "MUL R4.z, R1.w, c[5];\n" + "ABS R0.y, R1;\n" + "SGE R1.w, R0.y, R4.z;\n" + "ABS R6.y, R5.x;\n" + "SGE R0.y, R6, R4.z;\n" + "ABS R1.w, R1;\n" + "CMP R6.y, -R1.w, c[4].x, c[4].z;\n" + "ABS R0.y, R0;\n" + "CMP R5.z, -R0.y, c[4].x, c[4];\n" + "ADD_SAT R0.y, R5.z, R6;\n" + "MUL R4.w, R2.x, R0.y;\n" + "MUL R0.y, R2.x, R6;\n" + "MAD R1.w, R3.y, c[5], R5;\n" + "CMP R6.x, -R0.y, R1.w, R5.w;\n" + "MAD R6.z, R3.x, c[5].w, R1;\n" + "CMP R1.z, -R0.y, R6, R1;\n" + "MOV R1.w, R6.x;\n" + "TEX R0.y, R1.zwzw, texture[0], 2D;\n" + "MUL R1.w, R4, R6.y;\n" + "CMP R6.y, -R1.w, R0, R1;\n" + "MUL R0.y, R2.x, R5.z;\n" + "MAD R1.y, -R3, c[5].w, R5;\n" + "CMP R5.w, -R0.y, R1.y, R5.y;\n" + "MAD R6.z, -R3.x, c[5].w, R1.x;\n" + "CMP R1.x, -R0.y, R6.z, R1;\n" + "MOV R1.y, R5.w;\n" + "TEX R0.y, R1, texture[0], 2D;\n" + "MUL R5.y, R4.w, R5.z;\n" + "CMP R0.y, -R5, R0, R5.x;\n" + "MAD R5.x, -R4.y, c[5].y, R0.y;\n" + "CMP R5.z, -R5.y, R5.x, R0.y;\n" + "MAD R1.y, -R4, c[5], R6;\n" + "CMP R1.y, -R1.w, R1, R6;\n" + "ABS R1.w, R1.y;\n" + "SGE R1.w, R1, R4.z;\n" + "ABS R0.y, R5.z;\n" + "SGE R0.y, R0, R4.z;\n" + "ABS R1.w, R1;\n" + "CMP R6.y, -R1.w, c[4].x, c[4].z;\n" + "ABS R0.y, R0;\n" + "CMP R5.y, -R0, c[4].x, c[4].z;\n" + "ADD_SAT R0.y, R5, R6;\n" + "MUL R5.x, R4.w, R0.y;\n" + "MUL R0.y, R4.w, R6;\n" + "MAD R1.w, R3.y, c[5].x, R6.x;\n" + "CMP R6.x, -R0.y, R1.w, R6;\n" + "MAD R6.z, R3.x, c[5].x, R1;\n" + "CMP R1.z, -R0.y, R6, R1;\n" + "MOV R1.w, R6.x;\n" + "TEX R0.y, R1.zwzw, texture[0], 2D;\n" + "MUL R1.w, R5.x, R6.y;\n" + "CMP R6.y, -R1.w, R0, R1;\n" + "MUL R0.y, R4.w, R5;\n" + "MAD R1.y, -R3, c[5].x, R5.w;\n" + "CMP R4.w, -R0.y, R1.y, R5;\n" + "MAD R6.z, -R3.x, c[5].x, R1.x;\n" + "CMP R1.x, -R0.y, R6.z, R1;\n" + "MOV R1.y, R4.w;\n" + "TEX R0.y, R1, texture[0], 2D;\n" + "MUL R5.y, R5.x, R5;\n" + "CMP R0.y, -R5, R0, R5.z;\n" + "MAD R5.z, -R4.y, c[5].y, R0.y;\n" + "CMP R5.w, -R5.y, R5.z, R0.y;\n" + "MAD R1.y, -R4, c[5], R6;\n" + "CMP R1.y, -R1.w, R1, R6;\n" + "ABS R1.w, R1.y;\n" + "SGE R1.w, R1, R4.z;\n" + "ABS R1.w, R1;\n" + "CMP R6.y, -R1.w, c[4].x, c[4].z;\n" + "ABS R0.y, R5.w;\n" + "SGE R0.y, R0, R4.z;\n" + "ABS R0.y, R0;\n" + "CMP R5.y, -R0, c[4].x, c[4].z;\n" + "ADD_SAT R0.y, R5, R6;\n" + "MUL R5.z, R5.x, R0.y;\n" + "MUL R0.y, R5.x, R6;\n" + "MAD R1.w, R3.y, c[6].x, R6.x;\n" + "CMP R6.x, -R0.y, R1.w, R6;\n" + "MAD R6.z, R3.x, c[6].x, R1;\n" + "CMP R1.z, -R0.y, R6, R1;\n" + "MOV R1.w, R6.x;\n" + "TEX R0.y, R1.zwzw, texture[0], 2D;\n" + "MUL R1.w, R5.z, R6.y;\n" + "CMP R6.y, -R1.w, R0, R1;\n" + "MUL R0.y, R5.x, R5;\n" + "MAD R1.y, -R3, c[6].x, R4.w;\n" + "CMP R4.w, -R0.y, R1.y, R4;\n" + "MAD R5.x, -R3, c[6], R1;\n" + "CMP R1.x, -R0.y, R5, R1;\n" + "MOV R1.y, R4.w;\n" + "TEX R0.y, R1, texture[0], 2D;\n" + "MUL R1.y, R5.z, R5;\n" + "CMP R5.x, -R1.y, R0.y, R5.w;\n" + "MAD R5.y, -R4, c[5], R5.x;\n" + "CMP R1.y, -R1, R5, R5.x;\n" + "MAD R0.y, -R4, c[5], R6;\n" + "CMP R0.y, -R1.w, R0, R6;\n" + "ABS R5.x, R0.y;\n" + "ABS R1.w, R1.y;\n" + "SGE R1.w, R1, R4.z;\n" + "SGE R5.x, R5, R4.z;\n" + "ABS R4.z, R5.x;\n" + "ABS R1.w, R1;\n" + "CMP R4.z, -R4, c[4].x, c[4];\n" + "CMP R1.w, -R1, c[4].x, c[4].z;\n" + "MUL R4.z, R5, R4;\n" + "MAD R5.y, R3.x, c[6], R1.z;\n" + "CMP R5.y, -R4.z, R5, R1.z;\n" + "MAD R5.x, R3.y, c[6].y, R6;\n" + "CMP R1.z, -R4, R5.x, R6.x;\n" + "MUL R1.w, R5.z, R1;\n" + "ADD R4.z, -fragment.texcoord[0].x, R5.y;\n" + "ADD R1.z, -fragment.texcoord[0].y, R1;\n" + "CMP R1.z, -R3.w, R1, R4;\n" + "MAD R4.z, -R3.x, c[6].y, R1.x;\n" + "MAD R3.x, -R3.y, c[6].y, R4.w;\n" + "CMP R3.y, -R1.w, R4.z, R1.x;\n" + "CMP R1.x, -R1.w, R3, R4.w;\n" + "ADD R1.w, fragment.texcoord[0].x, -R3.y;\n" + "ADD R1.x, fragment.texcoord[0].y, -R1;\n" + "CMP R1.x, -R3.w, R1, R1.w;\n" + "SLT R1.w, R1.x, R1.z;\n" + "ADD R3.x, R1, R1.z;\n" + "ABS R1.w, R1;\n" + "MIN R1.x, R1, R1.z;\n" + "CMP R1.w, -R1, c[4].x, c[4].z;\n" + "MUL R1.z, R2.x, R1.w;\n" + "RCP R3.x, R3.x;\n" + "MAD R1.x, R1, -R3, c[5].y;\n" + "MUL R1.w, R4.y, c[5].y;\n" + "SLT R3.x, R1.y, c[4];\n" + "SLT R1.y, R8, R1.w;\n" + "SLT R0.y, R0, c[4].x;\n" + "ADD R0.y, R0, -R1;\n" + "ADD R1.y, -R1, R3.x;\n" + "ABS R0.y, R0;\n" + "ABS R1.y, R1;\n" + "CMP R0.y, -R0, c[4].z, c[4].x;\n" + "CMP R1.y, -R1, c[4].z, c[4].x;\n" + "CMP R0.x, -R1.z, R0.y, R1.y;\n" + "MAD R0.y, R0.z, c[6].z, -R8;\n" + "ABS R0.x, R0;\n" + "CMP R0.x, -R0, c[4], c[4].z;\n" + "MUL R0.x, R2, R0;\n" + "CMP R0.x, -R0, c[4], R1;\n" + "RCP R0.z, R3.z;\n" + "ABS R0.y, R0;\n" + "MUL_SAT R0.y, R0, R0.z;\n" + "MUL R0.z, R0.y, c[4].w;\n" + "ADD R0.z, R0, c[6].w;\n" + "MUL R0.y, R0, R0;\n" + "MUL R0.y, R0.z, R0;\n" + "MUL R0.y, R0, R0;\n" + "MUL R0.y, R0, c[1].x;\n" + "MAX R0.x, R0, R0.y;\n" + "MAD R0.y, R0.x, R2, fragment.texcoord[0];\n" + "MAD R0.z, R0.x, R2.y, fragment.texcoord[0].x;\n" + "CMP R0.x, -R3.w, R0.z, fragment.texcoord[0];\n" + "CMP R0.y, -R4.x, R0, fragment.texcoord[0];\n" + "TEX R0.xyz, R0, texture[0], 2D;\n" + "CMP R1, R2.z, R8, R9;\n" + "MOV R0.w, R8.y;\n" + "CMP result.color, -R2.x, R0, R1;\n" + "END\n"; + /*"# 260 instructions, 10 R-regs\n" + "\n"*/ + +const char *a_arbfp1_ps3 = "!!ARBfp1.0\n" "OPTION ARB_precision_hint_fastest;\n" //# cgc version 3.1.0013, build date Apr 18 2012 @@ -203,7 +506,315 @@ const char *a_ps_2_0_test_avg = "mul r0, r0, c0.x\n" "mov oC0, r0\n"; -const char *a_ps_2_0 = +const char *a_ps_2_0 = + "ps_2_x\n" + /*"// cgc version 3.1.0013, build date Apr 18 2012\n" + "// command line args: -profile ps_2_x -O3 -fastmath -fastprecision\n" + "// source file: fxaa_pp.cg\n" + "//vendor NVIDIA Corporation\n" + "//version 3.1.0.13\n" + "//profile ps_2_x\n" + "//program fxaa_pp\n" + "//semantic fxaa_pp.fxaaQualityRcpFrame\n" + "//semantic fxaa_pp.fxaaQualitySubpix\n" + "//semantic fxaa_pp.fxaaQualityEdgeThreshold\n" + "//semantic fxaa_pp.fxaaQualityEdgeThresholdMin\n" + "//semantic fxaa_pp.nlTex0 : TEX0\n" + "//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n" + "//var float2 fxaaQualityRcpFrame : : c[0] : 2 : 1\n" + "//var float fxaaQualitySubpix : : c[1] : 3 : 1\n" + "//var float fxaaQualityEdgeThreshold : : c[2] : 4 : 1\n" + "//var float fxaaQualityEdgeThresholdMin : : c[3] : 5 : 1\n" + "//var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1\n" + "//var float4 oCol : $vout.COLOR : COL : 7 : 1\n" + "//const c[4] = 0 -1 1 -2\n" + "//const c[5] = 2 0.5 0.25 1.5\n" + "//const c[6] = 4 12 0.083333336\n" + "//const c[7] = -2 3\n"*/ + "dcl_2d s0\n" + "def c4, 0.00000000, -1.00000000, 1.00000000, -2.00000000\n" + "def c5, 2.00000000, 0.50000000, 0.25000000, 1.50000000\n" + "def c6, 4.00000000, 12.00000000, 0.08333334, 0\n" + "def c7, -2.00000000, 3.00000000, 0, 0\n" + "dcl t0.xy\n" + "mov r0.zw, c0.xyxy\n" + "mad r3.xy, c4.zxzw, r0.zwzw, t0\n" + "texld r7, r3, s0\n" + "texld r1, t0, s0\n" + "mov r0.xy, c0\n" + "mad r0.xy, c4.yxzw, r0, t0\n" + "texld r8, r0, s0\n" + "mov r0.xy, c0\n" + "mad r0.xy, c4, r0, t0\n" + "texld r9, r0, s0\n" + "add r0.xy, t0, -c0\n" + "texld r5, r0, s0\n" + "mov r3.xy, c0\n" + "mad r3.xy, c4.zyzw, r3, t0\n" + "texld r3, r3, s0\n" + "add r7.x, r8.y, r7.y\n" + "mad r0.z, r1.y, c4.w, r7.x\n" + "add r0.x, r5.y, r3.y\n" + "mad r0.w, r9.y, c4, r0.x\n" + "mov r0.xy, c0\n" + "mad r0.xy, c4.xzzw, r0, t0\n" + "texld r6, r0, s0\n" + "add r5.x, r9.y, r6.y\n" + "abs r0.z, r0\n" + "abs r0.w, r0\n" + "mad r3.x, r0.z, c5, r0.w\n" + "mov r0.zw, c0.xyxy\n" + "mad r4.xy, c4.yzzw, r0.zwzw, t0\n" + "texld r4, r4, s0\n" + "add r0.xy, t0, c0\n" + "texld r0, r0, s0\n" + "add r4.x, r5.y, r4.y\n" + "add r5.y, r3, r0\n" + "add r0.x, r4.y, r0.y\n" + "mad r0.x, r6.y, c4.w, r0\n" + "abs r0.x, r0\n" + "add r0.w, r0.x, r3.x\n" + "mad r0.x, r8.y, c4.w, r4\n" + "mad r0.z, r7.y, c4.w, r5.y\n" + "mad r0.y, r1, c4.w, r5.x\n" + "abs r0.z, r0\n" + "abs r0.y, r0\n" + "mad r0.y, r0, c5.x, r0.z\n" + "abs r0.x, r0\n" + "add r0.x, r0, r0.y\n" + "add r0.x, r0, -r0.w\n" + "cmp r3.y, r0.x, c4.z, c4.x\n" + "max r0.y, r6, r1\n" + "max r0.z, r7.y, r0.y\n" + "max r0.y, r9, r8\n" + "max r0.y, r0, r0.z\n" + "min r0.z, r6.y, r1.y\n" + "min r0.w, r7.y, r0.z\n" + "min r0.z, r9.y, r8.y\n" + "min r0.z, r0, r0.w\n" + "mul r3.x, r0.y, c2\n" + "abs_pp r0.x, r3.y\n" + "add r4.y, r0, -r0.z\n" + "max r0.w, r3.x, c3.x\n" + "add r4.z, r4.y, -r0.w\n" + "cmp_pp r4.w, r4.z, c4.z, c4.x\n" + "mul_pp r5.w, r4, r3.y\n" + "cmp_pp r0.y, -r0.x, c4.z, c4.x\n" + "mul_pp r5.z, r4.w, r0.y\n" + "cmp_pp r3.x, -r0, c4, c4.z\n" + "cmp r6.w, -r5.z, r6.y, r7.y\n" + "cmp r7.w, -r5.z, r9.y, r8.y\n" + "add r0.z, -r1.y, r6.w\n" + "add r0.y, -r1, r7.w\n" + "abs r9.z, r0\n" + "abs r7.y, r0\n" + "add r0.y, r7, -r9.z\n" + "cmp r0.y, r0, c4.z, c4.x\n" + "max r7.y, r7, r9.z\n" + "mul_pp r0.z, r4.w, r0.y\n" + "cmp r0.w, -r5, c0.x, c0.y\n" + "cmp r6.x, -r0.z, r0.w, -r0.w\n" + "mov r0.z, c0.y\n" + "cmp r6.y, -r5.z, c4.x, r0.z\n" + "mad r0.w, r6.x, c5.y, t0.y\n" + "cmp r0.z, -r5.w, t0.y, r0.w\n" + "add r8.z, r0, r6.y\n" + "add r7.z, r0, -r6.y\n" + "mov r9.y, r7.z\n" + "mov r8.y, r8.z\n" + "mad r0.w, r6.x, c5.y, t0.x\n" + "mov r0.x, c0\n" + "mul_pp r3.x, r4.w, r3\n" + "cmp r6.z, -r3.x, c4.x, r0.x\n" + "cmp r0.x, -r5.z, t0, r0.w\n" + "add r9.x, r0, -r6.z\n" + "texld r3, r9, s0\n" + "add r8.x, r0, r6.z\n" + "abs_pp r3.x, r0.y\n" + "texld r0, r8, s0\n" + "cmp_pp r0.x, -r3, c4.z, c4\n" + "add r0.w, r1.y, r6\n" + "add r0.z, r1.y, r7.w\n" + "mul_pp r0.x, r4.w, r0\n" + "cmp r6.w, -r0.x, r0.z, r0\n" + "mad r7.w, -r6, c5.y, r0.y\n" + "mad r8.w, -r6, c5.y, r3.y\n" + "abs r0.y, r7.w\n" + "abs r0.x, r8.w\n" + "mad r0.x, -r7.y, c5.z, r0\n" + "mad r0.y, -r7, c5.z, r0\n" + "cmp r0.x, r0, c4.z, c4\n" + "abs_pp r0.x, r0\n" + "cmp_pp r9.z, -r0.x, c4, c4.x\n" + "cmp r0.y, r0, c4.z, c4.x\n" + "abs_pp r0.y, r0\n" + "cmp_pp r9.w, -r0.y, c4.z, c4.x\n" + "mul_pp r0.x, r4.w, r9.z\n" + "mad r0.y, -r6, c5.w, r7.z\n" + "cmp r7.z, -r0.x, r7, r0.y\n" + "mad r0.z, -r6, c5.w, r9.x\n" + "cmp r9.x, -r0, r9, r0.z\n" + "mov r9.y, r7.z\n" + "texld r3, r9, s0\n" + "add_pp_sat r3.z, r9, r9.w\n" + "mul_pp r0.x, r4.w, r9.w\n" + "mad r0.y, r6, c5.w, r8.z\n" + "cmp r3.x, -r0, r8.z, r0.y\n" + "mad r0.z, r6, c5.w, r8.x\n" + "mul_pp r8.z, r4.w, r3\n" + "cmp r8.x, -r0, r8, r0.z\n" + "mov r8.y, r3.x\n" + "texld r0, r8, s0\n" + "mul_pp r0.w, r8.z, r9\n" + "cmp r3.z, -r0.w, r7.w, r0.y\n" + "mul_pp r0.x, r8.z, r9.z\n" + "cmp r0.y, -r0.x, r8.w, r3\n" + "mad r0.z, -r6.w, c5.y, r0.y\n" + "cmp r8.w, -r0.x, r0.y, r0.z\n" + "mad r3.y, -r6.w, c5, r3.z\n" + "cmp r9.w, -r0, r3.z, r3.y\n" + "abs r0.y, r9.w\n" + "abs r0.x, r8.w\n" + "mad r0.y, -r7, c5.z, r0\n" + "mad r0.x, -r7.y, c5.z, r0\n" + "cmp r0.y, r0, c4.z, c4.x\n" + "abs_pp r0.y, r0\n" + "cmp_pp r10.x, -r0.y, c4.z, c4\n" + "cmp r0.x, r0, c4.z, c4\n" + "abs_pp r0.x, r0\n" + "cmp_pp r9.z, -r0.x, c4, c4.x\n" + "mul_pp r0.x, r8.z, r10\n" + "mad r0.y, r6, c5.x, r3.x\n" + "cmp r7.w, -r0.x, r3.x, r0.y\n" + "mad r0.z, r6, c5.x, r8.x\n" + "cmp r8.x, -r0, r8, r0.z\n" + "mov r8.y, r7.w\n" + "texld r0, r8, s0\n" + "mul_pp r0.w, r8.z, r9.z\n" + "mad r3.x, -r6.z, c5, r9\n" + "mad r0.x, -r6.y, c5, r7.z\n" + "cmp r0.x, -r0.w, r7.z, r0\n" + "add_pp_sat r0.z, r9, r10.x\n" + "mul_pp r7.z, r8, r0\n" + "cmp r9.x, -r0.w, r9, r3\n" + "mov r9.y, r0.x\n" + "texld r3, r9, s0\n" + "mul_pp r0.z, r7, r9\n" + "cmp r0.w, -r0.z, r8, r3.y\n" + "mul_pp r3.x, r7.z, r10\n" + "cmp r3.y, -r3.x, r9.w, r0\n" + "mad r0.y, -r6.w, c5, r0.w\n" + "cmp r8.z, -r0, r0.w, r0.y\n" + "mad r3.z, -r6.w, c5.y, r3.y\n" + "cmp r9.z, -r3.x, r3.y, r3\n" + "abs r0.y, r8.z\n" + "abs r0.z, r9\n" + "mad r0.y, -r7, c5.z, r0\n" + "mad r0.z, -r7.y, c5, r0\n" + "cmp r0.y, r0, c4.z, c4.x\n" + "abs_pp r0.y, r0\n" + "cmp_pp r8.w, -r0.y, c4.z, c4.x\n" + "cmp r0.z, r0, c4, c4.x\n" + "abs_pp r0.z, r0\n" + "cmp_pp r9.w, -r0.z, c4.z, c4.x\n" + "mul_pp r0.y, r7.z, r8.w\n" + "mad r0.z, -r6.y, c6.x, r0.x\n" + "cmp r10.x, -r0.y, r0, r0.z\n" + "mad r0.w, -r6.z, c6.x, r9.x\n" + "cmp r9.x, -r0.y, r9, r0.w\n" + "mov r9.y, r10.x\n" + "texld r3, r9, s0\n" + "mul_pp r0.x, r7.z, r9.w\n" + "mad r0.z, r6, c6.x, r8.x\n" + "mad r0.y, r6, c6.x, r7.w\n" + "cmp r3.x, -r0, r7.w, r0.y\n" + "cmp r8.x, -r0, r8, r0.z\n" + "mov r8.y, r3.x\n" + "texld r0, r8, s0\n" + "add_pp_sat r3.z, r8.w, r9.w\n" + "mul_pp r0.x, r7.z, r3.z\n" + "mul_pp r3.z, r0.x, r9.w\n" + "cmp r0.y, -r3.z, r9.z, r0\n" + "mul_pp r0.z, r0.x, r8.w\n" + "cmp r0.w, -r0.z, r8.z, r3.y\n" + "mad r3.w, -r6, c5.y, r0.y\n" + "cmp r0.y, -r3.z, r0, r3.w\n" + "mad r3.y, -r6.w, c5, r0.w\n" + "cmp r0.z, -r0, r0.w, r3.y\n" + "abs r3.y, r0\n" + "abs r0.w, r0.z\n" + "mad r3.y, -r7, c5.z, r3\n" + "mad r0.w, -r7.y, c5.z, r0\n" + "cmp r3.y, r3, c4.z, c4.x\n" + "abs_pp r3.y, r3\n" + "cmp r0.w, r0, c4.z, c4.x\n" + "cmp_pp r3.z, -r3.y, c4, c4.x\n" + "abs_pp r0.w, r0\n" + "cmp_pp r3.y, -r0.w, c4.z, c4.x\n" + "mul_pp r0.w, r0.x, r3.z\n" + "mul_pp r0.x, r0, r3.y\n" + "mad r3.w, r6.y, c6.y, r3.x\n" + "cmp r3.x, -r0.w, r3, r3.w\n" + "mad r3.z, r6, c6.y, r8.x\n" + "cmp r0.w, -r0, r8.x, r3.z\n" + "mad r3.y, -r6, c6, r10.x\n" + "cmp r3.y, -r0.x, r10.x, r3\n" + "add r3.x, -t0.y, r3\n" + "add r0.w, -t0.x, r0\n" + "cmp r0.w, -r5.z, r0, r3.x\n" + "mad r3.x, -r6.z, c6.y, r9\n" + "cmp r0.x, -r0, r9, r3\n" + "add r3.x, t0.y, -r3.y\n" + "add r0.x, t0, -r0\n" + "cmp r0.x, -r5.z, r0, r3\n" + "add r3.x, r0, -r0.w\n" + "add r3.y, r0.x, r0.w\n" + "cmp r3.x, r3, c4, c4.z\n" + "abs_pp r3.x, r3\n" + "min r0.x, r0, r0.w\n" + "cmp_pp r3.x, -r3, c4.z, c4\n" + "mul_pp r0.w, r4, r3.x\n" + "rcp r3.y, r3.y\n" + "mad r0.x, r0, -r3.y, c5.y\n" + "cmp r3.y, r0, c4.x, c4.z\n" + "mad r3.x, -r6.w, c5.y, r1.y\n" + "cmp r3.x, r3, c4, c4.z\n" + "cmp r0.y, r0.z, c4.x, c4.z\n" + "add_pp r0.z, -r3.x, r3.y\n" + "add_pp r0.y, r0, -r3.x\n" + "abs_pp r0.y, r0\n" + "abs_pp r0.z, r0\n" + "cmp_pp r0.z, -r0, c4.x, c4\n" + "cmp_pp r0.y, -r0, c4.x, c4.z\n" + "cmp_pp r0.y, -r0.w, r0, r0.z\n" + "abs_pp r0.y, r0\n" + "cmp_pp r0.y, -r0, c4.z, c4.x\n" + "mul_pp r0.y, r4.w, r0\n" + "rcp r0.w, r4.y\n" + "cmp r0.x, -r0.y, r0, c4\n" + "add r3.y, r4.x, r5\n" + "add r3.x, r5, r7\n" + "mad r3.x, r3, c5, r3.y\n" + "mad r0.z, r3.x, c6, -r1.y\n" + "abs r0.z, r0\n" + "mul_sat r0.z, r0, r0.w\n" + "mul r0.w, r0.z, r0.z\n" + "mad r0.z, r0, c7.x, c7.y\n" + "mul r0.z, r0, r0.w\n" + "mul r0.z, r0, r0\n" + "mul r0.z, r0, c1.x\n" + "max r0.x, r0, r0.z\n" + "mad r0.y, r0.x, r6.x, t0\n" + "mad r0.z, r0.x, r6.x, t0.x\n" + "cmp r0.x, -r5.z, t0, r0.z\n" + "cmp r0.y, -r5.w, t0, r0\n" + "texld r0, r0, s0\n" + "mov r0.w, r1.y\n" + "cmp r1, r4.z, r2, r1\n" + "cmp r0, -r4.w, r1, r0\n" + "mov oC0, r0\n"; + +const char *a_ps_2_0_ps3 = "ps_2_0\n" // cgc version 3.1.0013, build date Apr 18 2012 // command line args: -profile ps_2_0 -O3 -fastmath -fastprecision diff --git a/code/nel/src/3d/shaders/compile.bat b/code/nel/src/3d/shaders/compile.bat index a1d660d9d..06306a0da 100644 --- a/code/nel/src/3d/shaders/compile.bat +++ b/code/nel/src/3d/shaders/compile.bat @@ -1,3 +1,3 @@ cgc -entry fxaa_pp fxaa_pp.cg -profile arbfp1 -O3 -fastmath -fastprecision -o fxaa_pp_arbfp1.txt -cgc -entry fxaa_pp fxaa_pp.cg -profile ps_2_0 -O3 -fastmath -fastprecision -o fxaa_pp_ps_2_0.txt +cgc -entry fxaa_pp fxaa_pp.cg -profile ps_2_x -O3 -fastmath -fastprecision -o fxaa_pp_ps_2_0.txt cgc -entry fxaa_vp fxaa_vp.cg -profile arbvp1 -fastmath -fastprecision -o fxaa_vp_arbvp1.txt \ No newline at end of file diff --git a/code/nel/src/3d/shaders/fxaa3_11.h b/code/nel/src/3d/shaders/fxaa3_11.h index 0443fd6e2..7cdc32c70 100644 --- a/code/nel/src/3d/shaders/fxaa3_11.h +++ b/code/nel/src/3d/shaders/fxaa3_11.h @@ -695,7 +695,11 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; }; #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) #endif - + +#undef FxaaTexTop +#define FxaaTexTop(t, p) tex2D(t, p) +#undef FxaaTexOff +#define FxaaTexOff(t, p, o, r) tex2D(t, p + (o * r)) /*============================================================================ GREEN AS LUMA OPTION SUPPORT FUNCTION @@ -726,7 +730,7 @@ FxaaFloat2 pos, // Use noperspective interpolation here (turn off perspective interpolation). // {xy__} = upper left of pixel // {__zw} = lower right of pixel -FxaaFloat4 fxaaConsolePosPos, +//FxaaFloat4 fxaaConsolePosPos, // // Input color texture. // {rgb_} = color in linear or perceptual color space @@ -738,13 +742,13 @@ FxaaTex tex, // For everything but 360, just use the same input here as for "tex". // For 360, same texture, just alias with a 2nd sampler. // This sampler needs to have an exponent bias of -1. -FxaaTex fxaaConsole360TexExpBiasNegOne, +//FxaaTex fxaaConsole360TexExpBiasNegOne, // // Only used on the optimized 360 version of FXAA Console. // For everything but 360, just use the same input here as for "tex". // For 360, same texture, just alias with a 3nd sampler. // This sampler needs to have an exponent bias of -2. -FxaaTex fxaaConsole360TexExpBiasNegTwo, +//FxaaTex fxaaConsole360TexExpBiasNegTwo, // // Only used on FXAA Quality. // This must be from a constant/uniform. @@ -762,7 +766,7 @@ FxaaFloat2 fxaaQualityRcpFrame, // {_y__} = -N/screenHeightInPixels // {__z_} = N/screenWidthInPixels // {___w} = N/screenHeightInPixels -FxaaFloat4 fxaaConsoleRcpFrameOpt, +//FxaaFloat4 fxaaConsoleRcpFrameOpt, // // Only used on FXAA Console. // Not used on 360, but used on PS3 and PC. @@ -771,7 +775,7 @@ FxaaFloat4 fxaaConsoleRcpFrameOpt, // {_y__} = -2.0/screenHeightInPixels // {__z_} = 2.0/screenWidthInPixels // {___w} = 2.0/screenHeightInPixels -FxaaFloat4 fxaaConsoleRcpFrameOpt2, +//FxaaFloat4 fxaaConsoleRcpFrameOpt2, // // Only used on FXAA Console. // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. @@ -780,7 +784,7 @@ FxaaFloat4 fxaaConsoleRcpFrameOpt2, // {_y__} = 8.0/screenHeightInPixels // {__z_} = -4.0/screenWidthInPixels // {___w} = -4.0/screenHeightInPixels -FxaaFloat4 fxaaConsole360RcpFrameOpt2, +//FxaaFloat4 fxaaConsole360RcpFrameOpt2, // // Only used on FXAA Quality. // This used to be the FXAA_QUALITY__SUBPIX define. @@ -818,7 +822,7 @@ FxaaFloat fxaaQualityEdgeThreshold, // will appear very dark in the green channel! // Tune by looking at mostly non-green content, // then start at zero and increase until aliasing is a problem. -FxaaFloat fxaaQualityEdgeThresholdMin, +FxaaFloat fxaaQualityEdgeThresholdMin // // Only used on FXAA Console. // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. @@ -832,7 +836,7 @@ FxaaFloat fxaaQualityEdgeThresholdMin, // 8.0 is sharper (default!!!) // 4.0 is softer // 2.0 is really soft (good only for vector graphics inputs) -FxaaFloat fxaaConsoleEdgeSharpness, +//FxaaFloat fxaaConsoleEdgeSharpness, // // Only used on FXAA Console. // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. @@ -846,7 +850,7 @@ FxaaFloat fxaaConsoleEdgeSharpness, // Other platforms can use other values. // 0.125 leaves less aliasing, but is softer (default!!!) // 0.25 leaves more aliasing, and is sharper -FxaaFloat fxaaConsoleEdgeThreshold, +//FxaaFloat fxaaConsoleEdgeThreshold, // // Only used on FXAA Console. // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. @@ -865,14 +869,14 @@ FxaaFloat fxaaConsoleEdgeThreshold, // will appear very dark in the green channel! // Tune by looking at mostly non-green content, // then start at zero and increase until aliasing is a problem. -FxaaFloat fxaaConsoleEdgeThresholdMin, +//FxaaFloat fxaaConsoleEdgeThresholdMin, // // Extra constants for 360 FXAA Console only. // Use zeros or anything else for other platforms. // These must be in physical constant registers and NOT immedates. // Immedates will result in compiler un-optimizing. // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) -FxaaFloat4 fxaaConsole360ConstDir +//FxaaFloat4 fxaaConsole360ConstDir ) { /*--------------------------------------------------------------------------*/ FxaaFloat2 posM; diff --git a/code/nel/src/3d/shaders/fxaa_pp.cg b/code/nel/src/3d/shaders/fxaa_pp.cg index e4993ead8..49622f206 100644 --- a/code/nel/src/3d/shaders/fxaa_pp.cg +++ b/code/nel/src/3d/shaders/fxaa_pp.cg @@ -1,8 +1,9 @@ -#define FXAA_PS3 1 +#define FXAA_PC 1 #define FXAA_HLSL_3 1 #define FXAA_QUALITY__PRESET 12 #define FXAA_EARLY_EXIT 0 +#define FXAA_GREEN_AS_LUMA 1 #define h4tex2Dlod tex2Dlod #define half4 float4 @@ -15,17 +16,36 @@ void fxaa_pp( // Per fragment parameters float2 pos : TEXCOORD0, +#if (FXAA_PS3 == 1) float4 fxaaConsolePosPos : TEXCOORD1, +#endif // Fragment program constants +#if (FXAA_PC == 1) + uniform float2 fxaaQualityRcpFrame, + uniform float fxaaQualitySubpix, + uniform float fxaaQualityEdgeThreshold, + uniform float fxaaQualityEdgeThresholdMin, +#else uniform float4 fxaaConsoleRcpFrameOpt, uniform float4 fxaaConsoleRcpFrameOpt2, +#endif uniform sampler2D nlTex0 : TEX0, // Output color out float4 oCol : COLOR ) { +#if (FXAA_PC == 1) + oCol = FxaaPixelShader( + pos, + nlTex0, + fxaaQualityRcpFrame, + fxaaQualitySubpix, + fxaaQualityEdgeThreshold, + fxaaQualityEdgeThresholdMin + ); +#else oCol = FxaaPixelShader( pos, fxaaConsolePosPos, @@ -33,6 +53,7 @@ void fxaa_pp( fxaaConsoleRcpFrameOpt, fxaaConsoleRcpFrameOpt2 ); +#endif } /* diff --git a/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt b/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt index 73ecb767c..5a498ed61 100644 --- a/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt +++ b/code/nel/src/3d/shaders/fxaa_pp_arbfp1.txt @@ -7,70 +7,294 @@ OPTION ARB_precision_hint_fastest; #version 3.1.0.13 #profile arbfp1 #program fxaa_pp -#semantic fxaa_pp.fxaaConsoleRcpFrameOpt -#semantic fxaa_pp.fxaaConsoleRcpFrameOpt2 +#semantic fxaa_pp.fxaaQualityRcpFrame +#semantic fxaa_pp.fxaaQualitySubpix +#semantic fxaa_pp.fxaaQualityEdgeThreshold +#semantic fxaa_pp.fxaaQualityEdgeThresholdMin #semantic fxaa_pp.nlTex0 : TEX0 #var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 -#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 -#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 -#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 -#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 -#var float4 oCol : $vout.COLOR : COL : 5 : 1 -#const c[2] = 0.125 0 -2 2 -#const c[3] = 0.001953125 0.5 -PARAM c[4] = { program.local[0..1], - { 0.125, 0, -2, 2 }, - { 0.001953125, 0.5 } }; +#var float2 fxaaQualityRcpFrame : : c[0] : 1 : 1 +#var float fxaaQualitySubpix : : c[1] : 2 : 1 +#var float fxaaQualityEdgeThreshold : : c[2] : 3 : 1 +#var float fxaaQualityEdgeThresholdMin : : c[3] : 4 : 1 +#var sampler2D nlTex0 : TEX0 : texunit 0 : 5 : 1 +#var float4 oCol : $vout.COLOR : COL : 6 : 1 +#const c[4] = 0 -1 1 -2 +#const c[5] = 2 0.5 0.25 1.5 +#const c[6] = 4 12 0.083333336 3 +PARAM c[7] = { program.local[0..3], + { 0, -1, 1, -2 }, + { 2, 0.5, 0.25, 1.5 }, + { 4, 12, 0.083333336, 3 } }; TEMP R0; TEMP R1; TEMP R2; TEMP R3; TEMP R4; TEMP R5; -TEX R1.w, fragment.texcoord[1].zyzw, texture[0], 2D; -ADD R0.x, R1.w, c[3]; -TEX R0.w, fragment.texcoord[1].xwzw, texture[0], 2D; -TEX R1.w, fragment.texcoord[1], texture[0], 2D; -ADD R0.y, -R0.x, R0.w; -ADD R0.z, R1.w, R0.y; -TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D; -ADD R0.y, -R1.w, R0; -ADD R1.x, R2.w, R0.y; -ADD R1.y, R0.z, -R2.w; -MUL R2.xy, R1, R1; -ADD R0.y, R2.x, R2; -RSQ R0.y, R0.y; -MUL R2.xy, R0.y, R1; -MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0]; -ABS R0.z, R2.y; -ABS R0.y, R2.x; -MIN R0.y, R0, R0.z; -RCP R0.y, R0.y; -MUL R1.xy, R0.y, R2; -MUL R1.xy, R1, c[2].x; -MIN R1.xy, R1, c[2].w; -TEX R4, R3, texture[0], 2D; -MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0]; -TEX R3, R2, texture[0], 2D; -ADD R3, R3, R4; -MAX R1.xy, R1, c[2].z; -MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0]; -MUL R5, R3, c[3].y; -MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0]; -MIN R0.z, R0.x, R2.w; -MIN R0.y, R0.w, R1.w; -MIN R0.y, R0, R0.z; -MAX R0.z, R0.x, R2.w; -MAX R0.x, R0.w, R1.w; -MAX R0.x, R0, R0.z; -TEX R4, R2, texture[0], 2D; -TEX R3, R1, texture[0], 2D; -ADD R3, R3, R4; -MAD R3, R3, c[3].y, R5; -MUL R3, R3, c[3].y; -SLT R0.z, R0.x, R3.w; -SLT R0.x, R3.w, R0.y; -ADD_SAT R0.x, R0, R0.z; -CMP result.color, -R0.x, R5, R3; +TEMP R6; +TEMP R7; +TEMP R8; +TEMP R9; +MOV R3.xyz, c[4]; +MAD R2.zw, R3.xyyz, c[0].xyxy, fragment.texcoord[0].xyxy; +MAD R0.xy, R3, c[0], fragment.texcoord[0]; +MAD R1.xy, R3.zyzw, c[0], fragment.texcoord[0]; +TEX R5.y, R1, texture[0], 2D; +MAD R1.xy, R3.zxzw, c[0], fragment.texcoord[0]; +ADD R0.zw, fragment.texcoord[0].xyxy, -c[0].xyxy; +TEX R4.y, R0.zwzw, texture[0], 2D; +TEX R6.y, R2.zwzw, texture[0], 2D; +TEX R8, fragment.texcoord[0], texture[0], 2D; +TEX R1.y, R1, texture[0], 2D; +TEX R0.y, R0, texture[0], 2D; +ADD R0.z, R4.y, R5.y; +MAD R1.z, R0.y, c[4].w, R0; +MAD R0.zw, R3.xyyx, c[0].xyxy, fragment.texcoord[0].xyxy; +TEX R2.y, R0.zwzw, texture[0], 2D; +ADD R0.x, R2.y, R1.y; +ABS R0.w, R1.z; +ADD R1.zw, fragment.texcoord[0].xyxy, c[0].xyxy; +TEX R7.y, R1.zwzw, texture[0], 2D; +MAD R0.z, R8.y, c[4].w, R0.x; +ABS R0.z, R0; +MAD R2.x, R0.z, c[5], R0.w; +MAD R0.zw, R3.xyxz, c[0].xyxy, fragment.texcoord[0].xyxy; +TEX R3.y, R0.zwzw, texture[0], 2D; +ADD R0.z, R0.y, R3.y; +ADD R1.x, R6.y, R7.y; +MAD R0.w, R3.y, c[4], R1.x; +MAD R1.x, R8.y, c[4].w, R0.z; +ABS R0.w, R0; +ADD R2.x, R0.w, R2; +ADD R2.w, R4.y, R6.y; +ADD R0.w, R5.y, R7.y; +ABS R1.z, R1.x; +MAD R1.x, R1.y, c[4].w, R0.w; +ABS R1.w, R1.x; +MAD R1.x, R2.y, c[4].w, R2.w; +MAD R1.z, R1, c[5].x, R1.w; +ABS R1.x, R1; +ADD R1.x, R1, R1.z; +SGE R4.x, R1, R2; +MAX R1.x, R3.y, R8.y; +MAX R1.z, R1.y, R1.x; +MAX R1.x, R0.y, R2.y; +MAX R1.x, R1, R1.z; +MIN R1.z, R3.y, R8.y; +MIN R1.w, R1.y, R1.z; +MIN R1.z, R0.y, R2.y; +MIN R1.z, R1, R1.w; +MUL R2.x, R1, c[2]; +ADD R3.z, R1.x, -R1; +ABS R3.w, R4.x; +MAX R1.w, R2.x, c[3].x; +ADD R2.z, R3, -R1.w; +CMP R2.x, R2.z, c[4], c[4].z; +CMP R1.x, -R3.w, c[4], c[4].z; +MUL R3.w, R2.x, R1.x; +CMP R1.z, -R3.w, R1.y, R3.y; +ADD R1.y, -R8, R1.z; +CMP R1.w, -R3, R2.y, R0.y; +ADD R0.y, -R8, R1.w; +MUL R4.x, R2, R4; +CMP R3.y, -R3.w, c[0], R3.x; +ABS R4.w, R1.y; +ABS R4.z, R0.y; +SGE R0.y, R4.z, R4.w; +MUL R1.y, R2.x, R0; +ABS R0.y, R0; +CMP R4.y, -R0, c[4].x, c[4].z; +ABS R0.y, R1.x; +CMP R0.y, -R0, c[4].x, c[4].z; +MUL R1.x, R2, R0.y; +CMP R2.y, -R4.x, c[0], c[0].x; +CMP R2.y, -R1, -R2, R2; +MAD R1.y, R2, c[5], fragment.texcoord[0]; +CMP R5.z, -R4.x, R1.y, fragment.texcoord[0].y; +ADD R5.y, R5.z, -R3; +MAD R0.y, R2, c[5], fragment.texcoord[0].x; +CMP R3.x, -R1, c[0], R3; +CMP R6.x, -R3.w, R0.y, fragment.texcoord[0]; +ADD R5.w, R5.z, R3.y; +ADD R1.x, R6, -R3; +MOV R1.y, R5; +TEX R0.y, R1, texture[0], 2D; +MUL R1.y, R2.x, R4; +ADD R0.x, R0.z, R0; +ADD R0.w, R2, R0; +MAD R0.z, R0.x, c[5].x, R0.w; +ADD R1.w, R8.y, R1; +ADD R1.z, R8.y, R1; +CMP R4.y, -R1, R1.z, R1.w; +ADD R1.z, R6.x, R3.x; +MAD R5.x, -R4.y, c[5].y, R0.y; +MOV R1.w, R5; +TEX R0.y, R1.zwzw, texture[0], 2D; +MAX R1.w, R4.z, R4; +MAD R1.y, -R4, c[5], R0; +MUL R4.z, R1.w, c[5]; +ABS R0.y, R1; +SGE R1.w, R0.y, R4.z; +ABS R6.y, R5.x; +SGE R0.y, R6, R4.z; +ABS R1.w, R1; +CMP R6.y, -R1.w, c[4].x, c[4].z; +ABS R0.y, R0; +CMP R5.z, -R0.y, c[4].x, c[4]; +ADD_SAT R0.y, R5.z, R6; +MUL R4.w, R2.x, R0.y; +MUL R0.y, R2.x, R6; +MAD R1.w, R3.y, c[5], R5; +CMP R6.x, -R0.y, R1.w, R5.w; +MAD R6.z, R3.x, c[5].w, R1; +CMP R1.z, -R0.y, R6, R1; +MOV R1.w, R6.x; +TEX R0.y, R1.zwzw, texture[0], 2D; +MUL R1.w, R4, R6.y; +CMP R6.y, -R1.w, R0, R1; +MUL R0.y, R2.x, R5.z; +MAD R1.y, -R3, c[5].w, R5; +CMP R5.w, -R0.y, R1.y, R5.y; +MAD R6.z, -R3.x, c[5].w, R1.x; +CMP R1.x, -R0.y, R6.z, R1; +MOV R1.y, R5.w; +TEX R0.y, R1, texture[0], 2D; +MUL R5.y, R4.w, R5.z; +CMP R0.y, -R5, R0, R5.x; +MAD R5.x, -R4.y, c[5].y, R0.y; +CMP R5.z, -R5.y, R5.x, R0.y; +MAD R1.y, -R4, c[5], R6; +CMP R1.y, -R1.w, R1, R6; +ABS R1.w, R1.y; +SGE R1.w, R1, R4.z; +ABS R0.y, R5.z; +SGE R0.y, R0, R4.z; +ABS R1.w, R1; +CMP R6.y, -R1.w, c[4].x, c[4].z; +ABS R0.y, R0; +CMP R5.y, -R0, c[4].x, c[4].z; +ADD_SAT R0.y, R5, R6; +MUL R5.x, R4.w, R0.y; +MUL R0.y, R4.w, R6; +MAD R1.w, R3.y, c[5].x, R6.x; +CMP R6.x, -R0.y, R1.w, R6; +MAD R6.z, R3.x, c[5].x, R1; +CMP R1.z, -R0.y, R6, R1; +MOV R1.w, R6.x; +TEX R0.y, R1.zwzw, texture[0], 2D; +MUL R1.w, R5.x, R6.y; +CMP R6.y, -R1.w, R0, R1; +MUL R0.y, R4.w, R5; +MAD R1.y, -R3, c[5].x, R5.w; +CMP R4.w, -R0.y, R1.y, R5; +MAD R6.z, -R3.x, c[5].x, R1.x; +CMP R1.x, -R0.y, R6.z, R1; +MOV R1.y, R4.w; +TEX R0.y, R1, texture[0], 2D; +MUL R5.y, R5.x, R5; +CMP R0.y, -R5, R0, R5.z; +MAD R5.z, -R4.y, c[5].y, R0.y; +CMP R5.w, -R5.y, R5.z, R0.y; +MAD R1.y, -R4, c[5], R6; +CMP R1.y, -R1.w, R1, R6; +ABS R1.w, R1.y; +SGE R1.w, R1, R4.z; +ABS R1.w, R1; +CMP R6.y, -R1.w, c[4].x, c[4].z; +ABS R0.y, R5.w; +SGE R0.y, R0, R4.z; +ABS R0.y, R0; +CMP R5.y, -R0, c[4].x, c[4].z; +ADD_SAT R0.y, R5, R6; +MUL R5.z, R5.x, R0.y; +MUL R0.y, R5.x, R6; +MAD R1.w, R3.y, c[6].x, R6.x; +CMP R6.x, -R0.y, R1.w, R6; +MAD R6.z, R3.x, c[6].x, R1; +CMP R1.z, -R0.y, R6, R1; +MOV R1.w, R6.x; +TEX R0.y, R1.zwzw, texture[0], 2D; +MUL R1.w, R5.z, R6.y; +CMP R6.y, -R1.w, R0, R1; +MUL R0.y, R5.x, R5; +MAD R1.y, -R3, c[6].x, R4.w; +CMP R4.w, -R0.y, R1.y, R4; +MAD R5.x, -R3, c[6], R1; +CMP R1.x, -R0.y, R5, R1; +MOV R1.y, R4.w; +TEX R0.y, R1, texture[0], 2D; +MUL R1.y, R5.z, R5; +CMP R5.x, -R1.y, R0.y, R5.w; +MAD R5.y, -R4, c[5], R5.x; +CMP R1.y, -R1, R5, R5.x; +MAD R0.y, -R4, c[5], R6; +CMP R0.y, -R1.w, R0, R6; +ABS R5.x, R0.y; +ABS R1.w, R1.y; +SGE R1.w, R1, R4.z; +SGE R5.x, R5, R4.z; +ABS R4.z, R5.x; +ABS R1.w, R1; +CMP R4.z, -R4, c[4].x, c[4]; +CMP R1.w, -R1, c[4].x, c[4].z; +MUL R4.z, R5, R4; +MAD R5.y, R3.x, c[6], R1.z; +CMP R5.y, -R4.z, R5, R1.z; +MAD R5.x, R3.y, c[6].y, R6; +CMP R1.z, -R4, R5.x, R6.x; +MUL R1.w, R5.z, R1; +ADD R4.z, -fragment.texcoord[0].x, R5.y; +ADD R1.z, -fragment.texcoord[0].y, R1; +CMP R1.z, -R3.w, R1, R4; +MAD R4.z, -R3.x, c[6].y, R1.x; +MAD R3.x, -R3.y, c[6].y, R4.w; +CMP R3.y, -R1.w, R4.z, R1.x; +CMP R1.x, -R1.w, R3, R4.w; +ADD R1.w, fragment.texcoord[0].x, -R3.y; +ADD R1.x, fragment.texcoord[0].y, -R1; +CMP R1.x, -R3.w, R1, R1.w; +SLT R1.w, R1.x, R1.z; +ADD R3.x, R1, R1.z; +ABS R1.w, R1; +MIN R1.x, R1, R1.z; +CMP R1.w, -R1, c[4].x, c[4].z; +MUL R1.z, R2.x, R1.w; +RCP R3.x, R3.x; +MAD R1.x, R1, -R3, c[5].y; +MUL R1.w, R4.y, c[5].y; +SLT R3.x, R1.y, c[4]; +SLT R1.y, R8, R1.w; +SLT R0.y, R0, c[4].x; +ADD R0.y, R0, -R1; +ADD R1.y, -R1, R3.x; +ABS R0.y, R0; +ABS R1.y, R1; +CMP R0.y, -R0, c[4].z, c[4].x; +CMP R1.y, -R1, c[4].z, c[4].x; +CMP R0.x, -R1.z, R0.y, R1.y; +MAD R0.y, R0.z, c[6].z, -R8; +ABS R0.x, R0; +CMP R0.x, -R0, c[4], c[4].z; +MUL R0.x, R2, R0; +CMP R0.x, -R0, c[4], R1; +RCP R0.z, R3.z; +ABS R0.y, R0; +MUL_SAT R0.y, R0, R0.z; +MUL R0.z, R0.y, c[4].w; +ADD R0.z, R0, c[6].w; +MUL R0.y, R0, R0; +MUL R0.y, R0.z, R0; +MUL R0.y, R0, R0; +MUL R0.y, R0, c[1].x; +MAX R0.x, R0, R0.y; +MAD R0.y, R0.x, R2, fragment.texcoord[0]; +MAD R0.z, R0.x, R2.y, fragment.texcoord[0].x; +CMP R0.x, -R3.w, R0.z, fragment.texcoord[0]; +CMP R0.y, -R4.x, R0, fragment.texcoord[0]; +TEX R0.xyz, R0, texture[0], 2D; +CMP R1, R2.z, R8, R9; +MOV R0.w, R8.y; +CMP result.color, -R2.x, R0, R1; END -# 45 instructions, 6 R-regs +# 260 instructions, 10 R-regs diff --git a/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt b/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt index fcd16fcd0..de51eba42 100644 --- a/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt +++ b/code/nel/src/3d/shaders/fxaa_pp_ps_2_0.txt @@ -1,92 +1,306 @@ -ps_2_0 +ps_2_x // cgc version 3.1.0013, build date Apr 18 2012 -// command line args: -profile ps_2_0 -O3 -fastmath -fastprecision +// command line args: -profile ps_2_x -O3 -fastmath -fastprecision // source file: fxaa_pp.cg //vendor NVIDIA Corporation //version 3.1.0.13 -//profile ps_2_0 +//profile ps_2_x //program fxaa_pp -//semantic fxaa_pp.fxaaConsoleRcpFrameOpt -//semantic fxaa_pp.fxaaConsoleRcpFrameOpt2 +//semantic fxaa_pp.fxaaQualityRcpFrame +//semantic fxaa_pp.fxaaQualitySubpix +//semantic fxaa_pp.fxaaQualityEdgeThreshold +//semantic fxaa_pp.fxaaQualityEdgeThresholdMin //semantic fxaa_pp.nlTex0 : TEX0 //var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1 -//var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1 -//var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1 -//var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1 -//var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1 -//var float4 oCol : $vout.COLOR : COL : 5 : 1 -//const c[2] = 0.001953125 0.125 2 -2 -//const c[3] = 0.5 0 1 +//var float2 fxaaQualityRcpFrame : : c[0] : 1 : 1 +//var float fxaaQualitySubpix : : c[1] : 2 : 1 +//var float fxaaQualityEdgeThreshold : : c[2] : 3 : 1 +//var float fxaaQualityEdgeThresholdMin : : c[3] : 4 : 1 +//var sampler2D nlTex0 : TEX0 : texunit 0 : 5 : 1 +//var float4 oCol : $vout.COLOR : COL : 6 : 1 +//const c[4] = 0 -1 1 -2 +//const c[5] = 2 0.5 0.25 1.5 +//const c[6] = 4 12 0.083333336 +//const c[7] = -2 3 dcl_2d s0 -def c2, 0.00195313, 0.12500000, 2.00000000, -2.00000000 -def c3, 0.50000000, 0.00000000, 1.00000000, 0 -dcl t1 +def c4, 0.00000000, -1.00000000, 1.00000000, -2.00000000 +def c5, 2.00000000, 0.50000000, 0.25000000, 1.50000000 +def c6, 4.00000000, 12.00000000, 0.08333334, 0 +def c7, -2.00000000, 3.00000000, 0, 0 dcl t0.xy -texld r5, t1, s0 -mov r1.y, t1.w -mov r1.x, t1.z -mov r2.xy, r1 -mov r0.y, t1.w -mov r0.x, t1 -mov r1.y, t1 -mov r1.x, t1.z -texld r1, r1, s0 -texld r0, r0, s0 -texld r6, r2, s0 -add r0.x, r1.w, c2 -add r2.x, -r0, r0.w -add r1.x, r5.w, r2 -add r2.z, r1.x, -r6.w -add r2.x, -r5.w, r2 -add r2.x, r6.w, r2 -mov r3.x, r2 -mov r3.y, r2.z -mov r2.y, r2.z -mov r1.y, r2.z -mov r1.x, r2 -mul r1.xy, r3, r1 -add r1.x, r1, r1.y -rsq r1.x, r1.x -mul r4.xy, r1.x, r2 -abs r2.x, r4.y -abs r1.x, r4 -min r1.x, r1, r2 -rcp r1.x, r1.x -mul r1.xy, r1.x, r4 -mul r1.xy, r1, c2.y -min r1.xy, r1, c2.z -max r2.xy, r1, c2.w -mov r1.y, c1.w -mov r1.x, c1.z -mad r3.xy, r2, r1, t0 -mov r1.y, c1.w -mov r1.x, c1.z -mad r5.xy, -r2, r1, t0 -mov r1.y, c0.w -mov r1.x, c0.z -mad r2.xy, -r4, r1, t0 -mov r1.y, c0.w -mov r1.x, c0.z -mad r1.xy, r4, r1, t0 -texld r4, r5, s0 +mov r0.zw, c0.xyxy +mad r3.xy, c4.zxzw, r0.zwzw, t0 +texld r7, r3, s0 +texld r1, t0, s0 +mov r0.xy, c0 +mad r0.xy, c4.yxzw, r0, t0 +texld r8, r0, s0 +mov r0.xy, c0 +mad r0.xy, c4, r0, t0 +texld r9, r0, s0 +add r0.xy, t0, -c0 +texld r5, r0, s0 +mov r3.xy, c0 +mad r3.xy, c4.zyzw, r3, t0 texld r3, r3, s0 -texld r1, r1, s0 -texld r2, r2, s0 -add r1, r2, r1 -mul r2, r1, c3.x -add r1, r4, r3 -max r3.x, r0, r6.w -mad r1, r1, c3.x, r2 -mul r4, r1, c3.x -max r1.x, r0.w, r5.w -max r1.x, r1, r3 -add r1.x, -r4.w, r1 -min r3.x, r0.w, r5.w -min r0.x, r0, r6.w -min r0.x, r3, r0 -add r0.x, r4.w, -r0 -cmp r1.x, r1, c3.y, c3.z -cmp r0.x, r0, c3.y, c3.z -add_pp_sat r0.x, r0, r1 -cmp r0, -r0.x, r4, r2 +add r7.x, r8.y, r7.y +mad r0.z, r1.y, c4.w, r7.x +add r0.x, r5.y, r3.y +mad r0.w, r9.y, c4, r0.x +mov r0.xy, c0 +mad r0.xy, c4.xzzw, r0, t0 +texld r6, r0, s0 +add r5.x, r9.y, r6.y +abs r0.z, r0 +abs r0.w, r0 +mad r3.x, r0.z, c5, r0.w +mov r0.zw, c0.xyxy +mad r4.xy, c4.yzzw, r0.zwzw, t0 +texld r4, r4, s0 +add r0.xy, t0, c0 +texld r0, r0, s0 +add r4.x, r5.y, r4.y +add r5.y, r3, r0 +add r0.x, r4.y, r0.y +mad r0.x, r6.y, c4.w, r0 +abs r0.x, r0 +add r0.w, r0.x, r3.x +mad r0.x, r8.y, c4.w, r4 +mad r0.z, r7.y, c4.w, r5.y +mad r0.y, r1, c4.w, r5.x +abs r0.z, r0 +abs r0.y, r0 +mad r0.y, r0, c5.x, r0.z +abs r0.x, r0 +add r0.x, r0, r0.y +add r0.x, r0, -r0.w +cmp r3.y, r0.x, c4.z, c4.x +max r0.y, r6, r1 +max r0.z, r7.y, r0.y +max r0.y, r9, r8 +max r0.y, r0, r0.z +min r0.z, r6.y, r1.y +min r0.w, r7.y, r0.z +min r0.z, r9.y, r8.y +min r0.z, r0, r0.w +mul r3.x, r0.y, c2 +abs_pp r0.x, r3.y +add r4.y, r0, -r0.z +max r0.w, r3.x, c3.x +add r4.z, r4.y, -r0.w +cmp_pp r4.w, r4.z, c4.z, c4.x +mul_pp r5.w, r4, r3.y +cmp_pp r0.y, -r0.x, c4.z, c4.x +mul_pp r5.z, r4.w, r0.y +cmp_pp r3.x, -r0, c4, c4.z +cmp r6.w, -r5.z, r6.y, r7.y +cmp r7.w, -r5.z, r9.y, r8.y +add r0.z, -r1.y, r6.w +add r0.y, -r1, r7.w +abs r9.z, r0 +abs r7.y, r0 +add r0.y, r7, -r9.z +cmp r0.y, r0, c4.z, c4.x +max r7.y, r7, r9.z +mul_pp r0.z, r4.w, r0.y +cmp r0.w, -r5, c0.x, c0.y +cmp r6.x, -r0.z, r0.w, -r0.w +mov r0.z, c0.y +cmp r6.y, -r5.z, c4.x, r0.z +mad r0.w, r6.x, c5.y, t0.y +cmp r0.z, -r5.w, t0.y, r0.w +add r8.z, r0, r6.y +add r7.z, r0, -r6.y +mov r9.y, r7.z +mov r8.y, r8.z +mad r0.w, r6.x, c5.y, t0.x +mov r0.x, c0 +mul_pp r3.x, r4.w, r3 +cmp r6.z, -r3.x, c4.x, r0.x +cmp r0.x, -r5.z, t0, r0.w +add r9.x, r0, -r6.z +texld r3, r9, s0 +add r8.x, r0, r6.z +abs_pp r3.x, r0.y +texld r0, r8, s0 +cmp_pp r0.x, -r3, c4.z, c4 +add r0.w, r1.y, r6 +add r0.z, r1.y, r7.w +mul_pp r0.x, r4.w, r0 +cmp r6.w, -r0.x, r0.z, r0 +mad r7.w, -r6, c5.y, r0.y +mad r8.w, -r6, c5.y, r3.y +abs r0.y, r7.w +abs r0.x, r8.w +mad r0.x, -r7.y, c5.z, r0 +mad r0.y, -r7, c5.z, r0 +cmp r0.x, r0, c4.z, c4 +abs_pp r0.x, r0 +cmp_pp r9.z, -r0.x, c4, c4.x +cmp r0.y, r0, c4.z, c4.x +abs_pp r0.y, r0 +cmp_pp r9.w, -r0.y, c4.z, c4.x +mul_pp r0.x, r4.w, r9.z +mad r0.y, -r6, c5.w, r7.z +cmp r7.z, -r0.x, r7, r0.y +mad r0.z, -r6, c5.w, r9.x +cmp r9.x, -r0, r9, r0.z +mov r9.y, r7.z +texld r3, r9, s0 +add_pp_sat r3.z, r9, r9.w +mul_pp r0.x, r4.w, r9.w +mad r0.y, r6, c5.w, r8.z +cmp r3.x, -r0, r8.z, r0.y +mad r0.z, r6, c5.w, r8.x +mul_pp r8.z, r4.w, r3 +cmp r8.x, -r0, r8, r0.z +mov r8.y, r3.x +texld r0, r8, s0 +mul_pp r0.w, r8.z, r9 +cmp r3.z, -r0.w, r7.w, r0.y +mul_pp r0.x, r8.z, r9.z +cmp r0.y, -r0.x, r8.w, r3 +mad r0.z, -r6.w, c5.y, r0.y +cmp r8.w, -r0.x, r0.y, r0.z +mad r3.y, -r6.w, c5, r3.z +cmp r9.w, -r0, r3.z, r3.y +abs r0.y, r9.w +abs r0.x, r8.w +mad r0.y, -r7, c5.z, r0 +mad r0.x, -r7.y, c5.z, r0 +cmp r0.y, r0, c4.z, c4.x +abs_pp r0.y, r0 +cmp_pp r10.x, -r0.y, c4.z, c4 +cmp r0.x, r0, c4.z, c4 +abs_pp r0.x, r0 +cmp_pp r9.z, -r0.x, c4, c4.x +mul_pp r0.x, r8.z, r10 +mad r0.y, r6, c5.x, r3.x +cmp r7.w, -r0.x, r3.x, r0.y +mad r0.z, r6, c5.x, r8.x +cmp r8.x, -r0, r8, r0.z +mov r8.y, r7.w +texld r0, r8, s0 +mul_pp r0.w, r8.z, r9.z +mad r3.x, -r6.z, c5, r9 +mad r0.x, -r6.y, c5, r7.z +cmp r0.x, -r0.w, r7.z, r0 +add_pp_sat r0.z, r9, r10.x +mul_pp r7.z, r8, r0 +cmp r9.x, -r0.w, r9, r3 +mov r9.y, r0.x +texld r3, r9, s0 +mul_pp r0.z, r7, r9 +cmp r0.w, -r0.z, r8, r3.y +mul_pp r3.x, r7.z, r10 +cmp r3.y, -r3.x, r9.w, r0 +mad r0.y, -r6.w, c5, r0.w +cmp r8.z, -r0, r0.w, r0.y +mad r3.z, -r6.w, c5.y, r3.y +cmp r9.z, -r3.x, r3.y, r3 +abs r0.y, r8.z +abs r0.z, r9 +mad r0.y, -r7, c5.z, r0 +mad r0.z, -r7.y, c5, r0 +cmp r0.y, r0, c4.z, c4.x +abs_pp r0.y, r0 +cmp_pp r8.w, -r0.y, c4.z, c4.x +cmp r0.z, r0, c4, c4.x +abs_pp r0.z, r0 +cmp_pp r9.w, -r0.z, c4.z, c4.x +mul_pp r0.y, r7.z, r8.w +mad r0.z, -r6.y, c6.x, r0.x +cmp r10.x, -r0.y, r0, r0.z +mad r0.w, -r6.z, c6.x, r9.x +cmp r9.x, -r0.y, r9, r0.w +mov r9.y, r10.x +texld r3, r9, s0 +mul_pp r0.x, r7.z, r9.w +mad r0.z, r6, c6.x, r8.x +mad r0.y, r6, c6.x, r7.w +cmp r3.x, -r0, r7.w, r0.y +cmp r8.x, -r0, r8, r0.z +mov r8.y, r3.x +texld r0, r8, s0 +add_pp_sat r3.z, r8.w, r9.w +mul_pp r0.x, r7.z, r3.z +mul_pp r3.z, r0.x, r9.w +cmp r0.y, -r3.z, r9.z, r0 +mul_pp r0.z, r0.x, r8.w +cmp r0.w, -r0.z, r8.z, r3.y +mad r3.w, -r6, c5.y, r0.y +cmp r0.y, -r3.z, r0, r3.w +mad r3.y, -r6.w, c5, r0.w +cmp r0.z, -r0, r0.w, r3.y +abs r3.y, r0 +abs r0.w, r0.z +mad r3.y, -r7, c5.z, r3 +mad r0.w, -r7.y, c5.z, r0 +cmp r3.y, r3, c4.z, c4.x +abs_pp r3.y, r3 +cmp r0.w, r0, c4.z, c4.x +cmp_pp r3.z, -r3.y, c4, c4.x +abs_pp r0.w, r0 +cmp_pp r3.y, -r0.w, c4.z, c4.x +mul_pp r0.w, r0.x, r3.z +mul_pp r0.x, r0, r3.y +mad r3.w, r6.y, c6.y, r3.x +cmp r3.x, -r0.w, r3, r3.w +mad r3.z, r6, c6.y, r8.x +cmp r0.w, -r0, r8.x, r3.z +mad r3.y, -r6, c6, r10.x +cmp r3.y, -r0.x, r10.x, r3 +add r3.x, -t0.y, r3 +add r0.w, -t0.x, r0 +cmp r0.w, -r5.z, r0, r3.x +mad r3.x, -r6.z, c6.y, r9 +cmp r0.x, -r0, r9, r3 +add r3.x, t0.y, -r3.y +add r0.x, t0, -r0 +cmp r0.x, -r5.z, r0, r3 +add r3.x, r0, -r0.w +add r3.y, r0.x, r0.w +cmp r3.x, r3, c4, c4.z +abs_pp r3.x, r3 +min r0.x, r0, r0.w +cmp_pp r3.x, -r3, c4.z, c4 +mul_pp r0.w, r4, r3.x +rcp r3.y, r3.y +mad r0.x, r0, -r3.y, c5.y +cmp r3.y, r0, c4.x, c4.z +mad r3.x, -r6.w, c5.y, r1.y +cmp r3.x, r3, c4, c4.z +cmp r0.y, r0.z, c4.x, c4.z +add_pp r0.z, -r3.x, r3.y +add_pp r0.y, r0, -r3.x +abs_pp r0.y, r0 +abs_pp r0.z, r0 +cmp_pp r0.z, -r0, c4.x, c4 +cmp_pp r0.y, -r0, c4.x, c4.z +cmp_pp r0.y, -r0.w, r0, r0.z +abs_pp r0.y, r0 +cmp_pp r0.y, -r0, c4.z, c4.x +mul_pp r0.y, r4.w, r0 +rcp r0.w, r4.y +cmp r0.x, -r0.y, r0, c4 +add r3.y, r4.x, r5 +add r3.x, r5, r7 +mad r3.x, r3, c5, r3.y +mad r0.z, r3.x, c6, -r1.y +abs r0.z, r0 +mul_sat r0.z, r0, r0.w +mul r0.w, r0.z, r0.z +mad r0.z, r0, c7.x, c7.y +mul r0.z, r0, r0.w +mul r0.z, r0, r0 +mul r0.z, r0, c1.x +max r0.x, r0, r0.z +mad r0.y, r0.x, r6.x, t0 +mad r0.z, r0.x, r6.x, t0.x +cmp r0.x, -r5.z, t0, r0.z +cmp r0.y, -r5.w, t0, r0 +texld r0, r0, s0 +mov r0.w, r1.y +cmp r1, r4.z, r2, r1 +cmp r0, -r4.w, r1, r0 mov oC0, r0 From d56047bde6699983897ba62bb3d99d85b3495c91 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 06:19:03 +0200 Subject: [PATCH 054/240] Remove debug --HG-- branch : multipass-stereo --- code/nel/src/3d/fxaa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index a1f07aaa1..a0fe90ecc 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -237,7 +237,7 @@ void CFXAA::applyEffect() drv->setRenderTarget(renderTarget); // debug - m_Driver->clearBuffers(CRGBA(128, 128, 128, 128)); + // m_Driver->clearBuffers(CRGBA(128, 128, 128, 128)); // activate program bool vpok = drv->activeVertexProgram(m_VP); From 1a413b0fe3b436e2b8a2553a82b3d4862aa42328 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 06:19:19 +0200 Subject: [PATCH 055/240] Add FXAA to Ryzom Client --HG-- branch : multipass-stereo --- code/ryzom/client/client_default.cfg | 6 +++++ code/ryzom/client/client_default.cfg.in | 6 +++++ .../gamedev/interfaces_v3/game_config.xml | 15 +++++++++++- code/ryzom/client/src/client_cfg.cpp | 5 ++++ code/ryzom/client/src/client_cfg.h | 3 +++ code/ryzom/client/src/global.cpp | 23 +++++++++++-------- code/ryzom/client/src/global.h | 4 ++++ code/ryzom/client/src/init_main_loop.cpp | 5 ++++ code/ryzom/client/src/login.cpp | 1 + code/ryzom/client/src/main_loop.cpp | 4 +++- code/ryzom/client/src/main_loop_utilities.cpp | 17 ++++++++++++++ code/ryzom/client/src/release.cpp | 6 +++-- 12 files changed, 81 insertions(+), 14 deletions(-) diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index a27e69ee0..2846713fc 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -214,6 +214,12 @@ Shadows_ps1 = 1; Shadows_ps2 = 1; Shadows_ps3 = 1; +FXAA = 1; +FXAA_ps0 = 0; +FXAA_ps1 = 1; +FXAA_ps2 = 1; +FXAA_ps3 = 1; + Bloom = 0; Bloom_ps0 = 0; Bloom_ps1 = 1; diff --git a/code/ryzom/client/client_default.cfg.in b/code/ryzom/client/client_default.cfg.in index 030a4a2b2..ec699fe14 100644 --- a/code/ryzom/client/client_default.cfg.in +++ b/code/ryzom/client/client_default.cfg.in @@ -210,6 +210,12 @@ Shadows_ps1 = 1; Shadows_ps2 = 1; Shadows_ps3 = 1; +FXAA = 1; +FXAA_ps0 = 0; +FXAA_ps1 = 1; +FXAA_ps2 = 1; +FXAA_ps3 = 1; + Bloom = 0; Bloom_ps0 = 0; Bloom_ps1 = 1; diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml index 5e9072b93..c2b62cebd 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml @@ -1230,8 +1230,15 @@ posref="BL TL" x="-20" y="-12" /> + + setDefaultContextHelp(CI18N::get("uiFxTooltipBloom")); + ClientCfg.writeBool("FXAA", false); ClientCfg.writeBool("Bloom", false); ClientCfg.writeBool("SquareBloom", false); ClientCfg.writeInt("DensityBloom", 0); diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index ff199eace..628cc7624 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -1990,6 +1990,7 @@ class CAHInitResLod : public IActionHandler CfgPresetList.push_back(pair("NbMaxSkeletonNotCLod", false)); CfgPresetList.push_back(pair("CharacterFarClip", true)); + CfgPresetList.push_back(pair("FXAA", false)); CfgPresetList.push_back(pair("Bloom", false)); CfgPresetList.push_back(pair("SquareBloom", false)); CfgPresetList.push_back(pair("DensityBloom", true)); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index ad1cb403e..66fe7cc39 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -45,6 +45,7 @@ #include "nel/3d/stereo_hmd.h" #include "nel/3d/render_target_manager.h" #include "nel/3d/driver_user.h" +#include "nel/3d/fxaa.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" @@ -1630,7 +1631,7 @@ bool mainLoop() bool effectRender = false; CTextureUser *effectRenderTarget = NULL; bool haveEffects = Render && Driver->getPolygonMode() == UDriver::Filled - && ClientCfg.Bloom; + && (ClientCfg.Bloom || FXAA); bool defaultRenderTarget = false; if (haveEffects) { @@ -1733,6 +1734,7 @@ bool mainLoop() if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); UCamera pCam = Scene->getCam(); Driver->setMatrixMode2D11(); + if (FXAA) FXAA->applyEffect(); if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom(); Driver->setMatrixMode3D(pCam); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index 194810ea9..0fe52e53c 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "game_share/scenario_entry_points.h" @@ -218,6 +219,22 @@ void updateFromClientCfg() } } + //--------------------------------------------------- + if (ClientCfg.FXAA != LastClientCfg.FXAA) + { + if (ClientCfg.FXAA) + { + nlassert(!FXAA); + FXAA = new NL3D::CFXAA(Driver); + } + else + { + nlassert(FXAA); + delete FXAA; + FXAA = NULL; + } + } + // GRAPHICS - CHARACTERS //--------------------------------------------------- if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 3659d034d..5affddd04 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -497,7 +497,8 @@ void releaseOutGame() // Remove the Actions listener from the Events Server. EventsListener.removeFromServer(CInputHandlerManager::getInstance()->FilteredEventServer); - // Release Bloom + // Release effects + delete FXAA; FXAA = NULL; CBloomEffect::releaseInstance(); // Release Scene, textcontexts, materials, ... @@ -591,7 +592,8 @@ void release() Driver->deleteTextContext(TextContext); TextContext = NULL; - // Release Bloom + // Release effects + delete FXAA; FXAA = NULL; CBloomEffect::releaseInstance(); // Release Scene, textcontexts, materials, ... From 96bd17ae6321cdf253f3545cd25dfc087544b76c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 07:38:40 +0200 Subject: [PATCH 056/240] 3D: Fix texture coords for FXAA on D3D --HG-- branch : multipass-stereo --- code/nel/src/3d/fxaa.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index a0fe90ecc..238303001 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -148,10 +148,20 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); - m_QuadUV.Uv0 = CUV(0.f, 0.f); - m_QuadUV.Uv1 = CUV(1.f, 0.f); - m_QuadUV.Uv2 = CUV(1.f, 1.f); - m_QuadUV.Uv3 = CUV(0.f, 1.f); + if (drv->textureCoordinateAlternativeMode()) + { + m_QuadUV.Uv0 = CUV(0.f, 1.f); + m_QuadUV.Uv1 = CUV(1.f, 1.f); + m_QuadUV.Uv2 = CUV(1.f, 0.f); + m_QuadUV.Uv3 = CUV(0.f, 0.f); + } + else + { + m_QuadUV.Uv0 = CUV(0.f, 0.f); + m_QuadUV.Uv1 = CUV(1.f, 0.f); + m_QuadUV.Uv2 = CUV(1.f, 1.f); + m_QuadUV.Uv3 = CUV(0.f, 1.f); + } /*CVertexBuffer &vb = m_VB; vb.clearValueEx(); From 0488b706b23010a5142f0cb2921a89cd22ae7d20 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 18:30:25 +0200 Subject: [PATCH 057/240] Add placeholders for LibOVR 0.4.0 support --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr.h | 2 +- code/nel/include/nel/3d/stereo_ovr_04.h | 185 +++++ code/nel/src/3d/CMakeLists.txt | 8 + code/nel/src/3d/stereo_debugger.cpp | 2 +- code/nel/src/3d/stereo_display.cpp | 9 +- code/nel/src/3d/stereo_hmd.cpp | 2 +- code/nel/src/3d/stereo_libvr.cpp | 2 +- code/nel/src/3d/stereo_ovr.cpp | 5 +- code/nel/src/3d/stereo_ovr_04.cpp | 1015 +++++++++++++++++++++++ code/nel/src/3d/stereo_ovr_04_program.h | 249 ++++++ code/nel/src/3d/stereo_ovr_fp.cpp | 2 + 11 files changed, 1471 insertions(+), 10 deletions(-) create mode 100644 code/nel/include/nel/3d/stereo_ovr_04.h create mode 100644 code/nel/src/3d/stereo_ovr_04.cpp create mode 100644 code/nel/src/3d/stereo_ovr_04_program.h diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index a215ff8b6..750f32027 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -44,7 +44,7 @@ #ifndef NL3D_STEREO_OVR_H #define NL3D_STEREO_OVR_H -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 #include diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h new file mode 100644 index 000000000..d58698066 --- /dev/null +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -0,0 +1,185 @@ +/** + * \file stereo_ovr.h + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifndef NL3D_STEREO_OVR_H +#define NL3D_STEREO_OVR_H + +#ifdef HAVE_LIBOVR + +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CStereoOVRDevicePtr; +class CStereoOVRDeviceHandle; +/*class CPixelProgramOVR;*/ + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +/** + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoOVR : public IStereoHMD +{ +public: + CStereoOVR(const CStereoOVRDeviceHandle *handle); + virtual ~CStereoOVR(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + /// Get the original frustum of the camera + virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const; + + /// Set the GUI reference + virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix); + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + + /// Calculates internal camera information based on the reference camera + void initCamera(uint cid, const NL3D::UCamera *camera); + /// Render GUI + void renderGUI(); + + /// Checks if the device used by this class was actually created + bool isDeviceCreated(); + + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + +private: + CStereoOVRDevicePtr *m_DevicePtr; + int m_Stage; + int m_SubStage; + CViewport m_RegularViewport; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_InterfaceCameraMatrix; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NL3D::CTextureUser *m_GUITexture; + /*NL3D::CTextureUser *m_SceneTexture; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; + NLMISC::CRefPtr m_PixelProgram;*/ + NLMISC::CVector m_EyePosition; + float m_Scale; + +}; /* class CStereoOVR */ + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +#endif /* #ifndef NL3D_STEREO_OVR_H */ + +/* end of file */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index fff343915..21184eb12 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -562,8 +562,13 @@ SOURCE_GROUP(Fx\\Particles\\lights FILES ps_light.cpp ../../include/nel/3d/ps_light.h) SOURCE_GROUP(Fx\\2d FILES + render_target_manager.cpp + ../../include/nel/3d/render_target_manager.h bloom_effect.cpp ../../include/nel/3d/bloom_effect.h + fxaa.cpp + fxaa_program.h + ../../include/nel/3d/fxaa.h deform_2d.cpp ../../include/nel/3d/deform_2d.h heat_haze.cpp @@ -700,6 +705,9 @@ SOURCE_GROUP(Stereo FILES stereo_ovr.cpp stereo_ovr_fp.cpp ../../include/nel/3d/stereo_ovr.h + stereo_ovr_04.cpp + stereo_ovr_04_program.h + ../../include/nel/3d/stereo_ovr_04.h stereo_libvr.cpp ../../include/nel/3d/stereo_libvr.h stereo_debugger.cpp diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 3a3144113..89ca605d0 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -26,7 +26,7 @@ */ #if !FINAL_VERSION -#include +#include "std3d.h" #include // STL includes diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index eace867fc..2ef8dca17 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -25,7 +25,7 @@ * . */ -#include +#include "std3d.h" #include // STL includes @@ -35,6 +35,7 @@ // Project includes #include +#include #include #include @@ -76,7 +77,7 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 CStereoOVR::listDevices(devicesOut); #endif #ifdef HAVE_LIBVR @@ -94,7 +95,7 @@ IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo void IStereoDisplay::releaseUnusedLibraries() { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 if (!CStereoOVR::isLibraryInUse()) CStereoOVR::releaseLibrary(); #endif @@ -102,7 +103,7 @@ void IStereoDisplay::releaseUnusedLibraries() void IStereoDisplay::releaseAllLibraries() { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 CStereoOVR::releaseLibrary(); #endif } diff --git a/code/nel/src/3d/stereo_hmd.cpp b/code/nel/src/3d/stereo_hmd.cpp index d28017482..25249e2b4 100644 --- a/code/nel/src/3d/stereo_hmd.cpp +++ b/code/nel/src/3d/stereo_hmd.cpp @@ -25,7 +25,7 @@ * . */ -#include +#include "std3d.h" #include // STL includes diff --git a/code/nel/src/3d/stereo_libvr.cpp b/code/nel/src/3d/stereo_libvr.cpp index 44a5a0a5a..c655f959c 100644 --- a/code/nel/src/3d/stereo_libvr.cpp +++ b/code/nel/src/3d/stereo_libvr.cpp @@ -27,7 +27,7 @@ #ifdef HAVE_LIBVR -#include +#include "std3d.h" #include #include diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 8b8f8a90a..073490dc0 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -41,15 +41,16 @@ * so, delete this exception statement from your version. */ -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 -#include +#include "std3d.h" #include // STL includes #include // External includes +#define OVR_NO_STDINT #include // NeL includes diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp new file mode 100644 index 000000000..5751af285 --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -0,0 +1,1015 @@ +/** + * \file stereo_ovr.cpp + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifdef HAVE_LIBOVR + +#include "std3d.h" +#include + +// STL includes +#include + +// External includes +#define OVR_NO_STDINT +#include + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +/*extern const char *g_StereoOVR_fp40; +extern const char *g_StereoOVR_arbfp1; +extern const char *g_StereoOVR_ps_2_0; +extern const char *g_StereoOVR_glsl330f;*/ + +namespace { +/* +class CStereoOVRLog : public OVR::Log +{ +public: + CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) + { + + } + + virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) + { + if (NLMISC::INelContext::isContextInitialised()) + { + char buffer[MaxLogBufferMessageSize]; + FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); + if (IsDebugMessage(messageType)) + NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); + else + NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); + } + } +}; + +CStereoOVRLog *s_StereoOVRLog = NULL; +OVR::Ptr s_DeviceManager; + +class CStereoOVRSystem +{ +public: + ~CStereoOVRSystem() + { + Release(); + } + + void Init() + { + if (!s_StereoOVRLog) + { + nldebug("Initialize OVR"); + s_StereoOVRLog = new CStereoOVRLog(); + } + if (!OVR::System::IsInitialized()) + OVR::System::Init(s_StereoOVRLog); + if (!s_DeviceManager) + s_DeviceManager = OVR::DeviceManager::Create(); + } + + void Release() + { + if (s_DeviceManager) + { + nldebug("Release OVR"); + s_DeviceManager->Release(); + } + s_DeviceManager.Clear(); + if (OVR::System::IsInitialized()) + OVR::System::Destroy(); + if (s_StereoOVRLog) + nldebug("Release OVR Ok"); + delete s_StereoOVRLog; + s_StereoOVRLog = NULL; + } +}; + +CStereoOVRSystem s_StereoOVRSystem; + +sint s_DeviceCounter = 0; +*/ +} +/* +class CStereoOVRDeviceHandle : public IStereoDeviceFactory +{ +public: + // fixme: virtual destructor??? + OVR::DeviceEnumerator DeviceHandle; + IStereoDisplay *createDevice() const + { + CStereoOVR *stereo = new CStereoOVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + +class CStereoOVRDevicePtr +{ +public: + OVR::Ptr HMDDevice; + OVR::Ptr SensorDevice; + OVR::SensorFusion SensorFusion; + OVR::HMDInfo HMDInfo; +}; +*/ +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +{ + /*++s_DeviceCounter; + m_DevicePtr = new CStereoOVRDevicePtr(); + + OVR::DeviceEnumerator dh = handle->DeviceHandle; + m_DevicePtr->HMDDevice = dh.CreateDevice(); + + if (m_DevicePtr->HMDDevice) + { + m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo); + nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); + nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); + nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); + nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); + nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); + nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); + nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000 + m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); + m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); + m_DevicePtr->SensorFusion.SetGravityEnabled(true); + m_DevicePtr->SensorFusion.SetPredictionEnabled(true); + m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); + }*/ +} + +CStereoOVR::~CStereoOVR() +{ + /*if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; + + if (m_DevicePtr->SensorDevice) + m_DevicePtr->SensorDevice->Release(); + m_DevicePtr->SensorDevice.Clear(); + if (m_DevicePtr->HMDDevice) + m_DevicePtr->HMDDevice->Release(); + m_DevicePtr->HMDDevice.Clear(); + + delete m_DevicePtr; + m_DevicePtr = NULL; + --s_DeviceCounter;*/ +} +/* +class CPixelProgramOVR : public CPixelProgram +{ +public: + struct COVRIndices + { + uint LensCenter; + uint ScreenCenter; + uint Scale; + uint ScaleIn; + uint HmdWarpParam; + }; + + CPixelProgramOVR() + { + { + CSource *source = new CSource(); + source->Profile = glsl330f; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_glsl330f); + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = fp40; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_fp40); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = arbfp1; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_arbfp1); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = ps_2_0; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_ps_2_0); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + } + + virtual ~CPixelProgramOVR() + { + + } + + virtual void buildInfo() + { + CPixelProgram::buildInfo(); + + m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + nlassert(m_OVRIndices.LensCenter != ~0); + m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); + nlassert(m_OVRIndices.ScreenCenter != ~0); + m_OVRIndices.Scale = getUniformIndex("cScale"); + nlassert(m_OVRIndices.Scale != ~0); + m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); + nlassert(m_OVRIndices.ScaleIn != ~0); + m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); + nlassert(m_OVRIndices.HmdWarpParam != ~0); + } + + inline const COVRIndices &ovrIndices() { return m_OVRIndices; } + +private: + COVRIndices m_OVRIndices; + +}; +*/ +void CStereoOVR::setDriver(NL3D::UDriver *driver) +{/* + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + m_PixelProgram = new CPixelProgramOVR(); + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + m_PixelProgram.kill(); + } + } + + if (m_PixelProgram) + { + m_Driver = driver; + + /*m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex);* / + + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::Normal); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + // barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + + // nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); + + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); + } + else + { + nlwarning("VR: No pixel program support"); + }*/ +} + +bool CStereoOVR::getScreenResolution(uint &width, uint &height) +{ + /*width = m_DevicePtr->HMDInfo.HResolution; + height = m_DevicePtr->HMDInfo.VResolution;*/ + return true; +} + +void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) +{ + /*m_OriginalFrustum[cid] = camera->getFrustum(); + + float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); + float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; + + float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; + float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work? + float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up + nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right);*/ +} + +/// Get the frustum to use for clipping +void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); +} + +/// Get the original frustum of the camera +void CStereoOVR::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_OriginalFrustum[cid]); +} + +void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoOVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); +} + +bool CStereoOVR::nextPass() +{ + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + // nlassert(width == m_DevicePtr->HMDInfo.HResolution); + // nlassert(height == m_DevicePtr->HMDInfo.VResolution); + + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) // Previous stage + { + case 0: + m_Stage += 2; + m_SubStage = 0; + // stage 2: + // draw interface 2d (onto render target) + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw scene right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endBloom) + // draw interface 3d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 3d right + return true; + /*case 6: + ++m_Stage; + m_SubStage = 0; + // stage 7: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 7: + ++m_Stage; + m_SubStage = 0; + // stage 8: + // draw interface 2d right + return true;*/ + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + nlerror("Invalid stage"); + m_Stage = 0; + m_SubStage = 0; + m_OrientationCached = false; + return false; +} + +const NL3D::CViewport &CStereoOVR::getCurrentViewport() const +{ + if (m_Stage == 2) return m_RegularViewport; + else if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const +{ + if (m_Stage == 2) return m_OriginalFrustum[cid]; + else if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; +} + +void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + if (m_Stage == 2) camera->setFrustum(m_OriginalFrustum[cid]); + else if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); +} + +void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{/* + CMatrix translate; + if (m_Stage == 2) { } + else if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + }*/ +} + +bool CStereoOVR::wantClear() +{ + switch (m_Stage) + { + case 3: + m_SubStage = 1; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantScene() +{ + switch (m_Stage) + { + case 3: + case 4: + m_SubStage = 2; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface3D() +{ + switch (m_Stage) + { + case 5: + case 6: + m_SubStage = 3; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface2D() +{ + switch (m_Stage) + { + case 2: + m_SubStage = 4; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +/// Returns non-NULL if a new render target was set +bool CStereoOVR::beginRenderTarget() +{ + // render target always set before driver clear + // nlassert(m_SubStage <= 1); + + // Set GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + nlassert(!m_GUITexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); + m_GUITexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height, true, UTexture::RGBA8888); + static_cast(m_Driver)->setRenderTarget(*m_GUITexture); + m_Driver->clearBuffers(NLMISC::CRGBA(0, 0, 0, 0)); + return true; + } + + // Begin 3D scene render target + /*if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + nlassert(!m_SceneTexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); // Temporary limitation, TODO: scaling! + m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); + return true; + }*/ + + return false; +} + +void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix) +{ + m_InterfaceCameraMatrix = matrix; +} + +void CStereoOVR::renderGUI() +{ + + /*CMatrix mat; + mat.translate(m_InterfaceCameraMatrix.getPos()); + CVector dir = m_InterfaceCameraMatrix.getJ(); + dir.z = 0; + dir.normalize(); + if (dir.y < 0) + mat.rotateZ(float(NLMISC::Pi+asin(dir.x))); + else + mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); + m_Driver->setModelMatrix(mat);*/ + m_Driver->setModelMatrix(m_InterfaceCameraMatrix); + + { + NLMISC::CLine line(NLMISC::CVector(0, 5, 2), NLMISC::CVector(0, 5, 3)); + + NL3D::UMaterial mat = m_Driver->createMaterial(); + mat.setZWrite(false); + // mat.setZFunc(UMaterial::always); // Not nice! + mat.setDoubleSided(true); + mat.setColor(NLMISC::CRGBA::Red); + mat.setBlend(false); + + m_Driver->drawLine(line, mat); + + m_Driver->deleteMaterial(mat); + } + + { + nlassert(m_GUITexture); + + NLMISC::CQuadUV quad; + + NL3D::UMaterial umat = m_Driver->createMaterial(); + umat.initUnlit(); + umat.setColor(NLMISC::CRGBA::White); + umat.setDoubleSided(true); + umat.setBlend(true); + umat.setAlphaTest(false); + NL3D::CMaterial *mat = umat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::Normal); + mat->setBlendFunc(CMaterial::one, CMaterial::invsrcalpha); + mat->setZWrite(false); + // mat->setZFunc(CMaterial::always); // Not nice + mat->setDoubleSided(true); + mat->setTexture(0, m_GUITexture->getITexture()); + + // user options + float scale = 1.0f; + float distance = 1.5f; + float offcenter = 0.75f; + + float height = scale * distance * 2.0f; + + uint32 winw, winh; + m_Driver->getWindowSize(winw, winh); + float width = height * (float)winw / (float)winh; + + float bottom = -(height * 0.5f); + float top = (height * 0.5f); + + NLMISC::CQuadUV quadUV; + quadUV.V0 = CVector(-(width * 0.5f), distance, -(height * 0.5f)); + quadUV.V1 = CVector((width * 0.5f), distance, -(height * 0.5f)); + quadUV.V2 = CVector((width * 0.5f), distance, (height * 0.5f)); + quadUV.V3 = CVector(-(width * 0.5f), distance, (height * 0.5f)); + quadUV.Uv0 = CUV(0.f, 0.f); + quadUV.Uv1 = CUV(1.f, 0.f); + quadUV.Uv2 = CUV(1.f, 1.f); + quadUV.Uv3 = CUV(0.f, 1.f); + + const uint nbQuads = 128; + static CVertexBuffer vb; + static CIndexBuffer ib; + + vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag); + vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false); + vb.setNumVertices((nbQuads + 1) * 2); + + { + CVertexBufferReadWrite vba; + vb.lock(vba); + float radius = distance + offcenter; + float relWidth = width / radius; + float quadWidth = relWidth / (float)nbQuads; + for (uint i = 0; i < nbQuads + 1; ++i) + { + uint vi0 = i * 2; + uint vi1 = vi0 + 1; + float lineH = -(relWidth * 0.5f) + quadWidth * (float)i; + float lineUV = (float)i / (float)(nbQuads); + float left = sin(lineH) * radius; + float forward = cos(lineH) * radius; + vba.setVertexCoord(vi0, left, forward - offcenter, bottom); + vba.setTexCoord(vi0, 0, lineUV, 0.0f); + vba.setVertexCoord(vi1, left, forward - offcenter, top); + vba.setTexCoord(vi1, 0, lineUV, 1.0f); + } + } + + ib.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); + ib.setPreferredMemory(CIndexBuffer::RAMVolatile, false); + ib.setNumIndexes(nbQuads * 6); + + { + CIndexBufferReadWrite iba; + ib.lock(iba); + for (uint i = 0; i < nbQuads; ++i) + { + uint ti0 = i * 2; + uint ti1 = ti0 + 1; + uint bl = ti0; + uint tl = ti0 + 1; + uint br = ti0 + 2; + uint tr = ti0 + 3; + iba.setTri(ti0 * 3, bl, tl, br); + iba.setTri(ti1 * 3, br, tl, tr); + } + } + + IDriver *driver = static_cast(m_Driver)->getDriver(); + // m_Driver->setPolygonMode(UDriver::Line); + driver->activeVertexBuffer(vb); + driver->activeIndexBuffer(ib); + driver->renderTriangles(*umat.getObjectPtr(), 0, nbQuads * 2); //renderRawQuads(umat, 0, 128); + // m_Driver->setPolygonMode(UDriver::Filled); + + // m_Driver->drawQuad(quadUV, umat); + + m_Driver->deleteMaterial(umat); + } +} + +/// Returns true if a render target was fully drawn +bool CStereoOVR::endRenderTarget() +{ + // after rendering of course + // nlassert(m_SubStage > 1); + + // End GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // End GUI render target + nlassert(m_GUITexture); + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + } + + // End of 3D Interface pass left + if (m_Driver && m_Stage == 5 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + } + + // End of 3D Interface pass right + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_GUITexture); + m_GUITexture = NULL; + } + + // End 3D scene render target + /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui + { + nlassert(m_SceneTexture); + + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_SceneTexture->getITexture()); + + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); + + float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset; + float lensViewportShift = 4.0f * lensShift / m_DevicePtr->HMDInfo.HScreenSize; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2); + float scaleY = (h / 2); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().Scale, + scaleX, scaleY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScaleIn, + scaleInX, scaleInY); + + + drvInternal->setUniform4fv(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().HmdWarpParam, + 1, m_DevicePtr->HMDInfo.DistortionK); + + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_SceneTexture); + m_SceneTexture = NULL; + + return true; + }*/ + + return false; +} + +NLMISC::CQuat CStereoOVR::getOrientation() const +{ + //if (m_OrientationCached) + return m_OrientationCache; +/* + OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat;*/ +} + +/// Get GUI shift +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const +{ + +} + +void CStereoOVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoOVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoOVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + +void CStereoOVR::listDevices(std::vector &devicesOut) +{ + /* + s_StereoOVRSystem.Init(); + OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); + uint id = 1; + do + { + CStereoDeviceInfo deviceInfoOut; + OVR::DeviceInfo deviceInfo; + if (devices.IsAvailable()) + { + devices.GetDeviceInfo(&deviceInfo); + CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + handle->DeviceHandle = devices; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice + deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; + deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; + deviceInfoOut.ProductName = deviceInfo.ProductName; + deviceInfoOut.AllowAuto = true; + stringstream ser; + ser << id; + deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... + devicesOut.push_back(deviceInfoOut); + ++id; + } + + } while (devices.Next());*/ +} + +bool CStereoOVR::isLibraryInUse() +{ + /*nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0;*/ + return false; +} + +void CStereoOVR::releaseLibrary() +{ + /*nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release();*/ +} + +bool CStereoOVR::isDeviceCreated() +{ + /*return m_DevicePtr->HMDDevice != NULL;*/ + return false; +} + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr_04_program.h b/code/nel/src/3d/stereo_ovr_04_program.h new file mode 100644 index 000000000..940be0bfe --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_04_program.h @@ -0,0 +1,249 @@ +/************************************************************************************ + +Filename : stereo_ovf_fp.cpp +Content : Barrel fragment program compiled to a blob of assembly +Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +namespace NL3D { +const char *g_StereoOVR_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile fp40 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile fp40 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 + "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! + " { 0.25, 0.5, 0 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "SHORT TEMP H0;\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" + "MULR R0.xy, R0, c[3];\n" + "MULR R0.z, R0.y, R0.y;\n" + "MADR R1.x, R0, R0, R0.z;\n" + "MULR R0.zw, R1.x, c[4].xywz;\n" + "MADR R1.y, R1.x, c[4], c[4].x;\n" + "MADR R0.w, R0, R1.x, R1.y;\n" + "MULR R0.z, R0, R1.x;\n" + "MADR R0.z, R0, R1.x, R0.w;\n" + "MULR R1.xy, R0, R0.z;\n" + "MOVR R0.xy, c[5];\n" + "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" + "MOVR R0.zw, c[0].xyxy;\n" + "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" + "MINR R1.xy, R0.zwzw, R1.zwzw;\n" + "ADDR R0.xy, -R0, c[1];\n" + "MAXR R0.xy, R0, R1;\n" + "SEQR H0.xy, R0, R0.zwzw;\n" + "MULXC HC.x, H0, H0.y;\n" + "IF EQ.x;\n" + "MOVR oCol, c[5].z;\n" + "ELSE;\n" + "TEX oCol, R0.zwzw, texture[0], 2D;\n" + "ENDIF;\n" + "END\n"; + //# 24 instructions, 2 R-regs, 1 H-regs + +const char *g_StereoOVR_arbfp1 = + "!!ARBfp1.0\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile arbfp1 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile arbfp1 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 1 + "PARAM c[6] = { program.env[0..4],\n" + " { 0.25, 0.5, 0, 1 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "ADD R0.xy, fragment.texcoord[0], -c[0];\n" + "MUL R0.xy, R0, c[3];\n" + "MUL R0.z, R0.y, R0.y;\n" + "MAD R0.z, R0.x, R0.x, R0;\n" + "MUL R0.w, R0.z, c[4];\n" + "MUL R0.w, R0, R0.z;\n" + "MAD R1.y, R0.z, c[4], c[4].x;\n" + "MUL R1.x, R0.z, c[4].z;\n" + "MAD R1.x, R0.z, R1, R1.y;\n" + "MAD R0.z, R0.w, R0, R1.x;\n" + "MUL R0.xy, R0, R0.z;\n" + "MOV R0.zw, c[5].xyxy;\n" + "ADD R1.xy, R0.zwzw, c[1];\n" + "MUL R0.xy, R0, c[2];\n" + "ADD R0.xy, R0, c[0];\n" + "MIN R1.xy, R1, R0;\n" + "ADD R0.zw, -R0, c[1].xyxy;\n" + "MAX R0.zw, R0, R1.xyxy;\n" + "ADD R0.zw, R0, -R0.xyxy;\n" + "ABS R0.zw, R0;\n" + "CMP R0.zw, -R0, c[5].z, c[5].w;\n" + "MUL R0.z, R0, R0.w;\n" + "ABS R0.z, R0;\n" + "CMP R0.z, -R0, c[5], c[5].w;\n" + "ABS R1.x, R0.z;\n" + "TEX R0, R0, texture[0], 2D;\n" + "CMP R1.x, -R1, c[5].z, c[5].w;\n" + "CMP result.color, -R1.x, R0, c[5].z;\n" + "END\n"; + //# 28 instructions, 2 R-regs + +const char *g_StereoOVR_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_oculus_vr.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_oculus_vr + //semantic pp_oculus_vr.cLensCenter + //semantic pp_oculus_vr.cScreenCenter + //semantic pp_oculus_vr.cScale + //semantic pp_oculus_vr.cScaleIn + //semantic pp_oculus_vr.cHmdWarpParam + //semantic pp_oculus_vr.cTex0 : TEX0 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float2 cLensCenter : : c[0] : 1 : 1 + //var float2 cScreenCenter : : c[1] : 2 : 1 + //var float2 cScale : : c[2] : 3 : 1 + //var float2 cScaleIn : : c[3] : 4 : 1 + //var float4 cHmdWarpParam : : c[4] : 5 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //var float4 oCol : $vout.COLOR : COL : 7 : 1 + //const c[5] = -0.25 -0.5 0.25 0.5 + //const c[6] = 1 0 + "dcl_2d s0\n" + "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" + "def c6, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "add r0.xy, t0, -c0\n" + "mul r4.xy, r0, c3\n" + "mul r0.x, r4.y, r4.y\n" + "mad r0.x, r4, r4, r0\n" + "mul r1.x, r0, c4.w\n" + "mul r1.x, r1, r0\n" + "mad r3.x, r0, c4.y, c4\n" + "mul r2.x, r0, c4.z\n" + "mad r2.x, r0, r2, r3\n" + "mad r0.x, r1, r0, r2\n" + "mul r0.xy, r4, r0.x\n" + "mul r0.xy, r0, c2\n" + "add r3.xy, r0, c0\n" + "mov r1.x, c5.z\n" + "mov r1.y, c5.w\n" + "mov r2.xy, c1\n" + "add r2.xy, r1, r2\n" + "mov r1.xy, c1\n" + "min r2.xy, r2, r3\n" + "add r1.xy, c5, r1\n" + "max r1.xy, r1, r2\n" + "add r1.xy, r1, -r3\n" + "abs r1.xy, r1\n" + "cmp r1.xy, -r1, c6.x, c6.y\n" + "mul_pp r1.x, r1, r1.y\n" + "abs_pp r1.x, r1\n" + "cmp_pp r1.x, -r1, c6, c6.y\n" + "abs_pp r1.x, r1\n" + "texld r0, r3, s0\n" + "cmp r0, -r1.x, r0, c6.y\n" + "mov oC0, r0\n"; + +const char *g_StereoOVR_glsl330f = + "#version 330\n" + "\n" + "bool _TMP2;\n" + "bvec2 _TMP1;\n" + "vec2 _TMP3;\n" + "uniform vec2 cLensCenter;\n" + "uniform vec2 cScreenCenter;\n" + "uniform vec2 cScale;\n" + "uniform vec2 cScaleIn;\n" + "uniform vec4 cHmdWarpParam;\n" + "uniform sampler2D nlTex0;\n" + "vec2 _TMP10;\n" + "vec2 _b0011;\n" + "vec2 _a0011;\n" + "in vec4 nlTexCoord0;\n" + "out vec4 nlCol;\n" + "\n" + "void main()\n" + "{\n" + " vec2 _theta;\n" + " float _rSq;\n" + " vec2 _theta1;\n" + " vec2 _tc;\n" + "\n" + " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" + " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" + " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" + " _tc = cLensCenter + cScale*_theta1;\n" + " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" + " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" + " _TMP3 = min(_b0011, _tc);\n" + " _TMP10 = max(_a0011, _TMP3);\n" + " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" + " _TMP2 = _TMP1.x && _TMP1.y;\n" + " if (!_TMP2) {\n" + " nlCol = vec4(0, 0, 0, 0);\n" + " } else {\n" + " nlCol = texture(nlTex0, _tc);\n" + " }\n" + "}\n"; + +} + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index 940be0bfe..84a74598e 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -21,6 +21,8 @@ limitations under the License. ************************************************************************************/ +#include "std3d.h" + namespace NL3D { const char *g_StereoOVR_fp40 = "!!ARBfp1.0\n" From b9e10fca72d8a7253d2dfceb3f28a06349c39ca6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 18:31:31 +0200 Subject: [PATCH 058/240] Cleanup --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 6 +++--- code/nel/src/3d/stereo_display.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index d58698066..655424dfc 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -41,8 +41,8 @@ * so, delete this exception statement from your version. */ -#ifndef NL3D_STEREO_OVR_H -#define NL3D_STEREO_OVR_H +#ifndef NL3D_STEREO_OVR_04_H +#define NL3D_STEREO_OVR_04_H #ifdef HAVE_LIBOVR @@ -180,6 +180,6 @@ private: #endif /* HAVE_LIBOVR */ -#endif /* #ifndef NL3D_STEREO_OVR_H */ +#endif /* #ifndef NL3D_STEREO_OVR_04_H */ /* end of file */ diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index 2ef8dca17..2a79c1039 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -77,7 +77,7 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { -#ifdef HAVE_LIBOVR_02 +#ifdef HAVE_LIBOVR CStereoOVR::listDevices(devicesOut); #endif #ifdef HAVE_LIBVR @@ -95,7 +95,7 @@ IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo void IStereoDisplay::releaseUnusedLibraries() { -#ifdef HAVE_LIBOVR_02 +#ifdef HAVE_LIBOVR if (!CStereoOVR::isLibraryInUse()) CStereoOVR::releaseLibrary(); #endif @@ -103,7 +103,7 @@ void IStereoDisplay::releaseUnusedLibraries() void IStereoDisplay::releaseAllLibraries() { -#ifdef HAVE_LIBOVR_02 +#ifdef HAVE_LIBOVR CStereoOVR::releaseLibrary(); #endif } From f2274d23785493cdccf817d6c92dae128c2e45ac Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 19:19:15 +0200 Subject: [PATCH 059/240] OVR: Iterate devices --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_display.h | 1 + code/nel/include/nel/3d/stereo_ovr_04.h | 7 +- code/nel/src/3d/stereo_ovr_04.cpp | 187 +++++++++-------- code/nel/src/3d/stereo_ovr_04_program.h | 247 +---------------------- code/ryzom/client/src/init.cpp | 12 +- 5 files changed, 118 insertions(+), 336 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 78db78e07..f796bccfe 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -130,6 +130,7 @@ public: virtual bool endRenderTarget() = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); + // List all devices. Device creation factories are no longer valid after re-calling this function static void listDevices(std::vector &devicesOut); static IStereoDisplay *createDevice(const CStereoDeviceInfo &deviceInfo); static void releaseUnusedLibraries(); diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 655424dfc..40ef4955b 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -64,8 +64,7 @@ namespace NL3D { class ITexture; class CTextureUser; -class CStereoOVRDevicePtr; -class CStereoOVRDeviceHandle; +class CStereoOVRDeviceFactory; /*class CPixelProgramOVR;*/ #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -79,7 +78,7 @@ class CStereoOVRDeviceHandle; class CStereoOVR : public IStereoHMD { public: - CStereoOVR(const CStereoOVRDeviceHandle *handle); + CStereoOVR(const CStereoOVRDeviceFactory *handle); virtual ~CStereoOVR(); /// Sets driver and generates necessary render targets @@ -150,7 +149,7 @@ public: static void releaseLibrary(); private: - CStereoOVRDevicePtr *m_DevicePtr; + // CStereoOVRDevicePtr *m_DevicePtr; int m_Stage; int m_SubStage; CViewport m_RegularViewport; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 5751af285..d31d1a82e 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -70,87 +70,70 @@ using namespace std; namespace NL3D { -/*extern const char *g_StereoOVR_fp40; -extern const char *g_StereoOVR_arbfp1; -extern const char *g_StereoOVR_ps_2_0; -extern const char *g_StereoOVR_glsl330f;*/ - namespace { -/* -class CStereoOVRLog : public OVR::Log + +#include "stereo_ovr_04_program.h" + +class CStereoOVRSystem { public: - CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) + CStereoOVRSystem() : m_InitOk(false) { } - virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) + ~CStereoOVRSystem() { - if (NLMISC::INelContext::isContextInitialised()) + if (m_InitOk) { - char buffer[MaxLogBufferMessageSize]; - FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); - if (IsDebugMessage(messageType)) - NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); - else - NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); + nlwarning("OVR: Not all resources were released before exit"); + Release(); } } -}; - -CStereoOVRLog *s_StereoOVRLog = NULL; -OVR::Ptr s_DeviceManager; -class CStereoOVRSystem -{ -public: - ~CStereoOVRSystem() + bool Init() { - Release(); - } - - void Init() - { - if (!s_StereoOVRLog) + if (!m_InitOk) { - nldebug("Initialize OVR"); - s_StereoOVRLog = new CStereoOVRLog(); + nldebug("OVR: Initialize"); + m_InitOk = ovr_Initialize(); + nlassert(m_InitOk); } - if (!OVR::System::IsInitialized()) - OVR::System::Init(s_StereoOVRLog); - if (!s_DeviceManager) - s_DeviceManager = OVR::DeviceManager::Create(); + + return m_InitOk; } void Release() { - if (s_DeviceManager) + if (m_InitOk) { - nldebug("Release OVR"); - s_DeviceManager->Release(); + nldebug("OVR: Release"); + ovr_Shutdown(); + m_InitOk = false; } - s_DeviceManager.Clear(); - if (OVR::System::IsInitialized()) - OVR::System::Destroy(); - if (s_StereoOVRLog) - nldebug("Release OVR Ok"); - delete s_StereoOVRLog; - s_StereoOVRLog = NULL; } + +private: + bool m_InitOk; + }; CStereoOVRSystem s_StereoOVRSystem; sint s_DeviceCounter = 0; -*/ +uint s_DetectId = 0; + } -/* -class CStereoOVRDeviceHandle : public IStereoDeviceFactory + +class CStereoOVRDeviceFactory : public IStereoDeviceFactory { public: - // fixme: virtual destructor??? - OVR::DeviceEnumerator DeviceHandle; + uint DeviceIndex; + uint DetectId; + + bool DebugDevice; + ovrHmdType DebugDeviceType; + IStereoDisplay *createDevice() const { CStereoOVR *stereo = new CStereoOVR(this); @@ -161,6 +144,7 @@ public: } }; +/* class CStereoOVRDevicePtr { public: @@ -170,7 +154,8 @@ public: OVR::HMDInfo HMDInfo; }; */ -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) + +CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { /*++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -958,48 +943,84 @@ void CStereoOVR::setScale(float s) m_Scale = s; } + + void CStereoOVR::listDevices(std::vector &devicesOut) { - /* - s_StereoOVRSystem.Init(); - OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); - uint id = 1; - do - { - CStereoDeviceInfo deviceInfoOut; - OVR::DeviceInfo deviceInfo; - if (devices.IsAvailable()) - { - devices.GetDeviceInfo(&deviceInfo); - CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); - deviceInfoOut.Factory = static_cast(handle); - handle->DeviceHandle = devices; - deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice - deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; - deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; - deviceInfoOut.ProductName = deviceInfo.ProductName; - deviceInfoOut.AllowAuto = true; - stringstream ser; - ser << id; - deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... - devicesOut.push_back(deviceInfoOut); - ++id; - } + if (!s_StereoOVRSystem.Init()) + return; + + ++s_DetectId; + uint hmdDetect = ovrHmd_Detect(); + nldebug("OVR: Detected %u HMDs", hmdDetect); - } while (devices.Next());*/ + for (uint i = 0; i < hmdDetect; ++i) + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_Create(i); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DetectId = s_DetectId; + factory->DeviceIndex = i; + factory->DebugDevice = false; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = true; + deviceInfoOut.Serial = hmd->SerialNumber; + ovrHmd_Destroy(hmd); + } + +#if !FINAL_VERSION + // Debug DK1 + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK1); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DebugDevice = true; + factory->DebugDeviceType = ovrHmd_DK1; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = false; + deviceInfoOut.Serial = "OVR-DK1-DEBUG"; + ovrHmd_Destroy(hmd); + } + // Debug DK2 + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DebugDevice = true; + factory->DebugDeviceType = ovrHmd_DK2; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = false; + deviceInfoOut.Serial = "OVR-DK2-DEBUG"; + ovrHmd_Destroy(hmd); + } +#endif } bool CStereoOVR::isLibraryInUse() { - /*nlassert(s_DeviceCounter >= 0); - return s_DeviceCounter > 0;*/ - return false; + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; } void CStereoOVR::releaseLibrary() { - /*nlassert(s_DeviceCounter == 0); - s_StereoOVRSystem.Release();*/ + nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release(); } bool CStereoOVR::isDeviceCreated() diff --git a/code/nel/src/3d/stereo_ovr_04_program.h b/code/nel/src/3d/stereo_ovr_04_program.h index 940be0bfe..f8c253aeb 100644 --- a/code/nel/src/3d/stereo_ovr_04_program.h +++ b/code/nel/src/3d/stereo_ovr_04_program.h @@ -1,249 +1,4 @@ -/************************************************************************************ -Filename : stereo_ovf_fp.cpp -Content : Barrel fragment program compiled to a blob of assembly -Created : July 01, 2013 -Modified by : Jan Boon (Kaetemi) - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -namespace NL3D { -const char *g_StereoOVR_fp40 = - "!!ARBfp1.0\n" - "OPTION NV_fragment_program2;\n" - //# cgc version 3.1.0013, build date Apr 18 2012 - //# command line args: -profile fp40 - //# source file: pp_oculus_vr.cg - //#vendor NVIDIA Corporation - //#version 3.1.0.13 - //#profile fp40 - //#program pp_oculus_vr - //#semantic pp_oculus_vr.cLensCenter - //#semantic pp_oculus_vr.cScreenCenter - //#semantic pp_oculus_vr.cScale - //#semantic pp_oculus_vr.cScaleIn - //#semantic pp_oculus_vr.cHmdWarpParam - //#semantic pp_oculus_vr.cTex0 : TEX0 - //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //#var float2 cLensCenter : : c[0] : 1 : 1 - //#var float2 cScreenCenter : : c[1] : 2 : 1 - //#var float2 cScale : : c[2] : 3 : 1 - //#var float2 cScaleIn : : c[3] : 4 : 1 - //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //#var float4 oCol : $vout.COLOR : COL : 7 : 1 - //#const c[5] = 0.25 0.5 0 - "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! - " { 0.25, 0.5, 0 } };\n" - "TEMP R0;\n" - "TEMP R1;\n" - "SHORT TEMP H0;\n" - "TEMP RC;\n" - "TEMP HC;\n" - "OUTPUT oCol = result.color;\n" - "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" - "MULR R0.xy, R0, c[3];\n" - "MULR R0.z, R0.y, R0.y;\n" - "MADR R1.x, R0, R0, R0.z;\n" - "MULR R0.zw, R1.x, c[4].xywz;\n" - "MADR R1.y, R1.x, c[4], c[4].x;\n" - "MADR R0.w, R0, R1.x, R1.y;\n" - "MULR R0.z, R0, R1.x;\n" - "MADR R0.z, R0, R1.x, R0.w;\n" - "MULR R1.xy, R0, R0.z;\n" - "MOVR R0.xy, c[5];\n" - "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" - "MOVR R0.zw, c[0].xyxy;\n" - "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" - "MINR R1.xy, R0.zwzw, R1.zwzw;\n" - "ADDR R0.xy, -R0, c[1];\n" - "MAXR R0.xy, R0, R1;\n" - "SEQR H0.xy, R0, R0.zwzw;\n" - "MULXC HC.x, H0, H0.y;\n" - "IF EQ.x;\n" - "MOVR oCol, c[5].z;\n" - "ELSE;\n" - "TEX oCol, R0.zwzw, texture[0], 2D;\n" - "ENDIF;\n" - "END\n"; - //# 24 instructions, 2 R-regs, 1 H-regs - -const char *g_StereoOVR_arbfp1 = - "!!ARBfp1.0\n" - //# cgc version 3.1.0013, build date Apr 18 2012 - //# command line args: -profile arbfp1 - //# source file: pp_oculus_vr.cg - //#vendor NVIDIA Corporation - //#version 3.1.0.13 - //#profile arbfp1 - //#program pp_oculus_vr - //#semantic pp_oculus_vr.cLensCenter - //#semantic pp_oculus_vr.cScreenCenter - //#semantic pp_oculus_vr.cScale - //#semantic pp_oculus_vr.cScaleIn - //#semantic pp_oculus_vr.cHmdWarpParam - //#semantic pp_oculus_vr.cTex0 : TEX0 - //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //#var float2 cLensCenter : : c[0] : 1 : 1 - //#var float2 cScreenCenter : : c[1] : 2 : 1 - //#var float2 cScale : : c[2] : 3 : 1 - //#var float2 cScaleIn : : c[3] : 4 : 1 - //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //#var float4 oCol : $vout.COLOR : COL : 7 : 1 - //#const c[5] = 0.25 0.5 0 1 - "PARAM c[6] = { program.env[0..4],\n" - " { 0.25, 0.5, 0, 1 } };\n" - "TEMP R0;\n" - "TEMP R1;\n" - "ADD R0.xy, fragment.texcoord[0], -c[0];\n" - "MUL R0.xy, R0, c[3];\n" - "MUL R0.z, R0.y, R0.y;\n" - "MAD R0.z, R0.x, R0.x, R0;\n" - "MUL R0.w, R0.z, c[4];\n" - "MUL R0.w, R0, R0.z;\n" - "MAD R1.y, R0.z, c[4], c[4].x;\n" - "MUL R1.x, R0.z, c[4].z;\n" - "MAD R1.x, R0.z, R1, R1.y;\n" - "MAD R0.z, R0.w, R0, R1.x;\n" - "MUL R0.xy, R0, R0.z;\n" - "MOV R0.zw, c[5].xyxy;\n" - "ADD R1.xy, R0.zwzw, c[1];\n" - "MUL R0.xy, R0, c[2];\n" - "ADD R0.xy, R0, c[0];\n" - "MIN R1.xy, R1, R0;\n" - "ADD R0.zw, -R0, c[1].xyxy;\n" - "MAX R0.zw, R0, R1.xyxy;\n" - "ADD R0.zw, R0, -R0.xyxy;\n" - "ABS R0.zw, R0;\n" - "CMP R0.zw, -R0, c[5].z, c[5].w;\n" - "MUL R0.z, R0, R0.w;\n" - "ABS R0.z, R0;\n" - "CMP R0.z, -R0, c[5], c[5].w;\n" - "ABS R1.x, R0.z;\n" - "TEX R0, R0, texture[0], 2D;\n" - "CMP R1.x, -R1, c[5].z, c[5].w;\n" - "CMP result.color, -R1.x, R0, c[5].z;\n" - "END\n"; - //# 28 instructions, 2 R-regs - -const char *g_StereoOVR_ps_2_0 = - "ps_2_0\n" - // cgc version 3.1.0013, build date Apr 18 2012 - // command line args: -profile ps_2_0 - // source file: pp_oculus_vr.cg - //vendor NVIDIA Corporation - //version 3.1.0.13 - //profile ps_2_0 - //program pp_oculus_vr - //semantic pp_oculus_vr.cLensCenter - //semantic pp_oculus_vr.cScreenCenter - //semantic pp_oculus_vr.cScale - //semantic pp_oculus_vr.cScaleIn - //semantic pp_oculus_vr.cHmdWarpParam - //semantic pp_oculus_vr.cTex0 : TEX0 - //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //var float2 cLensCenter : : c[0] : 1 : 1 - //var float2 cScreenCenter : : c[1] : 2 : 1 - //var float2 cScale : : c[2] : 3 : 1 - //var float2 cScaleIn : : c[3] : 4 : 1 - //var float4 cHmdWarpParam : : c[4] : 5 : 1 - //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //var float4 oCol : $vout.COLOR : COL : 7 : 1 - //const c[5] = -0.25 -0.5 0.25 0.5 - //const c[6] = 1 0 - "dcl_2d s0\n" - "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" - "def c6, 1.00000000, 0.00000000, 0, 0\n" - "dcl t0.xy\n" - "add r0.xy, t0, -c0\n" - "mul r4.xy, r0, c3\n" - "mul r0.x, r4.y, r4.y\n" - "mad r0.x, r4, r4, r0\n" - "mul r1.x, r0, c4.w\n" - "mul r1.x, r1, r0\n" - "mad r3.x, r0, c4.y, c4\n" - "mul r2.x, r0, c4.z\n" - "mad r2.x, r0, r2, r3\n" - "mad r0.x, r1, r0, r2\n" - "mul r0.xy, r4, r0.x\n" - "mul r0.xy, r0, c2\n" - "add r3.xy, r0, c0\n" - "mov r1.x, c5.z\n" - "mov r1.y, c5.w\n" - "mov r2.xy, c1\n" - "add r2.xy, r1, r2\n" - "mov r1.xy, c1\n" - "min r2.xy, r2, r3\n" - "add r1.xy, c5, r1\n" - "max r1.xy, r1, r2\n" - "add r1.xy, r1, -r3\n" - "abs r1.xy, r1\n" - "cmp r1.xy, -r1, c6.x, c6.y\n" - "mul_pp r1.x, r1, r1.y\n" - "abs_pp r1.x, r1\n" - "cmp_pp r1.x, -r1, c6, c6.y\n" - "abs_pp r1.x, r1\n" - "texld r0, r3, s0\n" - "cmp r0, -r1.x, r0, c6.y\n" - "mov oC0, r0\n"; - -const char *g_StereoOVR_glsl330f = - "#version 330\n" - "\n" - "bool _TMP2;\n" - "bvec2 _TMP1;\n" - "vec2 _TMP3;\n" - "uniform vec2 cLensCenter;\n" - "uniform vec2 cScreenCenter;\n" - "uniform vec2 cScale;\n" - "uniform vec2 cScaleIn;\n" - "uniform vec4 cHmdWarpParam;\n" - "uniform sampler2D nlTex0;\n" - "vec2 _TMP10;\n" - "vec2 _b0011;\n" - "vec2 _a0011;\n" - "in vec4 nlTexCoord0;\n" - "out vec4 nlCol;\n" - "\n" - "void main()\n" - "{\n" - " vec2 _theta;\n" - " float _rSq;\n" - " vec2 _theta1;\n" - " vec2 _tc;\n" - "\n" - " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" - " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" - " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" - " _tc = cLensCenter + cScale*_theta1;\n" - " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" - " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" - " _TMP3 = min(_b0011, _tc);\n" - " _TMP10 = max(_a0011, _TMP3);\n" - " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" - " _TMP2 = _TMP1.x && _TMP1.y;\n" - " if (!_TMP2) {\n" - " nlCol = vec4(0, 0, 0, 0);\n" - " } else {\n" - " nlCol = texture(nlTex0, _tc);\n" - " }\n" - "}\n"; - -} +// TODO /* end of file */ diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 5f0da0136..1644f7e2d 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -616,10 +616,16 @@ void initStereoDisplayDevice() std::vector devices; listStereoDisplayDevices(devices); CStereoDeviceInfo *deviceInfo = NULL; - if (ClientCfg.VRDisplayDevice == std::string("Auto") - && devices.begin() != devices.end()) + if (ClientCfg.VRDisplayDevice == std::string("Auto")) { - deviceInfo = &devices[0]; + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + if ((*it).AllowAuto) + { + deviceInfo = &(*it); + break; + } + } } else { From 99ea2c685cc508e079299c6f6caaa3e5ddaea07c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 20:32:31 +0200 Subject: [PATCH 060/240] OVR: Read device descriptions --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 15 ++- code/nel/src/3d/stereo_ovr_04.cpp | 161 +++++++++++++++--------- 2 files changed, 116 insertions(+), 60 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 40ef4955b..ff76a128e 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -60,6 +60,9 @@ #include #include +struct ovrHmdDesc_; +typedef const ovrHmdDesc_ *ovrHmd; + namespace NL3D { class ITexture; @@ -68,6 +71,7 @@ class CStereoOVRDeviceFactory; /*class CPixelProgramOVR;*/ #define NL_STEREO_MAX_USER_CAMERAS 8 +#define NL_OVR_EYE_COUNT 2 /** * \brief CStereoOVR @@ -78,7 +82,7 @@ class CStereoOVRDeviceFactory; class CStereoOVR : public IStereoHMD { public: - CStereoOVR(const CStereoOVRDeviceFactory *handle); + CStereoOVR(const CStereoOVRDeviceFactory *factory); virtual ~CStereoOVR(); /// Sets driver and generates necessary render targets @@ -149,12 +153,15 @@ public: static void releaseLibrary(); private: - // CStereoOVRDevicePtr *m_DevicePtr; + ovrHmd m_DevicePtr; int m_Stage; int m_SubStage; CViewport m_RegularViewport; - CViewport m_LeftViewport; - CViewport m_RightViewport; + CViewport m_EyeViewport[NL_OVR_EYE_COUNT]; + float m_EyeHFov[NL_OVR_EYE_COUNT]; + float m_EyeAR[NL_OVR_EYE_COUNT]; + uint m_RenderTargetWidth; + uint m_RenderTargetHeight; CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index d31d1a82e..496fe6b99 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -144,52 +144,105 @@ public: } }; -/* -class CStereoOVRDevicePtr +CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { -public: - OVR::Ptr HMDDevice; - OVR::Ptr SensorDevice; - OVR::SensorFusion SensorFusion; - OVR::HMDInfo HMDInfo; -}; -*/ + nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count); -CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) -{ - /*++s_DeviceCounter; - m_DevicePtr = new CStereoOVRDevicePtr(); + if (factory->DetectId != s_DetectId) + { + nlwarning("OVR: Previous device info structures become invalid after listing devices"); + return; + } - OVR::DeviceEnumerator dh = handle->DeviceHandle; - m_DevicePtr->HMDDevice = dh.CreateDevice(); + if (factory->DebugDevice) m_DevicePtr = ovrHmd_CreateDebug(factory->DebugDeviceType); + else m_DevicePtr = ovrHmd_Create(factory->DeviceIndex); - if (m_DevicePtr->HMDDevice) + if (!m_DevicePtr) { - m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo); - nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); - nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); - nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); - nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); - nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); - nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); - nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); - nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000 - //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000 - m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); - m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); - m_DevicePtr->SensorFusion.SetGravityEnabled(true); - m_DevicePtr->SensorFusion.SetPredictionEnabled(true); - m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); - m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); - m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); - }*/ + nlwarning("OVR: Device not created"); + return; + } + + ++s_DeviceCounter; + + // nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); // No more support for physically non-square pixels? + // nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); + // nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); + // nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); + // nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); + nldebug("OVR: Resolution.w: %i, Resolution.h: %i", m_DevicePtr->Resolution.w, m_DevicePtr->Resolution.h); + // nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); + // nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); + + if (!ovrHmd_ConfigureTracking(m_DevicePtr, + ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection, // | ovrTrackingCap_Position + ovrTrackingCap_Orientation)) + { + nlwarning("OVR: Cannot configure tracking"); + ovrHmd_Destroy(m_DevicePtr); + m_DevicePtr = NULL; + --s_DeviceCounter; + return; + } + + float nativeWidth = m_DevicePtr->Resolution.w; + float nativeHeight = m_DevicePtr->Resolution.h; + + ovrEyeRenderDesc eyeRenderDesc[ovrEye_Count]; + eyeRenderDesc[ovrEye_Left] = ovrHmd_GetRenderDesc(m_DevicePtr, ovrEye_Left, m_DevicePtr->DefaultEyeFov[ovrEye_Left]); + eyeRenderDesc[ovrEye_Right] = ovrHmd_GetRenderDesc(m_DevicePtr, ovrEye_Right, m_DevicePtr->DefaultEyeFov[ovrEye_Right]); + + nldebug("OVR: LEFT DistortedViewport: x: %i, y: %i, w: %i, h: %i", eyeRenderDesc[0].DistortedViewport.Pos.x, eyeRenderDesc[0].DistortedViewport.Pos.y, eyeRenderDesc[0].DistortedViewport.Size.w, eyeRenderDesc[0].DistortedViewport.Size.h); + nldebug("OVR: LEFT PixelsPerTanAngleAtCenter: x: %f, y: %f ", eyeRenderDesc[0].PixelsPerTanAngleAtCenter.x, eyeRenderDesc[0].PixelsPerTanAngleAtCenter.y); + nldebug("OVR: LEFT ViewAdjust: x: %f, y: %f, z: %f ", eyeRenderDesc[0].ViewAdjust.x, eyeRenderDesc[0].ViewAdjust.y, eyeRenderDesc[0].ViewAdjust.z); + nldebug("OVR: RIGHT DistortedViewport: x: %i, y: %i, w: %i, h: %i", eyeRenderDesc[1].DistortedViewport.Pos.x, eyeRenderDesc[1].DistortedViewport.Pos.y, eyeRenderDesc[1].DistortedViewport.Size.w, eyeRenderDesc[1].DistortedViewport.Size.h); + nldebug("OVR: RIGHT PixelsPerTanAngleAtCenter: x: %f, y: %f ", eyeRenderDesc[1].PixelsPerTanAngleAtCenter.x, eyeRenderDesc[1].PixelsPerTanAngleAtCenter.y); + nldebug("OVR: RIGHT ViewAdjust: x: %f, y: %f, z: %f ", eyeRenderDesc[1].ViewAdjust.x, eyeRenderDesc[1].ViewAdjust.y, eyeRenderDesc[1].ViewAdjust.z); + + // 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 171 NL3D::CStereoOVR::CStereoOVR : OVR: Resolution.w: 1280, Resolution.h: 800 + // 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 189 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT DistortedViewport: x: 0, y: 0, w: 640, h: 800 + // 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 190 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT PixelsPerTanAngleAtCenter: x: 363.247864, y: 363.247864 + // 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 191 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT ViewAdjust: x: 0.031800, y: 0.000000, z: 0.000000 + // 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 192 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT DistortedViewport: x: 640, y: 0, w: 640, h: 800 + // 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 193 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT PixelsPerTanAngleAtCenter: x: 363.247864, y: 363.247864 + // 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 194 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT ViewAdjust: x: -0.031868, y: 0.000000, z: 0.000000 + + ovrSizei fovTexLeftSize = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Left, eyeRenderDesc[ovrEye_Left].Fov, 1.0f); + ovrSizei fovTexRightSize = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Right, eyeRenderDesc[ovrEye_Right].Fov, 1.0f); + m_RenderTargetWidth = fovTexLeftSize.w + fovTexRightSize.w; + m_RenderTargetHeight = max(fovTexLeftSize.h, fovTexRightSize.h); + nldebug("OVR: RenderTarget: w: %u, h: %u", m_RenderTargetWidth, m_RenderTargetHeight); + + // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 213 NL3D::CStereoOVR::CStereoOVR : OVR: RenderTarget: w: 2414, h: 1870 // That looks a bit excessive... + + for (uint eye = 0; eye < ovrEye_Count; ++eye) + { + ovrFovPort &fov = eyeRenderDesc[eye].Fov; + + m_EyeViewport[eye].init( + (float)eyeRenderDesc[eye].DistortedViewport.Pos.x / nativeWidth, + (float)eyeRenderDesc[eye].DistortedViewport.Pos.y / nativeHeight, + (float)eyeRenderDesc[eye].DistortedViewport.Size.w / nativeWidth, + (float)eyeRenderDesc[eye].DistortedViewport.Size.h / nativeHeight); + nldebug("OVR: EyeViewport: x: %f, y: %f, w: %f, h: %f", m_EyeViewport[eye].getX(), m_EyeViewport[eye].getY(), m_EyeViewport[eye].getWidth(), m_EyeViewport[eye].getHeight()); + + float combinedTanHalfFovHorizontal = max(fov.LeftTan, fov.RightTan); + float combinedTanHalfFovVertical = max(fov.UpTan, fov.DownTan); + float horizontalFullFovInRadians = 2.0f * atanf (combinedTanHalfFovHorizontal); + float aspectRatio = combinedTanHalfFovHorizontal / combinedTanHalfFovVertical; + m_EyeHFov[eye] = horizontalFullFovInRadians; + m_EyeAR[eye] = aspectRatio; + nldebug("OVR: FOV: %f, AR: %f", horizontalFullFovInRadians, aspectRatio); + } + + // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.000000, y: 0.000000, w: 0.500000, h: 1.000000 + // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.500000, y: 0.000000, w: 0.500000, h: 1.000000 + + // DEBUG EARLY EXIT + nldebug("OVR: Early exit"); + ovrHmd_Destroy(m_DevicePtr); + m_DevicePtr = NULL; + --s_DeviceCounter; } CStereoOVR::~CStereoOVR() @@ -203,18 +256,14 @@ CStereoOVR::~CStereoOVR() delete m_PixelProgram; m_PixelProgram = NULL; - m_Driver = NULL; + m_Driver = NULL;*/ - if (m_DevicePtr->SensorDevice) - m_DevicePtr->SensorDevice->Release(); - m_DevicePtr->SensorDevice.Clear(); - if (m_DevicePtr->HMDDevice) - m_DevicePtr->HMDDevice->Release(); - m_DevicePtr->HMDDevice.Clear(); - - delete m_DevicePtr; - m_DevicePtr = NULL; - --s_DeviceCounter;*/ + if (m_DevicePtr) + { + ovrHmd_Destroy(m_DevicePtr); + m_DevicePtr = NULL; + --s_DeviceCounter; + } } /* class CPixelProgramOVR : public CPixelProgram @@ -304,6 +353,7 @@ private: }; */ + void CStereoOVR::setDriver(NL3D::UDriver *driver) {/* nlassert(!m_PixelProgram); @@ -516,8 +566,8 @@ bool CStereoOVR::nextPass() const NL3D::CViewport &CStereoOVR::getCurrentViewport() const { if (m_Stage == 2) return m_RegularViewport; - else if (m_Stage % 2) return m_LeftViewport; - else return m_RightViewport; + else if (m_Stage % 2) return m_EyeViewport[ovrEye_Left]; + else return m_EyeViewport[ovrEye_Right]; } const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const @@ -1025,8 +1075,7 @@ void CStereoOVR::releaseLibrary() bool CStereoOVR::isDeviceCreated() { - /*return m_DevicePtr->HMDDevice != NULL;*/ - return false; + return m_DevicePtr != NULL; } } /* namespace NL3D */ From 262c1f84a9e86952316f26be747add97fe3412fb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 00:20:21 +0200 Subject: [PATCH 061/240] OVR: Generate distortion mesh --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 23 +- code/nel/src/3d/stereo_ovr_04.cpp | 280 +++++++++++++++--------- 2 files changed, 198 insertions(+), 105 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index ff76a128e..5c5f73a6b 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -59,6 +59,8 @@ #include #include #include +#include +#include struct ovrHmdDesc_; typedef const ovrHmdDesc_ *ovrHmd; @@ -68,7 +70,8 @@ namespace NL3D { class ITexture; class CTextureUser; class CStereoOVRDeviceFactory; -/*class CPixelProgramOVR;*/ +class CPixelProgramOVR; +class CVertexProgramOVR; #define NL_STEREO_MAX_USER_CAMERAS 8 #define NL_OVR_EYE_COUNT 2 @@ -154,14 +157,22 @@ public: private: ovrHmd m_DevicePtr; + int m_Stage; int m_SubStage; + CViewport m_RegularViewport; CViewport m_EyeViewport[NL_OVR_EYE_COUNT]; float m_EyeHFov[NL_OVR_EYE_COUNT]; float m_EyeAR[NL_OVR_EYE_COUNT]; uint m_RenderTargetWidth; uint m_RenderTargetHeight; + NLMISC::CVector2f m_EyeUVScaleOffset[NL_OVR_EYE_COUNT][2]; + + CVertexBuffer m_VB; + CIndexBuffer m_IB; + uint m_NbTris; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; @@ -170,8 +181,16 @@ private: CMatrix m_InterfaceCameraMatrix; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; - NL3D::CTextureUser *m_GUITexture; + + CTextureUser *m_GUITexture; + + UMaterial m_UnlitMat; + NLMISC::CRefPtr m_VP; + NLMISC::CRefPtr m_PP; + + /*NL3D::CTextureUser *m_SceneTexture; NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 496fe6b99..2238c3d16 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -188,10 +188,10 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL float nativeWidth = m_DevicePtr->Resolution.w; float nativeHeight = m_DevicePtr->Resolution.h; + // get render descriptions for default fov ovrEyeRenderDesc eyeRenderDesc[ovrEye_Count]; eyeRenderDesc[ovrEye_Left] = ovrHmd_GetRenderDesc(m_DevicePtr, ovrEye_Left, m_DevicePtr->DefaultEyeFov[ovrEye_Left]); eyeRenderDesc[ovrEye_Right] = ovrHmd_GetRenderDesc(m_DevicePtr, ovrEye_Right, m_DevicePtr->DefaultEyeFov[ovrEye_Right]); - nldebug("OVR: LEFT DistortedViewport: x: %i, y: %i, w: %i, h: %i", eyeRenderDesc[0].DistortedViewport.Pos.x, eyeRenderDesc[0].DistortedViewport.Pos.y, eyeRenderDesc[0].DistortedViewport.Size.w, eyeRenderDesc[0].DistortedViewport.Size.h); nldebug("OVR: LEFT PixelsPerTanAngleAtCenter: x: %f, y: %f ", eyeRenderDesc[0].PixelsPerTanAngleAtCenter.x, eyeRenderDesc[0].PixelsPerTanAngleAtCenter.y); nldebug("OVR: LEFT ViewAdjust: x: %f, y: %f, z: %f ", eyeRenderDesc[0].ViewAdjust.x, eyeRenderDesc[0].ViewAdjust.y, eyeRenderDesc[0].ViewAdjust.z); @@ -207,10 +207,12 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL // 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 193 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT PixelsPerTanAngleAtCenter: x: 363.247864, y: 363.247864 // 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 194 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT ViewAdjust: x: -0.031868, y: 0.000000, z: 0.000000 - ovrSizei fovTexLeftSize = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Left, eyeRenderDesc[ovrEye_Left].Fov, 1.0f); - ovrSizei fovTexRightSize = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Right, eyeRenderDesc[ovrEye_Right].Fov, 1.0f); - m_RenderTargetWidth = fovTexLeftSize.w + fovTexRightSize.w; - m_RenderTargetHeight = max(fovTexLeftSize.h, fovTexRightSize.h); + // find out the recommended render target size + ovrSizei fovTextureSize[ovrEye_Count]; + fovTextureSize[ovrEye_Left] = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Left, eyeRenderDesc[ovrEye_Left].Fov, 1.0f); + fovTextureSize[ovrEye_Right] = ovrHmd_GetFovTextureSize(m_DevicePtr, ovrEye_Right, eyeRenderDesc[ovrEye_Right].Fov, 1.0f); + m_RenderTargetWidth = fovTextureSize[ovrEye_Left].w + fovTextureSize[ovrEye_Right].w; + m_RenderTargetHeight = max(fovTextureSize[ovrEye_Left].h, fovTextureSize[ovrEye_Right].h); nldebug("OVR: RenderTarget: w: %u, h: %u", m_RenderTargetWidth, m_RenderTargetHeight); // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 213 NL3D::CStereoOVR::CStereoOVR : OVR: RenderTarget: w: 2414, h: 1870 // That looks a bit excessive... @@ -218,25 +220,91 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL for (uint eye = 0; eye < ovrEye_Count; ++eye) { ovrFovPort &fov = eyeRenderDesc[eye].Fov; - + + // setup viewport m_EyeViewport[eye].init( (float)eyeRenderDesc[eye].DistortedViewport.Pos.x / nativeWidth, (float)eyeRenderDesc[eye].DistortedViewport.Pos.y / nativeHeight, (float)eyeRenderDesc[eye].DistortedViewport.Size.w / nativeWidth, (float)eyeRenderDesc[eye].DistortedViewport.Size.h / nativeHeight); nldebug("OVR: EyeViewport: x: %f, y: %f, w: %f, h: %f", m_EyeViewport[eye].getX(), m_EyeViewport[eye].getY(), m_EyeViewport[eye].getWidth(), m_EyeViewport[eye].getHeight()); - + ovrRecti eyeViewport; + eyeViewport.Pos.x = (eyeRenderDesc[eye].DistortedViewport.Pos.x * m_RenderTargetWidth) / m_DevicePtr->Resolution.w; + eyeViewport.Pos.y = (eyeRenderDesc[eye].DistortedViewport.Pos.y * m_RenderTargetHeight) / m_DevicePtr->Resolution.h; + eyeViewport.Size.w = (eyeRenderDesc[eye].DistortedViewport.Size.w * m_RenderTargetWidth) / m_DevicePtr->Resolution.w; + eyeViewport.Size.h = (eyeRenderDesc[eye].DistortedViewport.Size.h * m_RenderTargetHeight) / m_DevicePtr->Resolution.h; + + // calculate hfov and ar float combinedTanHalfFovHorizontal = max(fov.LeftTan, fov.RightTan); float combinedTanHalfFovVertical = max(fov.UpTan, fov.DownTan); float horizontalFullFovInRadians = 2.0f * atanf (combinedTanHalfFovHorizontal); float aspectRatio = combinedTanHalfFovHorizontal / combinedTanHalfFovVertical; m_EyeHFov[eye] = horizontalFullFovInRadians; m_EyeAR[eye] = aspectRatio; - nldebug("OVR: FOV: %f, AR: %f", horizontalFullFovInRadians, aspectRatio); + nldebug("OVR: HFOV: %f, AR: %f", horizontalFullFovInRadians, aspectRatio); + + // get distortion mesh + ovrDistortionMesh meshData; + ovrHmd_CreateDistortionMesh(m_DevicePtr, (ovrEyeType)eye, fov, + ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette, + &meshData); + ovrVector2f uvScaleOffset[2]; + + // get parameters for programs + ovrHmd_GetRenderScaleAndOffset(fov, + fovTextureSize[eye], eyeViewport, + (ovrVector2f *)uvScaleOffset); + m_EyeUVScaleOffset[eye][0] = NLMISC::CVector2f(uvScaleOffset[0].x, uvScaleOffset[0].y); + m_EyeUVScaleOffset[eye][1] = NLMISC::CVector2f(uvScaleOffset[1].x, uvScaleOffset[1].y); + + // create distortion mesh vertex buffer + m_VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag | CVertexBuffer::PrimaryColorFlag); + m_VB.setPreferredMemory(CVertexBuffer::StaticPreferred, false); + m_VB.setNumVertices(meshData.VertexCount); + { + CVertexBufferReadWrite vba; + m_VB.lock(vba); + for (uint i = 0; i < meshData.VertexCount; ++i) + { + ovrDistortionVertex &ov = meshData.pVertexData[i]; + vba.setVertexCoord(i, (ov.ScreenPosNDC.x + 1.0f) * 0.5f, (ov.ScreenPosNDC.y + 1.0f) * 0.5f, 0.5f); + vba.setTexCoord(i, 0, ov.TanEyeAnglesR.x, ov.TanEyeAnglesR.y); + vba.setTexCoord(i, 1, ov.TanEyeAnglesG.x, ov.TanEyeAnglesG.y); + vba.setTexCoord(i, 2, ov.TanEyeAnglesB.x, ov.TanEyeAnglesB.y); + NLMISC::CRGBA color; + color.R = color.G = color.B = (uint8)(ov.VignetteFactor * 255.99f); + color.A = (uint8)(ov.TimeWarpFactor * 255.99f); + vba.setColor(i, color); + } + } + + // create distortion mesh index buffer + m_IB.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); + m_IB.setPreferredMemory(CIndexBuffer::StaticPreferred, false); + m_IB.setNumIndexes(meshData.IndexCount); + { + CIndexBufferReadWrite iba; + m_IB.lock(iba); + for (uint i = 0; i + 2 < meshData.IndexCount; i += 3) + { + nlassert(meshData.pIndexData[i] < meshData.VertexCount); + nlassert(meshData.pIndexData[i + 1] < meshData.VertexCount); + nlassert(meshData.pIndexData[i + 2] < meshData.VertexCount); + iba.setTri(i, meshData.pIndexData[i], meshData.pIndexData[i + 1], meshData.pIndexData[i + 2]); + } + } + + // set tri count + m_NbTris = meshData.IndexCount / 3; + + // destroy ovr distortion mesh + ovrHmd_DestroyDistortionMesh(&meshData); } // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.000000, y: 0.000000, w: 0.500000, h: 1.000000 + // 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641 // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.500000, y: 0.000000, w: 0.500000, h: 1.000000 + // 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641 // DEBUG EARLY EXIT nldebug("OVR: Early exit"); @@ -247,16 +315,15 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL CStereoOVR::~CStereoOVR() { - /*if (!m_BarrelMat.empty()) + if (!m_UnlitMat.empty()) { - m_BarrelMat.getObjectPtr()->setTexture(0, NULL); - m_Driver->deleteMaterial(m_BarrelMat); + m_Driver->deleteMaterial(m_UnlitMat); } - delete m_PixelProgram; - m_PixelProgram = NULL; + m_PP.kill(); + m_VP.kill(); - m_Driver = NULL;*/ + m_Driver = NULL; if (m_DevicePtr) { @@ -265,40 +332,73 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } } -/* -class CPixelProgramOVR : public CPixelProgram + +class CVertexProgramOVR : public CVertexProgram { public: struct COVRIndices { - uint LensCenter; + /*uint LensCenter; uint ScreenCenter; uint Scale; uint ScaleIn; - uint HmdWarpParam; + uint HmdWarpParam;*/ }; - CPixelProgramOVR() + CVertexProgramOVR() { - { + /*{ CSource *source = new CSource(); source->Profile = glsl330f; source->Features.MaterialFlags = CProgramFeatures::TextureStages; source->setSourcePtr(g_StereoOVR_glsl330f); addSource(source); - } - { - CSource *source = new CSource(); - source->Profile = fp40; - source->Features.MaterialFlags = CProgramFeatures::TextureStages; - source->setSourcePtr(g_StereoOVR_fp40); - source->ParamIndices["cLensCenter"] = 0; - source->ParamIndices["cScreenCenter"] = 1; - source->ParamIndices["cScale"] = 2; - source->ParamIndices["cScaleIn"] = 3; - source->ParamIndices["cHmdWarpParam"] = 4; - addSource(source); - } + }*/ + } + + virtual ~CVertexProgramOVR() + { + + } + + virtual void buildInfo() + { + CVertexProgram::buildInfo(); + + /*m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + nlassert(m_OVRIndices.LensCenter != ~0); + m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); + nlassert(m_OVRIndices.ScreenCenter != ~0); + m_OVRIndices.Scale = getUniformIndex("cScale"); + nlassert(m_OVRIndices.Scale != ~0); + m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); + nlassert(m_OVRIndices.ScaleIn != ~0); + m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); + nlassert(m_OVRIndices.HmdWarpParam != ~0);*/ + } + + inline const COVRIndices &ovrIndices() { return m_OVRIndices; } + +private: + COVRIndices m_OVRIndices; + +}; + +class CPixelProgramOVR : public CPixelProgram +{ +public: + struct COVRIndices + { + /*uint LensCenter; + uint ScreenCenter; + uint Scale; + uint ScaleIn; + uint HmdWarpParam;*/ + }; + + CPixelProgramOVR() + { + /* { CSource *source = new CSource(); source->Profile = arbfp1; @@ -322,7 +422,7 @@ public: source->ParamIndices["cScaleIn"] = 3; source->ParamIndices["cHmdWarpParam"] = 4; addSource(source); - } + }*/ } virtual ~CPixelProgramOVR() @@ -334,7 +434,7 @@ public: { CPixelProgram::buildInfo(); - m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + /*m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); nlassert(m_OVRIndices.LensCenter != ~0); m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); nlassert(m_OVRIndices.ScreenCenter != ~0); @@ -343,7 +443,7 @@ public: m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); nlassert(m_OVRIndices.ScaleIn != ~0); m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); - nlassert(m_OVRIndices.HmdWarpParam != ~0); + nlassert(m_OVRIndices.HmdWarpParam != ~0);*/ } inline const COVRIndices &ovrIndices() { return m_OVRIndices; } @@ -352,83 +452,57 @@ private: COVRIndices m_OVRIndices; }; -*/ void CStereoOVR::setDriver(NL3D::UDriver *driver) -{/* - nlassert(!m_PixelProgram); - - NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - - if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) +{ + nlassert(!m_PP); + nlassert(!m_VP); + m_Driver = driver; + + CDriverUser *dru = static_cast(driver); + IDriver *drv = dru->getDriver(); + + m_UnlitMat = m_Driver->createMaterial(); + m_UnlitMat.initUnlit(); + m_UnlitMat.setColor(CRGBA::White); + m_UnlitMat.setBlend (false); + m_UnlitMat.setAlphaTest (false); + NL3D::CMaterial *unlitMat = m_UnlitMat.getObjectPtr(); + unlitMat->setShader(NL3D::CMaterial::Normal); + unlitMat->setBlendFunc(CMaterial::one, CMaterial::zero); + unlitMat->setZWrite(false); + unlitMat->setZFunc(CMaterial::always); + unlitMat->setDoubleSided(true); + + if (drv->supportBloomEffect() && drv->supportNonPowerOfTwoTextures()) { - m_PixelProgram = new CPixelProgramOVR(); - if (!drvInternal->compilePixelProgram(m_PixelProgram)) + m_PP = new CPixelProgramOVR(); + if (!drv->compilePixelProgram(m_PP)) { - m_PixelProgram.kill(); + m_PP.kill(); + nlwarning("OVR: No pixel program support"); + return; + } + m_VP = new CVertexProgramOVR(); + if (!drv->compileVertexProgram(m_VP)) + { + m_VP.kill(); + nlwarning("OVR: No vertex program support"); + m_PP.kill(); + return; } } - - if (m_PixelProgram) - { - m_Driver = driver; - - /*m_BarrelTex = new CTextureBloom(); // lol bloom - m_BarrelTex->setRenderTarget(true); - m_BarrelTex->setReleasable(false); - m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); - m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_BarrelTex->setWrapS(ITexture::Clamp); - m_BarrelTex->setWrapT(ITexture::Clamp); - drvInternal->setupTexture(*m_BarrelTex); - m_BarrelTexU = new CTextureUser(m_BarrelTex);* / - - m_BarrelMat = m_Driver->createMaterial(); - m_BarrelMat.initUnlit(); - m_BarrelMat.setColor(CRGBA::White); - m_BarrelMat.setBlend (false); - m_BarrelMat.setAlphaTest (false); - NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); - barrelMat->setShader(NL3D::CMaterial::Normal); - barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); - barrelMat->setZWrite(false); - barrelMat->setZFunc(CMaterial::always); - barrelMat->setDoubleSided(true); - // barrelMat->setTexture(0, m_BarrelTex); - - m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); - m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); - m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); - m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); - - m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); - m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); - m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); - m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); - - // nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed - - m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); - m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); - m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); - m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); - - m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); - m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); - m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); - m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); - } - else - { - nlwarning("VR: No pixel program support"); - }*/ } bool CStereoOVR::getScreenResolution(uint &width, uint &height) { - /*width = m_DevicePtr->HMDInfo.HResolution; - height = m_DevicePtr->HMDInfo.VResolution;*/ - return true; + if (m_DevicePtr) + { + width = m_DevicePtr->Resolution.w; + height = m_DevicePtr->Resolution.h; + return true; + } + return false; } void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) From 9b79a44f8a5ae2794169deafd670a58db2ddb157 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 00:46:04 +0200 Subject: [PATCH 062/240] OVR: Get orientation --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 3 +- code/nel/src/3d/stereo_ovr_04.cpp | 81 +++++++++++-------------- 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 5c5f73a6b..18c7083da 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -185,13 +185,14 @@ private: UDriver *m_Driver; CTextureUser *m_GUITexture; + NL3D::CTextureUser *m_SceneTexture; UMaterial m_UnlitMat; NLMISC::CRefPtr m_VP; NLMISC::CRefPtr m_PP; - /*NL3D::CTextureUser *m_SceneTexture; + /* NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; NLMISC::CQuadUV m_BarrelQuadRight; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 2238c3d16..0d0adb449 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -246,7 +246,7 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL // get distortion mesh ovrDistortionMesh meshData; ovrHmd_CreateDistortionMesh(m_DevicePtr, (ovrEyeType)eye, fov, - ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette, + ovrDistortionCap_Chromatic /*| ovrDistortionCap_TimeWarp*/ | ovrDistortionCap_Vignette, // I believe the timewarp gimmick screws with parallax &meshData); ovrVector2f uvScaleOffset[2]; @@ -273,7 +273,7 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL vba.setTexCoord(i, 2, ov.TanEyeAnglesB.x, ov.TanEyeAnglesB.y); NLMISC::CRGBA color; color.R = color.G = color.B = (uint8)(ov.VignetteFactor * 255.99f); - color.A = (uint8)(ov.TimeWarpFactor * 255.99f); + color.A = 255; // (uint8)(ov.TimeWarpFactor * 255.99f); vba.setColor(i, color); } } @@ -552,12 +552,6 @@ void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) bool CStereoOVR::nextPass() { - // Do not allow weird stuff. - uint32 width, height; - m_Driver->getWindowSize(width, height); - // nlassert(width == m_DevicePtr->HMDInfo.HResolution); - // nlassert(height == m_DevicePtr->HMDInfo.VResolution); - if (m_Driver->getPolygonMode() == UDriver::Filled) { switch (m_Stage) // Previous stage @@ -742,15 +736,13 @@ bool CStereoOVR::beginRenderTarget() } // Begin 3D scene render target - /*if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) + if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) { nlassert(!m_SceneTexture); - uint32 width, height; - m_Driver->getWindowSize(width, height); // Temporary limitation, TODO: scaling! - m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); return true; - }*/ + } return false; } @@ -762,17 +754,6 @@ void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix) void CStereoOVR::renderGUI() { - - /*CMatrix mat; - mat.translate(m_InterfaceCameraMatrix.getPos()); - CVector dir = m_InterfaceCameraMatrix.getJ(); - dir.z = 0; - dir.normalize(); - if (dir.y < 0) - mat.rotateZ(float(NLMISC::Pi+asin(dir.x))); - else - mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); - m_Driver->setModelMatrix(mat);*/ m_Driver->setModelMatrix(m_InterfaceCameraMatrix); { @@ -1022,27 +1003,39 @@ bool CStereoOVR::endRenderTarget() NLMISC::CQuat CStereoOVR::getOrientation() const { - //if (m_OrientationCached) + if (m_OrientationCached) return m_OrientationCache; -/* - OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); - NLMISC::CMatrix coordsys; - float csys[] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, -1.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; - coordsys.set(csys); - NLMISC::CMatrix matovr; - matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); - NLMISC::CMatrix matr; - matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) - NLMISC::CMatrix matnel = matr * matovr * coordsys; - NLMISC::CQuat finalquat = matnel.getRot(); - m_OrientationCache = finalquat; - m_OrientationCached = true; - return finalquat;*/ + + ovrTrackingState ts = ovrHmd_GetTrackingState(m_DevicePtr, ovr_GetTimeInSeconds()); // TODO: Predict forward + if (ts.StatusFlags & ovrStatus_OrientationTracked) + { + // get just the orientation + ovrQuatf quatovr = ts.HeadPose.ThePose.Orientation; + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat; + } + else + { + nlwarning("OVR: No orientation returned"); + // return old orientation + m_OrientationCached = true; + return m_OrientationCache; + } } /// Get GUI shift From 2e6893fd48a2ee8b7b7622fa0468c7c0f8bf434b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 00:51:53 +0200 Subject: [PATCH 063/240] OVR: Translate camera --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 1 + code/nel/src/3d/stereo_ovr_04.cpp | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 18c7083da..a8f912308 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -168,6 +168,7 @@ private: uint m_RenderTargetWidth; uint m_RenderTargetHeight; NLMISC::CVector2f m_EyeUVScaleOffset[NL_OVR_EYE_COUNT][2]; + float m_EyeViewAdjustX[NL_OVR_EYE_COUNT]; CVertexBuffer m_VB; CIndexBuffer m_IB; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 0d0adb449..999a9c9a3 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -220,6 +220,9 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL for (uint eye = 0; eye < ovrEye_Count; ++eye) { ovrFovPort &fov = eyeRenderDesc[eye].Fov; + + // store data + m_EyeViewAdjustX[eye] = -eyeRenderDesc[eye].ViewAdjust.x; // setup viewport m_EyeViewport[eye].init( @@ -653,11 +656,11 @@ void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const } void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const -{/* +{ CMatrix translate; if (m_Stage == 2) { } - else if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); - else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + else if (m_Stage % 2) translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Left] * m_Scale, 0.f, 0.f)); + else translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Right] * m_Scale, 0.f, 0.f)); CMatrix mat = m_CameraMatrix[cid] * translate; if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) { @@ -668,7 +671,7 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); camera->setMatrix(mat); - }*/ + } } bool CStereoOVR::wantClear() From 33235bdf6ce67bdda420bbba10917d98ddd5d3bb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 01:49:45 +0200 Subject: [PATCH 064/240] OVR: Testing --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 3 +- code/nel/src/3d/driver_user2.cpp | 16 +++- code/nel/src/3d/stereo_ovr_04.cpp | 100 +++++++++++++++++------- 3 files changed, 86 insertions(+), 33 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index a8f912308..4835f97be 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -163,8 +163,7 @@ private: CViewport m_RegularViewport; CViewport m_EyeViewport[NL_OVR_EYE_COUNT]; - float m_EyeHFov[NL_OVR_EYE_COUNT]; - float m_EyeAR[NL_OVR_EYE_COUNT]; + CFrustum m_EyeFrustumBase[NL_OVR_EYE_COUNT]; uint m_RenderTargetWidth; uint m_RenderTargetHeight; NLMISC::CVector2f m_EyeUVScaleOffset[NL_OVR_EYE_COUNT][2]; diff --git a/code/nel/src/3d/driver_user2.cpp b/code/nel/src/3d/driver_user2.cpp index 2398db906..1f1eed938 100644 --- a/code/nel/src/3d/driver_user2.cpp +++ b/code/nel/src/3d/driver_user2.cpp @@ -119,10 +119,20 @@ void CDriverUser::endDefaultRenderTarget(UScene *scene) _MatRenderTarget.getObjectPtr()->setTexture(0, _EffectRenderTarget->getITexture()); - UCamera pCam = scene->getCam(); - setMatrixMode2D11(); + UCamera pCam; + if (scene) + { + pCam = scene->getCam(); + setMatrixMode2D11(); + } + bool fog = fogEnabled(); + enableFog(false); drawQuad(_RenderTargetQuad, _MatRenderTarget); - setMatrixMode3D(pCam); + enableFog(fog); + if (scene) + { + setMatrixMode3D(pCam); + } _MatRenderTarget.getObjectPtr()->setTexture(0, NULL); diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 999a9c9a3..d68cbbdde 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -238,13 +238,28 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL eyeViewport.Size.h = (eyeRenderDesc[eye].DistortedViewport.Size.h * m_RenderTargetHeight) / m_DevicePtr->Resolution.h; // calculate hfov and ar - float combinedTanHalfFovHorizontal = max(fov.LeftTan, fov.RightTan); + /*float combinedTanHalfFovHorizontal = max(fov.LeftTan, fov.RightTan); float combinedTanHalfFovVertical = max(fov.UpTan, fov.DownTan); float horizontalFullFovInRadians = 2.0f * atanf (combinedTanHalfFovHorizontal); float aspectRatio = combinedTanHalfFovHorizontal / combinedTanHalfFovVertical; + float m_EyeHFov[NL_OVR_EYE_COUNT]; + float m_EyeAR[NL_OVR_EYE_COUNT]; m_EyeHFov[eye] = horizontalFullFovInRadians; m_EyeAR[eye] = aspectRatio; nldebug("OVR: HFOV: %f, AR: %f", horizontalFullFovInRadians, aspectRatio); + m_EyeFrustumBase[eye].initPerspective(m_EyeHFov[eye], m_EyeAR[eye], 1.0f, 100.f); + nldebug("OVR: FOV: Left: %f, Right: %f, Down: %f, Up: %f", // DOUBLE CHECK + m_EyeFrustumBase[eye].Left, m_EyeFrustumBase[eye].Right, m_EyeFrustumBase[eye].Bottom, m_EyeFrustumBase[eye].Top);*/ + m_EyeFrustumBase[eye].init( + -fov.LeftTan, // OVR provides positive values + fov.RightTan, // DEBUG: If renders shifted left and right, swap left and right + -fov.DownTan, + fov.UpTan, // DEBUG: If renders shifted up or down, swap down and up + 1.0f, // dummy + 100.f, // dummy + true); + nldebug("OVR: FOV: Left: %f, Right: %f, Down: %f, Up: %f", + m_EyeFrustumBase[eye].Left, m_EyeFrustumBase[eye].Right, m_EyeFrustumBase[eye].Bottom, m_EyeFrustumBase[eye].Top); // get distortion mesh ovrDistortionMesh meshData; @@ -310,10 +325,10 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL // 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641 // DEBUG EARLY EXIT - nldebug("OVR: Early exit"); + /*nldebug("OVR: Early exit"); ovrHmd_Destroy(m_DevicePtr); m_DevicePtr = NULL; - --s_DeviceCounter; + --s_DeviceCounter;*/ } CStereoOVR::~CStereoOVR() @@ -510,27 +525,39 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height) void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { - /*m_OriginalFrustum[cid] = camera->getFrustum(); - - float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); - float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); - m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); - m_RightFrustum[cid] = m_LeftFrustum[cid]; - - float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; - float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work? - float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up - nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); - - m_LeftFrustum[cid].Left -= projectionCenterOffset; - m_LeftFrustum[cid].Right -= projectionCenterOffset; - m_RightFrustum[cid].Left += projectionCenterOffset; - m_RightFrustum[cid].Right += projectionCenterOffset; - - // TODO: Clipping frustum should also take into account the IPD - m_ClippingFrustum[cid] = m_LeftFrustum[cid]; - m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); - m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right);*/ + m_OriginalFrustum[cid] = camera->getFrustum(); + + /*m_LeftFrustum[cid] = m_OriginalFrustum[cid]; + m_RightFrustum[cid] = m_OriginalFrustum[cid]; + m_ClippingFrustum[cid] = m_OriginalFrustum[cid]; + return;*/ + + m_LeftFrustum[cid].init( + m_EyeFrustumBase[ovrEye_Left].Left * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Left].Right * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Left].Bottom * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Left].Top * camera->getFrustum().Near, + camera->getFrustum().Near, + camera->getFrustum().Far, + true); + + m_RightFrustum[cid].init( + m_EyeFrustumBase[ovrEye_Right].Left * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Right].Right * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Right].Bottom * camera->getFrustum().Near, + m_EyeFrustumBase[ovrEye_Right].Top * camera->getFrustum().Near, + camera->getFrustum().Near, + camera->getFrustum().Far, + true); + + m_ClippingFrustum[cid].init( + min(m_EyeFrustumBase[ovrEye_Left].Left, m_EyeFrustumBase[ovrEye_Right].Left) * camera->getFrustum().Near, + max(m_EyeFrustumBase[ovrEye_Left].Right, m_EyeFrustumBase[ovrEye_Right].Right) * camera->getFrustum().Near, + min(m_EyeFrustumBase[ovrEye_Left].Bottom, m_EyeFrustumBase[ovrEye_Right].Bottom) * camera->getFrustum().Near, + max(m_EyeFrustumBase[ovrEye_Left].Top, m_EyeFrustumBase[ovrEye_Right].Top) * camera->getFrustum().Near, + camera->getFrustum().Near, + camera->getFrustum().Far, + true); } /// Get the frustum to use for clipping @@ -659,8 +686,8 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { CMatrix translate; if (m_Stage == 2) { } - else if (m_Stage % 2) translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Left] * m_Scale, 0.f, 0.f)); - else translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Right] * m_Scale, 0.f, 0.f)); + else if (m_Stage % 2) translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Left] * m_Scale, 0.f, 0.f)); // ok + else translate.translate(CVector(m_EyeViewAdjustX[ovrEye_Right] * m_Scale, 0.f, 0.f)); // ok CMatrix mat = m_CameraMatrix[cid] * translate; if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) { @@ -741,10 +768,15 @@ bool CStereoOVR::beginRenderTarget() // Begin 3D scene render target if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) { - nlassert(!m_SceneTexture); + /*nlassert(!m_SceneTexture); m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); - return true; + return true;*/ + /*nldebug("OVR: Begin render target"); + m_Driver->clearBuffers(CRGBA(64, 64, 128, 128)); + m_Driver->beginDefaultRenderTarget(); + m_Driver->clearBuffers(CRGBA(128, 64, 64, 128)); + return true;*/ } return false; @@ -913,6 +945,12 @@ bool CStereoOVR::endRenderTarget() } // End 3D scene render target + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + /*nldebug("OVR: End render target"); + m_Driver->endDefaultRenderTarget(NULL); + return true;*/ + } /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui { nlassert(m_SceneTexture); @@ -1006,6 +1044,12 @@ bool CStereoOVR::endRenderTarget() NLMISC::CQuat CStereoOVR::getOrientation() const { + // broken + + NLMISC::CQuat quat; + quat.identity(); + return quat; + if (m_OrientationCached) return m_OrientationCache; From 339c8b8dfaaa1ed694a4ee61ecd0b271e77e8dd9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 02:21:30 +0200 Subject: [PATCH 065/240] 3D: Render target matrix context fix --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/driver_user.h | 2 +- code/nel/include/nel/3d/u_driver.h | 4 ++-- code/nel/src/3d/driver/opengl/driver_opengl.cpp | 4 ++-- code/nel/src/3d/driver_user.cpp | 4 +--- code/nel/src/3d/driver_user2.cpp | 14 +++++++++----- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index 1d3c0b516..f1e1fad84 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -251,7 +251,7 @@ public: virtual CRenderTargetManager &getRenderTargetManager() { return _RenderTargetManager; } /// Set a texture the size of the window as render target - virtual void beginDefaultRenderTarget(); + virtual void beginDefaultRenderTarget(uint32 width = 0, uint32 height = 0); /// Draw the render target to the back buffer virtual void endDefaultRenderTarget(UScene *scene); diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index 247fdff75..a64e13dd6 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -310,8 +310,8 @@ public: /// Get the render target manager virtual CRenderTargetManager &getRenderTargetManager() =0; - /// Set a texture the size of the window as render target - virtual void beginDefaultRenderTarget() =0; + /// Set a texture of specified size or of the size of the window as render target + virtual void beginDefaultRenderTarget(uint32 width = 0, uint32 height = 0) =0; /// Draw the render target to the back buffer virtual void endDefaultRenderTarget(UScene *scene) =0; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 8fe98ffca..ce60d7f42 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -1077,7 +1077,7 @@ void CDriverGL::setupViewport (const class CViewport& viewport) // Setup gl viewport uint32 clientWidth, clientHeight; - getWindowSize(clientWidth, clientHeight); + getRenderTargetSize(clientWidth, clientHeight); // Backup the viewport _CurrViewport = viewport; @@ -1132,7 +1132,7 @@ void CDriverGL::setupScissor (const class CScissor& scissor) // Setup gl viewport uint32 clientWidth, clientHeight; - getWindowSize(clientWidth, clientHeight); + getRenderTargetSize(clientWidth, clientHeight); // Backup the scissor _CurrScissor= scissor; diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index d366d6d21..403b5859c 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -1948,9 +1948,7 @@ bool CDriverUser::setRenderTarget(class UTexture & uTex, uint32 x, uint32 y, uin bool result = _Driver->setRenderTarget(tex, x, y, width, height, mipmapLevel, cubeFace); - CViewport currentViewport; - _Driver->getViewport(currentViewport); - setViewport(currentViewport); + setupMatrixContext(); return result; } diff --git a/code/nel/src/3d/driver_user2.cpp b/code/nel/src/3d/driver_user2.cpp index 1f1eed938..1b46ab607 100644 --- a/code/nel/src/3d/driver_user2.cpp +++ b/code/nel/src/3d/driver_user2.cpp @@ -75,7 +75,7 @@ void CDriverUser::deleteScene(UScene *scene) // *************************************************************************** -void CDriverUser::beginDefaultRenderTarget() +void CDriverUser::beginDefaultRenderTarget(uint32 width, uint32 height) { if (_MatRenderTarget.empty()) { @@ -102,9 +102,9 @@ void CDriverUser::beginDefaultRenderTarget() } nlassert(!_EffectRenderTarget); - uint32 winw, winh; - getWindowSize(winw, winh); - _EffectRenderTarget = getRenderTargetManager().getRenderTarget(winw, winh); + if (width == 0 || height == 0) + getWindowSize(width, height); + _EffectRenderTarget = getRenderTargetManager().getRenderTarget(width, height); setRenderTarget(*_EffectRenderTarget); } @@ -123,12 +123,16 @@ void CDriverUser::endDefaultRenderTarget(UScene *scene) if (scene) { pCam = scene->getCam(); - setMatrixMode2D11(); } + CViewport oldVp = getViewport(); + CViewport vp = CViewport(); + setViewport(vp); + setMatrixMode2D11(); bool fog = fogEnabled(); enableFog(false); drawQuad(_RenderTargetQuad, _MatRenderTarget); enableFog(fog); + setViewport(oldVp); if (scene) { setMatrixMode3D(pCam); From 2fbf1cb06dc694e1389c24555d74857dadfcfcce Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 02:24:11 +0200 Subject: [PATCH 066/240] 3D: Set matrix modes after changing render target in effect --HG-- branch : multipass-stereo --- code/nel/src/3d/bloom_effect.cpp | 2 ++ code/nel/src/3d/fxaa.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index fe82e43c6..aee1a26e7 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -274,6 +274,7 @@ void CBloomEffect::applyBloom() // apply blur with a blend operation drv->setRenderTarget(renderTarget); + _Driver->setMatrixMode2D11(); applyBlur(); // cleanup material texture references @@ -356,6 +357,7 @@ void CBloomEffect::doBlur(bool horizontalBlur) nlwarning("setRenderTarget return false with blur texture for bloom effect\n"); return; } + _Driver->setMatrixMode2D11(); // initialize vertex program drvInternal->activeVertexProgram(TextureOffsetVertexProgram); diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index 238303001..73146aabe 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -245,6 +245,7 @@ void CFXAA::applyEffect() dru->setRenderTarget(texNull); drv->swapTextureHandle(*renderTarget, *otherRenderTarget->getITexture()); drv->setRenderTarget(renderTarget); + m_Driver->setMatrixMode2D11(); // debug // m_Driver->clearBuffers(CRGBA(128, 128, 128, 128)); From 65578ce4985424bf72f5ecef270e4ef581d8f113 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 02:25:14 +0200 Subject: [PATCH 067/240] OVR: Test large render target --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr_04.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index d68cbbdde..5e551739c 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -772,11 +772,11 @@ bool CStereoOVR::beginRenderTarget() m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); return true;*/ - /*nldebug("OVR: Begin render target"); - m_Driver->clearBuffers(CRGBA(64, 64, 128, 128)); - m_Driver->beginDefaultRenderTarget(); + /*nldebug("OVR: Begin render target");*/ + m_Driver->clearBuffers(CRGBA(64, 128, 64, 128)); + m_Driver->beginDefaultRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); m_Driver->clearBuffers(CRGBA(128, 64, 64, 128)); - return true;*/ + return true; } return false; @@ -947,9 +947,9 @@ bool CStereoOVR::endRenderTarget() // End 3D scene render target if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) { - /*nldebug("OVR: End render target"); + //nldebug("OVR: End render target"); m_Driver->endDefaultRenderTarget(NULL); - return true;*/ + return true; } /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui { @@ -1046,9 +1046,9 @@ NLMISC::CQuat CStereoOVR::getOrientation() const { // broken - NLMISC::CQuat quat; + /*NLMISC::CQuat quat; quat.identity(); - return quat; + return quat;*/ if (m_OrientationCached) return m_OrientationCache; @@ -1069,6 +1069,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const NLMISC::CMatrix matovr; matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); NLMISC::CMatrix matr; + matr.rotateZ(NLMISC::Pi); matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) NLMISC::CMatrix matnel = matr * matovr * coordsys; NLMISC::CQuat finalquat = matnel.getRot(); From 6ad1d146173055af717a5baeddbef3748eca6ecc Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 02:55:26 +0200 Subject: [PATCH 068/240] OVR: Test distortion mesh --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 7 +-- code/nel/src/3d/stereo_ovr_04.cpp | 79 +++++++++++++++++++------ 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 4835f97be..82b666fb1 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -169,9 +169,9 @@ private: NLMISC::CVector2f m_EyeUVScaleOffset[NL_OVR_EYE_COUNT][2]; float m_EyeViewAdjustX[NL_OVR_EYE_COUNT]; - CVertexBuffer m_VB; - CIndexBuffer m_IB; - uint m_NbTris; + CVertexBuffer m_VB[NL_OVR_EYE_COUNT]; + CIndexBuffer m_IB[NL_OVR_EYE_COUNT]; + uint32 m_NbTris[NL_OVR_EYE_COUNT]; CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; @@ -191,7 +191,6 @@ private: NLMISC::CRefPtr m_VP; NLMISC::CRefPtr m_PP; - /* NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 5e551739c..0384b06a8 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -144,7 +144,7 @@ public: } }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count); @@ -276,12 +276,12 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL m_EyeUVScaleOffset[eye][1] = NLMISC::CVector2f(uvScaleOffset[1].x, uvScaleOffset[1].y); // create distortion mesh vertex buffer - m_VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag | CVertexBuffer::PrimaryColorFlag); - m_VB.setPreferredMemory(CVertexBuffer::StaticPreferred, false); - m_VB.setNumVertices(meshData.VertexCount); + m_VB[eye].setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag | CVertexBuffer::PrimaryColorFlag); + m_VB[eye].setPreferredMemory(CVertexBuffer::StaticPreferred, true); + m_VB[eye].setNumVertices(meshData.VertexCount); { CVertexBufferReadWrite vba; - m_VB.lock(vba); + m_VB[eye].lock(vba); for (uint i = 0; i < meshData.VertexCount; ++i) { ovrDistortionVertex &ov = meshData.pVertexData[i]; @@ -297,12 +297,12 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL } // create distortion mesh index buffer - m_IB.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); - m_IB.setPreferredMemory(CIndexBuffer::StaticPreferred, false); - m_IB.setNumIndexes(meshData.IndexCount); + m_IB[eye].setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); + m_IB[eye].setPreferredMemory(CIndexBuffer::StaticPreferred, true); + m_IB[eye].setNumIndexes(meshData.IndexCount); { CIndexBufferReadWrite iba; - m_IB.lock(iba); + m_IB[eye].lock(iba); for (uint i = 0; i + 2 < meshData.IndexCount; i += 3) { nlassert(meshData.pIndexData[i] < meshData.VertexCount); @@ -313,7 +313,7 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL } // set tri count - m_NbTris = meshData.IndexCount / 3; + m_NbTris[eye] = meshData.IndexCount / 3; // destroy ovr distortion mesh ovrHmd_DestroyDistortionMesh(&meshData); @@ -768,15 +768,13 @@ bool CStereoOVR::beginRenderTarget() // Begin 3D scene render target if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) { - /*nlassert(!m_SceneTexture); + nlassert(!m_SceneTexture); m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); - return true;*/ - /*nldebug("OVR: Begin render target");*/ - m_Driver->clearBuffers(CRGBA(64, 128, 64, 128)); - m_Driver->beginDefaultRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); - m_Driver->clearBuffers(CRGBA(128, 64, 64, 128)); return true; + /*nldebug("OVR: Begin render target");*/ + //m_Driver->beginDefaultRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); // DEBUG + //return true; } return false; @@ -947,8 +945,55 @@ bool CStereoOVR::endRenderTarget() // End 3D scene render target if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) { + nlassert(m_SceneTexture); + //nldebug("OVR: End render target"); - m_Driver->endDefaultRenderTarget(NULL); + // m_Driver->endDefaultRenderTarget(NULL); // DEBUG + + // end render target + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + + // backup + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + CDriverUser *dru = static_cast(m_Driver); + IDriver *drv = dru->getDriver(); + + // set matrix mode + CViewport vp; + m_Driver->setViewport(vp); + m_Driver->setMatrixMode2D11(); + + // DEBUG + for (uint eye = 0; eye < ovrEye_Count; ++eye) + { + NL3D::UMaterial umat = m_Driver->createMaterial(); + umat.setZWrite(false); + // mat.setZFunc(UMaterial::always); // Not nice! + umat.setDoubleSided(true); + umat.setColor(NLMISC::CRGBA::Red); + umat.setBlend(false); + CMaterial *mat = umat.getObjectPtr(); + mat->setTexture(0, m_SceneTexture->getITexture()); + + //m_Driver->setPolygonMode(UDriver::Line); + drv->activeVertexBuffer(m_VB[eye]); + drv->activeIndexBuffer(m_IB[eye]); + drv->renderTriangles(*mat, 0, m_NbTris[eye]); + //m_Driver->setPolygonMode(UDriver::Filled); + + m_Driver->deleteMaterial(umat); + } + + // restore + m_Driver->enableFog(fogEnabled); + + // recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_SceneTexture); + m_SceneTexture = NULL; + return true; } /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui From 102d3653d712f3447bd0a9ed30f9f776a888e9bc Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 02:58:55 +0200 Subject: [PATCH 069/240] 3D: Ensure correct fog handling for effects --HG-- branch : multipass-stereo --- code/nel/src/3d/bloom_effect.cpp | 7 +++++++ code/nel/src/3d/fxaa.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index aee1a26e7..c468349ac 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -232,6 +232,10 @@ void CBloomEffect::applyBloom() CDriverUser *dru = static_cast(_Driver); IDriver *drv = dru->getDriver(); + // backup + bool fogEnabled = _Driver->fogEnabled(); + _Driver->enableFog(false); + NL3D::ITexture *renderTarget = drv->getRenderTarget(); nlassert(renderTarget); nlassert(renderTarget->isBloomTexture()); @@ -286,6 +290,9 @@ void CBloomEffect::applyBloom() _BlurMat.getObjectPtr()->setTexture(2, NULL); _BlurMat.getObjectPtr()->setTexture(3, NULL); + // restore + _Driver->enableFog(fogEnabled); + // recycle render targets _Driver->getRenderTargetManager().recycleRenderTarget(_BlurFinalTex); _BlurFinalTex = NULL; diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index 73146aabe..f19bcd8b4 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -199,6 +199,10 @@ void CFXAA::applyEffect() CDriverUser *dru = static_cast(m_Driver); IDriver *drv = dru->getDriver(); + // backup + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + NL3D::ITexture *renderTarget = drv->getRenderTarget(); nlassert(renderTarget); nlassert(renderTarget->isBloomTexture()); @@ -275,6 +279,9 @@ void CFXAA::applyEffect() drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); + // restore + m_Driver->enableFog(fogEnabled); + // recycle render target m_Driver->getRenderTargetManager().recycleRenderTarget(otherRenderTarget); } From 3fd358d69dcc7dbd451efaf388b804bd96b94707 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 03:54:19 +0200 Subject: [PATCH 070/240] OVR: Convert texture coordinates and setup rendering material --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 4 - code/nel/src/3d/stereo_ovr_04.cpp | 215 +++++++----------------- 2 files changed, 59 insertions(+), 160 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 82b666fb1..34a2d775a 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -70,8 +70,6 @@ namespace NL3D { class ITexture; class CTextureUser; class CStereoOVRDeviceFactory; -class CPixelProgramOVR; -class CVertexProgramOVR; #define NL_STEREO_MAX_USER_CAMERAS 8 #define NL_OVR_EYE_COUNT 2 @@ -188,8 +186,6 @@ private: NL3D::CTextureUser *m_SceneTexture; UMaterial m_UnlitMat; - NLMISC::CRefPtr m_VP; - NLMISC::CRefPtr m_PP; /* NL3D::UMaterial m_BarrelMat; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 0384b06a8..a21dcbcc3 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -144,6 +144,22 @@ public: } }; +static NLMISC::CVector2f toTex(NLMISC::CVector2f texCoord, NLMISC::CVector2f uvScaleOffset[2]) +{ + // return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); + NLMISC::CVector2f vec = NLMISC::CVector2f(texCoord.x * uvScaleOffset[0].x, texCoord.y * uvScaleOffset[0].y) + uvScaleOffset[1]; + // some trial and error voodoo, sorry + vec = (vec + NLMISC::CVector2f(1, 1)) * 0.5f; + vec.y = 1.0f - vec.y; + vec.x = 1.0f - vec.x; + vec.x += 0.5f; + vec.y *= 2.0f; + + vec.x = 1.0f - vec.x; + + return vec; +} + CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count); @@ -286,9 +302,15 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL { ovrDistortionVertex &ov = meshData.pVertexData[i]; vba.setVertexCoord(i, (ov.ScreenPosNDC.x + 1.0f) * 0.5f, (ov.ScreenPosNDC.y + 1.0f) * 0.5f, 0.5f); - vba.setTexCoord(i, 0, ov.TanEyeAnglesR.x, ov.TanEyeAnglesR.y); - vba.setTexCoord(i, 1, ov.TanEyeAnglesG.x, ov.TanEyeAnglesG.y); - vba.setTexCoord(i, 2, ov.TanEyeAnglesB.x, ov.TanEyeAnglesB.y); + NLMISC::CVector2f texR(ov.TanEyeAnglesR.x, ov.TanEyeAnglesR.y); + NLMISC::CVector2f texG(ov.TanEyeAnglesG.x, ov.TanEyeAnglesG.y); + NLMISC::CVector2f texB(ov.TanEyeAnglesB.x, ov.TanEyeAnglesB.y); + texR = toTex(texR, m_EyeUVScaleOffset[eye]); + texG = toTex(texG, m_EyeUVScaleOffset[eye]); + texB = toTex(texB, m_EyeUVScaleOffset[eye]); + vba.setTexCoord(i, 0, texR.x, texR.y); + vba.setTexCoord(i, 1, texG.x, texG.y); + vba.setTexCoord(i, 2, texB.x, texB.y); NLMISC::CRGBA color; color.R = color.G = color.B = (uint8)(ov.VignetteFactor * 255.99f); color.A = 255; // (uint8)(ov.TimeWarpFactor * 255.99f); @@ -338,9 +360,6 @@ CStereoOVR::~CStereoOVR() m_Driver->deleteMaterial(m_UnlitMat); } - m_PP.kill(); - m_VP.kill(); - m_Driver = NULL; if (m_DevicePtr) @@ -351,130 +370,8 @@ CStereoOVR::~CStereoOVR() } } -class CVertexProgramOVR : public CVertexProgram -{ -public: - struct COVRIndices - { - /*uint LensCenter; - uint ScreenCenter; - uint Scale; - uint ScaleIn; - uint HmdWarpParam;*/ - }; - - CVertexProgramOVR() - { - /*{ - CSource *source = new CSource(); - source->Profile = glsl330f; - source->Features.MaterialFlags = CProgramFeatures::TextureStages; - source->setSourcePtr(g_StereoOVR_glsl330f); - addSource(source); - }*/ - } - - virtual ~CVertexProgramOVR() - { - - } - - virtual void buildInfo() - { - CVertexProgram::buildInfo(); - - /*m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); - nlassert(m_OVRIndices.LensCenter != ~0); - m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); - nlassert(m_OVRIndices.ScreenCenter != ~0); - m_OVRIndices.Scale = getUniformIndex("cScale"); - nlassert(m_OVRIndices.Scale != ~0); - m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); - nlassert(m_OVRIndices.ScaleIn != ~0); - m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); - nlassert(m_OVRIndices.HmdWarpParam != ~0);*/ - } - - inline const COVRIndices &ovrIndices() { return m_OVRIndices; } - -private: - COVRIndices m_OVRIndices; - -}; - -class CPixelProgramOVR : public CPixelProgram -{ -public: - struct COVRIndices - { - /*uint LensCenter; - uint ScreenCenter; - uint Scale; - uint ScaleIn; - uint HmdWarpParam;*/ - }; - - CPixelProgramOVR() - { - /* - { - CSource *source = new CSource(); - source->Profile = arbfp1; - source->Features.MaterialFlags = CProgramFeatures::TextureStages; - source->setSourcePtr(g_StereoOVR_arbfp1); - source->ParamIndices["cLensCenter"] = 0; - source->ParamIndices["cScreenCenter"] = 1; - source->ParamIndices["cScale"] = 2; - source->ParamIndices["cScaleIn"] = 3; - source->ParamIndices["cHmdWarpParam"] = 4; - addSource(source); - } - { - CSource *source = new CSource(); - source->Profile = ps_2_0; - source->Features.MaterialFlags = CProgramFeatures::TextureStages; - source->setSourcePtr(g_StereoOVR_ps_2_0); - source->ParamIndices["cLensCenter"] = 0; - source->ParamIndices["cScreenCenter"] = 1; - source->ParamIndices["cScale"] = 2; - source->ParamIndices["cScaleIn"] = 3; - source->ParamIndices["cHmdWarpParam"] = 4; - addSource(source); - }*/ - } - - virtual ~CPixelProgramOVR() - { - - } - - virtual void buildInfo() - { - CPixelProgram::buildInfo(); - - /*m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); - nlassert(m_OVRIndices.LensCenter != ~0); - m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); - nlassert(m_OVRIndices.ScreenCenter != ~0); - m_OVRIndices.Scale = getUniformIndex("cScale"); - nlassert(m_OVRIndices.Scale != ~0); - m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); - nlassert(m_OVRIndices.ScaleIn != ~0); - m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); - nlassert(m_OVRIndices.HmdWarpParam != ~0);*/ - } - - inline const COVRIndices &ovrIndices() { return m_OVRIndices; } - -private: - COVRIndices m_OVRIndices; - -}; - void CStereoOVR::setDriver(NL3D::UDriver *driver) { - nlassert(!m_PP); - nlassert(!m_VP); m_Driver = driver; CDriverUser *dru = static_cast(driver); @@ -491,25 +388,28 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) unlitMat->setZWrite(false); unlitMat->setZFunc(CMaterial::always); unlitMat->setDoubleSided(true); - - if (drv->supportBloomEffect() && drv->supportNonPowerOfTwoTextures()) - { - m_PP = new CPixelProgramOVR(); - if (!drv->compilePixelProgram(m_PP)) - { - m_PP.kill(); - nlwarning("OVR: No pixel program support"); - return; - } - m_VP = new CVertexProgramOVR(); - if (!drv->compileVertexProgram(m_VP)) - { - m_VP.kill(); - nlwarning("OVR: No vertex program support"); - m_PP.kill(); - return; - } - } + + unlitMat->texConstantColor(0, NLMISC::CRGBA(255, 0, 0, 0)); + unlitMat->texConstantColor(1, NLMISC::CRGBA(0, 255, 0, 0)); + unlitMat->texConstantColor(2, NLMISC::CRGBA(0, 0, 255, 0)); + + m_UnlitMat.texEnvArg0RGB(0, UMaterial::Texture, UMaterial::SrcColor); + m_UnlitMat.texEnvArg1RGB(0, UMaterial::Constant, UMaterial::SrcColor); + m_UnlitMat.texEnvOpRGB(0, UMaterial::Modulate); + + m_UnlitMat.texEnvArg0RGB(1, UMaterial::Texture, UMaterial::SrcColor); + m_UnlitMat.texEnvArg1RGB(1, UMaterial::Constant, UMaterial::SrcColor); + m_UnlitMat.texEnvArg2RGB(1, UMaterial::Previous, UMaterial::SrcColor); + m_UnlitMat.texEnvOpRGB(1, UMaterial::Mad); + + m_UnlitMat.texEnvArg0RGB(2, UMaterial::Texture, UMaterial::SrcColor); + m_UnlitMat.texEnvArg1RGB(2, UMaterial::Constant, UMaterial::SrcColor); + m_UnlitMat.texEnvArg2RGB(2, UMaterial::Previous, UMaterial::SrcColor); + m_UnlitMat.texEnvOpRGB(2, UMaterial::Mad); + + m_UnlitMat.texEnvArg0RGB(3, UMaterial::Previous, UMaterial::SrcColor); + m_UnlitMat.texEnvArg1RGB(3, UMaterial::Diffuse, UMaterial::SrcColor); + m_UnlitMat.texEnvOpRGB(3, UMaterial::Modulate); } bool CStereoOVR::getScreenResolution(uint &width, uint &height) @@ -958,6 +858,9 @@ bool CStereoOVR::endRenderTarget() bool fogEnabled = m_Driver->fogEnabled(); m_Driver->enableFog(false); + // must clear everything to black (can we get a mesh to only handle the parts outside of the distortion mesh?) + m_Driver->clearRGBABuffer(CRGBA(0, 0, 0, 255)); + CDriverUser *dru = static_cast(m_Driver); IDriver *drv = dru->getDriver(); @@ -966,17 +869,13 @@ bool CStereoOVR::endRenderTarget() m_Driver->setViewport(vp); m_Driver->setMatrixMode2D11(); - // DEBUG for (uint eye = 0; eye < ovrEye_Count; ++eye) { - NL3D::UMaterial umat = m_Driver->createMaterial(); - umat.setZWrite(false); - // mat.setZFunc(UMaterial::always); // Not nice! - umat.setDoubleSided(true); - umat.setColor(NLMISC::CRGBA::Red); - umat.setBlend(false); - CMaterial *mat = umat.getObjectPtr(); + CMaterial *mat = m_UnlitMat.getObjectPtr(); mat->setTexture(0, m_SceneTexture->getITexture()); + mat->setTexture(1, m_SceneTexture->getITexture()); + mat->setTexture(2, m_SceneTexture->getITexture()); + mat->setTexture(3, m_SceneTexture->getITexture()); //m_Driver->setPolygonMode(UDriver::Line); drv->activeVertexBuffer(m_VB[eye]); @@ -984,7 +883,10 @@ bool CStereoOVR::endRenderTarget() drv->renderTriangles(*mat, 0, m_NbTris[eye]); //m_Driver->setPolygonMode(UDriver::Filled); - m_Driver->deleteMaterial(umat); + mat->setTexture(0, NULL); + mat->setTexture(1, NULL); + mat->setTexture(2, NULL); + mat->setTexture(3, NULL); } // restore @@ -996,6 +898,7 @@ bool CStereoOVR::endRenderTarget() return true; } + /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui { nlassert(m_SceneTexture); From e61eb57fd97b958be4e76f2ad13086584ae9e562 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 04:03:27 +0200 Subject: [PATCH 071/240] OVR: Fix for debug devices --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr_04.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index a21dcbcc3..44610b89e 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -1093,6 +1093,7 @@ void CStereoOVR::listDevices(std::vector &devicesOut) CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK1); CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DetectId = s_DetectId; factory->DebugDevice = true; factory->DebugDeviceType = ovrHmd_DK1; deviceInfoOut.Factory = factory; @@ -1110,6 +1111,7 @@ void CStereoOVR::listDevices(std::vector &devicesOut) CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2); CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DetectId = s_DetectId; factory->DebugDevice = true; factory->DebugDeviceType = ovrHmd_DK2; deviceInfoOut.Factory = factory; From e8a245a133851c2c87d1d10df900573893b26aaa Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 5 Aug 2014 20:14:58 +0200 Subject: [PATCH 072/240] OVR: Chroma factor --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr_04.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 44610b89e..527f065fd 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -160,6 +160,11 @@ static NLMISC::CVector2f toTex(NLMISC::CVector2f texCoord, NLMISC::CVector2f uvS return vec; } +static float lerp(float f0, float f1, float factor) +{ + return (f1 * factor) + (f0 * (1.0f - factor)); +} + CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count); @@ -291,6 +296,11 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL m_EyeUVScaleOffset[eye][0] = NLMISC::CVector2f(uvScaleOffset[0].x, uvScaleOffset[0].y); m_EyeUVScaleOffset[eye][1] = NLMISC::CVector2f(uvScaleOffset[1].x, uvScaleOffset[1].y); + // chroma bugfix + float chromaFactor = 1.00f; + if (m_DevicePtr->Type == ovrHmd_DK2) + chromaFactor = 0.75f; + // create distortion mesh vertex buffer m_VB[eye].setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag | CVertexBuffer::PrimaryColorFlag); m_VB[eye].setPreferredMemory(CVertexBuffer::StaticPreferred, true); @@ -302,9 +312,13 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL { ovrDistortionVertex &ov = meshData.pVertexData[i]; vba.setVertexCoord(i, (ov.ScreenPosNDC.x + 1.0f) * 0.5f, (ov.ScreenPosNDC.y + 1.0f) * 0.5f, 0.5f); - NLMISC::CVector2f texR(ov.TanEyeAnglesR.x, ov.TanEyeAnglesR.y); + NLMISC::CVector2f texR( + lerp(ov.TanEyeAnglesG.x, ov.TanEyeAnglesR.x, chromaFactor), + lerp(ov.TanEyeAnglesG.y, ov.TanEyeAnglesR.y, chromaFactor)); NLMISC::CVector2f texG(ov.TanEyeAnglesG.x, ov.TanEyeAnglesG.y); - NLMISC::CVector2f texB(ov.TanEyeAnglesB.x, ov.TanEyeAnglesB.y); + NLMISC::CVector2f texB( + lerp(ov.TanEyeAnglesG.x, ov.TanEyeAnglesB.x, chromaFactor), + lerp(ov.TanEyeAnglesG.y, ov.TanEyeAnglesB.y, chromaFactor)); texR = toTex(texR, m_EyeUVScaleOffset[eye]); texG = toTex(texG, m_EyeUVScaleOffset[eye]); texB = toTex(texB, m_EyeUVScaleOffset[eye]); @@ -346,6 +360,8 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL // 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.500000, y: 0.000000, w: 0.500000, h: 1.000000 // 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641 + ovrHmd_RecenterPose(m_DevicePtr); + // DEBUG EARLY EXIT /*nldebug("OVR: Early exit"); ovrHmd_Destroy(m_DevicePtr); @@ -1017,7 +1033,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const NLMISC::CMatrix matovr; matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); NLMISC::CMatrix matr; - matr.rotateZ(NLMISC::Pi); + // matr.rotateZ(NLMISC::Pi); // uncomment when backwards ... matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) NLMISC::CMatrix matnel = matr * matovr * coordsys; NLMISC::CQuat finalquat = matnel.getRot(); From 4e33e5cf2f959d17ec2f3c4fcdf76069ef93681c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 6 Aug 2014 14:36:09 +0200 Subject: [PATCH 073/240] Process some scene traversals only once when rendering in stereo --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/render_trav.h | 2 +- code/nel/include/nel/3d/scene.h | 6 +- code/nel/include/nel/3d/scene_user.h | 4 +- code/nel/include/nel/3d/stereo_debugger.h | 9 +- code/nel/include/nel/3d/stereo_display.h | 9 +- code/nel/include/nel/3d/stereo_ovr_04.h | 9 +- code/nel/include/nel/3d/u_scene.h | 7 +- code/nel/src/3d/render_trav.cpp | 5 +- code/nel/src/3d/scene.cpp | 124 +++++++++++------- code/nel/src/3d/scene_user.cpp | 8 +- code/nel/src/3d/stereo_debugger.cpp | 16 +++ code/nel/src/3d/stereo_ovr_04.cpp | 30 +++++ code/ryzom/client/src/landscape_poly_drawer.h | 4 +- code/ryzom/client/src/main_loop.cpp | 98 ++++++++------ code/ryzom/client/src/main_loop.h | 2 +- 15 files changed, 228 insertions(+), 105 deletions(-) diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index d50d2c242..6e41d8282 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -139,7 +139,7 @@ public: * \param renderPart : The part of the scene that must be rendered * \param newRender true If scene render is beginning. Otherwise other parts of the scene have already been rendered. */ - void traverse(UScene::TRenderPart renderPart, bool newRender); + void traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows); //@} /// \name RenderList. diff --git a/code/nel/include/nel/3d/scene.h b/code/nel/include/nel/3d/scene.h index e0648ebd3..68e86edf1 100644 --- a/code/nel/include/nel/3d/scene.h +++ b/code/nel/include/nel/3d/scene.h @@ -157,7 +157,7 @@ public: * \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if * you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras). */ - void render(bool doHrcPass=true); + void render(bool doHrcPass = true); /** Begin Part Rendering * During beginPartRender()/endPartRender(), you can ask other scene to render their part, but you should @@ -171,10 +171,10 @@ public: * WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work * WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender() */ - void renderPart(UScene::TRenderPart rp, bool doHrcPass=true); + void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false); /** End Part Rendering (commit model creation and deletion that were asked during rendering) */ - void endPartRender(); + void endPartRender(bool keepTrav = false); //@} diff --git a/code/nel/include/nel/3d/scene_user.h b/code/nel/include/nel/3d/scene_user.h index 708c8bfd7..639fa33d8 100644 --- a/code/nel/include/nel/3d/scene_user.h +++ b/code/nel/include/nel/3d/scene_user.h @@ -96,8 +96,8 @@ public: // render methods virtual void render(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true); virtual void beginPartRender(); - virtual void renderPart(TRenderPart rp); - virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true); + virtual void renderPart(TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false); + virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = true); // update async loading whithout a call to render virtual void updateWaitingInstances(double ellapsedTime); diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index ba9fff68d..cd66a4fdc 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -93,14 +93,21 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target - virtual bool wantClear(); + virtual bool wantClear(); /// The 3D scene virtual bool wantScene(); + /// Scene post processing effects + virtual bool wantSceneEffects(); /// Interface within the 3D scene virtual bool wantInterface3D(); /// 2D Interface virtual bool wantInterface2D(); + /// Is this the first 3D scene of the frame + virtual bool isSceneFirst(); + /// Is this the last 3D scene of the frame + virtual bool isSceneLast(); + /// Returns true if a new render target was set, always fase if not using render targets virtual bool beginRenderTarget(); /// Returns true if a render target was fully drawn, always false if not using render targets diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index f796bccfe..52ec37354 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -116,14 +116,21 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0; /// At the start of a new render target - virtual bool wantClear() = 0; + virtual bool wantClear() = 0; /// The 3D scene virtual bool wantScene() = 0; + /// Scene post processing effects + virtual bool wantSceneEffects() = 0; /// Interface within the 3D scene virtual bool wantInterface3D() = 0; /// 2D Interface virtual bool wantInterface2D() = 0; + /// Is this the first 3D scene of the frame + virtual bool isSceneFirst() = 0; + /// Is this the last 3D scene of the frame + virtual bool isSceneLast() = 0; + /// Returns true if a new render target was set, always fase if not using render targets virtual bool beginRenderTarget() = 0; /// Returns true if a render target was fully drawn, always false if not using render targets diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 34a2d775a..7523819a5 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -110,14 +110,21 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target - virtual bool wantClear(); + virtual bool wantClear(); /// The 3D scene virtual bool wantScene(); + /// Scene post processing effects + virtual bool wantSceneEffects(); /// Interface within the 3D scene virtual bool wantInterface3D(); /// 2D Interface virtual bool wantInterface2D(); + /// Is this the first 3D scene of the frame + virtual bool isSceneFirst(); + /// Is this the last 3D scene of the frame + virtual bool isSceneLast(); + /// Returns true if a new render target was set, always fase if not using render targets virtual bool beginRenderTarget(); /// Returns true if a render target was fully drawn, always false if not using render targets diff --git a/code/nel/include/nel/3d/u_scene.h b/code/nel/include/nel/3d/u_scene.h index d60266afe..c0733c5d2 100644 --- a/code/nel/include/nel/3d/u_scene.h +++ b/code/nel/include/nel/3d/u_scene.h @@ -134,14 +134,17 @@ public: /** Render a part (see render() for what it does) * beginPartRender() must have been called * \param renderPart a combination of UScene::TRenderPart flags, allow to choose which part of the scene must be rendered + * \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if + * you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras). + * \param doTrav set to false when processing a second frame for stereo rending to avoid unnecessary traversals. * WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work * WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender() */ - virtual void renderPart(UScene::TRenderPart rp) =0; + virtual void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false) =0; /** End Part Rendering (commit model creation and deletion that were asked during rendering) */ - virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true) =0; + virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = false) =0; /** Update waiting instances and igs that are loaded asynchronously diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index e7dfe89b1..026e80e9c 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -92,7 +92,7 @@ CRenderTrav::CRenderTrav() // *************************************************************************** -void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender) +void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows) { #ifdef NL_DEBUG_RENDER_TRAV nlwarning("Render trave begin"); @@ -279,7 +279,8 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender) */ // Generate ShadowMaps - _ShadowMapManager.renderGenerate(Scene); + if (generateShadows) + _ShadowMapManager.renderGenerate(Scene); // Render the Landscape renderLandscapes(); diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index fb2d476ac..b58ad046c 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -353,28 +353,31 @@ void CScene::beginPartRender() // *************************************************************************** -void CScene::endPartRender() +void CScene::endPartRender(bool keepTrav) { nlassert(_IsRendering); - - // Delete model deleted during the rendering _IsRendering = false; - uint i; - for (i=0; i<_ToDelete.size(); i++) - deleteModel (_ToDelete[i]); - _ToDelete.clear (); - - // Special for SkeletonSpawnScript animation. create models spawned now - flushSSSModelRequests(); - - // Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed). - // Note that only a few of them are tested at each call - _ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos); - // Waiting Instance handling - double deltaT = _DeltaSystemTimeBetweenRender; - clamp (deltaT, 0.01, 0.1); - updateWaitingInstances(deltaT); + if (!keepTrav) + { + // Delete model deleted during the rendering + uint i; + for (i=0; i<_ToDelete.size(); i++) + deleteModel (_ToDelete[i]); + _ToDelete.clear (); + + // Special for SkeletonSpawnScript animation. create models spawned now + flushSSSModelRequests(); + + // Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed). + // Note that only a few of them are tested at each call + _ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos); + + // Waiting Instance handling + double deltaT = _DeltaSystemTimeBetweenRender; + clamp (deltaT, 0.01, 0.1); + updateWaitingInstances(deltaT); + } // Reset profiling _NextRenderProfile= false; @@ -555,7 +558,7 @@ void CScene::endPartRender() // *************************************************************************** -void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) +void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav) { nlassert(_IsRendering); @@ -569,25 +572,31 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) // if first part to be rendered, do the start stuff if (_RenderedPart == UScene::RenderNothing) { - // update water envmap - //updateWaterEnvmap(); RenderTrav.clearWaterModelList(); - _FirstFlare = NULL; - double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime()); - if(_GlobalSystemTime==0) - _DeltaSystemTimeBetweenRender= 0.020; - else - _DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime; - _GlobalSystemTime = fNewGlobalSystemTime; + if (doTrav) + { + // update water envmap + //updateWaterEnvmap(); + _FirstFlare = NULL; + + double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime()); + if(_GlobalSystemTime==0) + _DeltaSystemTimeBetweenRender= 0.020; + else + _DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime; + _GlobalSystemTime = fNewGlobalSystemTime; + } // ++ _NumRender; // nlassert(CurrentCamera); + // update models. updateModels(); + // Use the camera to setup Clip / Render pass. float left, right, bottom, top, znear, zfar; CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar); @@ -609,49 +618,70 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) // **** For all render traversals, traverse them (except the Hrc one), in ascending order. if( doHrcPass ) HrcTrav.traverse(); + else + HrcTrav._MovingObjects.clear(); // Set Cam World Matrix for all trav that need it ClipTrav.setCamMatrix(CurrentCamera->getWorldMatrix()); RenderTrav.setCamMatrix (CurrentCamera->getWorldMatrix()); LoadBalancingTrav.setCamMatrix (CurrentCamera->getWorldMatrix()); - // clip ClipTrav.traverse(); - // animDetail - AnimDetailTrav.traverse(); + + if (doTrav) + { + // animDetail + AnimDetailTrav.traverse(); + } + // loadBalance LoadBalancingTrav.traverse(); - // - if (_RequestParticlesAnimate) + + if (doTrav) { - _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems - _RequestParticlesAnimate = false; + // + if (_RequestParticlesAnimate) + { + _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems + _RequestParticlesAnimate = false; + } } + // Light LightTrav.traverse(); } // render - RenderTrav.traverse(rp, _RenderedPart == UScene::RenderNothing); - // Always must clear shadow caster (if render did not work because of IDriver::isLost()) - RenderTrav.getShadowMapManager().clearAllShadowCasters(); + RenderTrav.traverse(rp, (_RenderedPart == UScene::RenderNothing), doTrav); + if (!keepTrav) + { + // Always must clear shadow caster (if render did not work because of IDriver::isLost()) + RenderTrav.getShadowMapManager().clearAllShadowCasters(); + } // render flare if (rp & UScene::RenderFlare) { - if (_FirstFlare) + if (doTrav) { - IDriver *drv = getDriver(); - CFlareModel::updateOcclusionQueryBegin(drv); - CFlareModel *currFlare = _FirstFlare; - do + if (_FirstFlare) { - currFlare->updateOcclusionQuery(drv); - currFlare = currFlare->Next; + IDriver *drv = getDriver(); + CFlareModel::updateOcclusionQueryBegin(drv); + CFlareModel *currFlare = _FirstFlare; + do + { + currFlare->updateOcclusionQuery(drv); + currFlare = currFlare->Next; + } + while(currFlare); + CFlareModel::updateOcclusionQueryEnd(drv); } - while(currFlare); - CFlareModel::updateOcclusionQueryEnd(drv); + } + else + { + _FirstFlare = NULL; } } _RenderedPart = (UScene::TRenderPart) (_RenderedPart | rp); diff --git a/code/nel/src/3d/scene_user.cpp b/code/nel/src/3d/scene_user.cpp index 908e6a090..0df2439de 100644 --- a/code/nel/src/3d/scene_user.cpp +++ b/code/nel/src/3d/scene_user.cpp @@ -517,7 +517,7 @@ void CSceneUser::beginPartRender() } // *************************************************************************** -void CSceneUser::renderPart(TRenderPart rp) +void CSceneUser::renderPart(TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav) { // render the scene. @@ -526,18 +526,18 @@ void CSceneUser::renderPart(TRenderPart rp) if(_Scene.getCam() == NULL) nlerror("render(): try to render with no camera linked (may have been deleted)"); - _Scene.renderPart(rp, true); + _Scene.renderPart(rp, doHrcPass, doTrav, keepTrav); } } // *************************************************************************** -void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender) +void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender, bool keepTrav) { // render the scene. { NL3D_HAUTO_RENDER_SCENE_END - _Scene.endPartRender(); + _Scene.endPartRender(keepTrav); } if (updateWaitingInstancesFlag) updateWaitingInstances(); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 89ca605d0..f8067d99d 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -415,6 +415,12 @@ bool CStereoDebugger::wantScene() return m_Stage != 3; } +/// The 3D scene end (after multiple wantScene) +bool CStereoDebugger::wantSceneEffects() +{ + return m_Stage != 3; +} + /// Interface within the 3D scene bool CStereoDebugger::wantInterface3D() { @@ -429,6 +435,16 @@ bool CStereoDebugger::wantInterface2D() return m_Stage == 3; } +bool CStereoDebugger::isSceneFirst() +{ + return m_Stage == 1; +} + +bool CStereoDebugger::isSceneLast() +{ + return m_Stage == 2; +} + /// Returns true if a new render target was set, always fase if not using render targets bool CStereoDebugger::beginRenderTarget() { diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 527f065fd..0f1f0738e 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -640,6 +640,16 @@ bool CStereoOVR::wantScene() return m_Driver->getPolygonMode() != UDriver::Filled; } +bool CStereoOVR::wantSceneEffects() +{ + switch (m_Stage) + { + case 4: + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + bool CStereoOVR::wantInterface3D() { switch (m_Stage) @@ -663,6 +673,26 @@ bool CStereoOVR::wantInterface2D() return m_Driver->getPolygonMode() != UDriver::Filled; } +bool CStereoOVR::isSceneFirst() +{ + switch (m_Stage) + { + case 3: + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::isSceneLast() +{ + switch (m_Stage) + { + case 4: + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + /// Returns non-NULL if a new render target was set bool CStereoOVR::beginRenderTarget() { diff --git a/code/ryzom/client/src/landscape_poly_drawer.h b/code/ryzom/client/src/landscape_poly_drawer.h index 73d7fcadc..865112223 100644 --- a/code/ryzom/client/src/landscape_poly_drawer.h +++ b/code/ryzom/client/src/landscape_poly_drawer.h @@ -97,7 +97,9 @@ private: // renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart // methods. - friend void renderScene(); + friend void beginRenderScene(); + friend void drawRenderScene(bool wantTraversals, bool keepTraversals); + friend void endRenderScene(bool keepTraversals); // Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method, // before opaque render of canopy and main scene parts. diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 66fe7cc39..1ac6a4a0c 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -423,9 +423,9 @@ void beginRenderMainScenePart() { Scene->beginPartRender(); } -void endRenderMainScenePart() +void endRenderMainScenePart(bool keepTraversals) { - Scene->endPartRender(true); + Scene->endPartRender(!keepTraversals, true, keepTraversals); } void beginRenderSkyPart() @@ -462,7 +462,7 @@ static void renderCanopyPart(UScene::TRenderPart renderPart) // *************************************************************************************************************************** // Render a part of the main scene -static void renderMainScenePart(UScene::TRenderPart renderPart) +static void renderMainScenePart(UScene::TRenderPart renderPart, bool wantTraversals, bool keepTraversals) { H_AUTO_USE ( RZ_Client_Main_Loop_Render_Main ) Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); @@ -474,7 +474,7 @@ static void renderMainScenePart(UScene::TRenderPart renderPart) { MainFogState.setupInDriver (*Driver); } - Scene->renderPart(renderPart); + Scene->renderPart(renderPart, true, wantTraversals, keepTraversals); } @@ -580,7 +580,7 @@ void renderScene(bool forceFullDetail, bool bloom) s_ForceFullDetail.set(); } clearBuffers(); - renderScene(); + doRenderScene(true, false); if (forceFullDetail) { s_ForceFullDetail.restore(); @@ -719,9 +719,7 @@ void updateWeather() } } -// *************************************************************************************************************************** -// Render all scenes -void renderScene() +void beginRenderScene() { // Update Filter Flags Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); @@ -743,28 +741,45 @@ void renderScene() beginRenderCanopyPart(); beginRenderMainScenePart(); beginRenderSkyPart(); +} + +void drawRenderScene(bool wantTraversals, bool keepTraversals) +{ // Render part // WARNING: always must begin rendering with at least UScene::RenderOpaque, // else dynamic shadows won't work renderCanopyPart(UScene::RenderOpaque); - renderMainScenePart(UScene::RenderOpaque); + renderMainScenePart(UScene::RenderOpaque, wantTraversals, keepTraversals); // render of polygons on landscape CLandscapePolyDrawer::getInstance().renderLandscapePolyPart(); if (s_SkyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent)); renderCanopyPart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); - renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); + renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare), wantTraversals, keepTraversals); if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare); +} + +void endRenderScene(bool keepTraversals) +{ // End Part Rendering endRenderSkyPart(); - endRenderMainScenePart(); + endRenderMainScenePart(keepTraversals); endRenderCanopyPart(); // reset depth range Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); } +// *************************************************************************************************************************** +// Render all scenes +void doRenderScene(bool wantTraversals, bool keepTraversals) +{ + beginRenderScene(); + drawRenderScene(wantTraversals, keepTraversals); + endRenderScene(keepTraversals); +} + // *************************************************************************** class CMusicFader @@ -1628,7 +1643,6 @@ bool mainLoop() } uint i = 0; - bool effectRender = false; CTextureUser *effectRenderTarget = NULL; bool haveEffects = Render && Driver->getPolygonMode() == UDriver::Filled && (ClientCfg.Bloom || FXAA); @@ -1646,6 +1660,7 @@ bool mainLoop() CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); } } + bool fullDetail = false; while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; @@ -1686,42 +1701,59 @@ bool mainLoop() if (!StereoDisplay || StereoDisplay->wantClear()) { - if (Render) - { - effectRender = haveEffects; - } - // Clear buffers clearBuffers(); } if (!StereoDisplay || StereoDisplay->wantScene()) { - if (!ClientCfg.Light) + if (!ClientCfg.Light && Render) { - // Render - if(Render) + if (!StereoDisplay || StereoDisplay->isSceneFirst()) { // nb : force full detail if a screenshot is asked // todo : move outside render code - bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; - if (fullDetail) + if (!fullDetail) { - s_ForceFullDetail.backup(); - s_ForceFullDetail.set(); + fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; + if (fullDetail) + { + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); + } } + } - // Render scene - renderScene(); - + // Render scene + bool wantTraversals = !StereoDisplay || StereoDisplay->isSceneFirst(); + bool keepTraversals = StereoDisplay && !StereoDisplay->isSceneLast(); + doRenderScene(wantTraversals, keepTraversals); + + if (!StereoDisplay || StereoDisplay->isSceneLast()) + { if (fullDetail) { s_ForceFullDetail.restore(); + fullDetail = false; } } } } + if (!StereoDisplay || StereoDisplay->wantSceneEffects()) + { + if (!ClientCfg.Light && Render && haveEffects) + { + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + if (FXAA) FXAA->applyEffect(); + if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom(); + Driver->setMatrixMode3D(pCam); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + } + } + if (!StereoDisplay || StereoDisplay->wantInterface3D()) { if (!ClientCfg.Light) @@ -1729,18 +1761,6 @@ bool mainLoop() // Render if (Render) { - if (effectRender) - { - if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - UCamera pCam = Scene->getCam(); - Driver->setMatrixMode2D11(); - if (FXAA) FXAA->applyEffect(); - if (ClientCfg.Bloom) CBloomEffect::instance().applyBloom(); - Driver->setMatrixMode3D(pCam); - if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - effectRender = false; - } - // for that frame and // tmp : display height grid //static volatile bool displayHeightGrid = true; diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index 21f64d37e..93e4db36d 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -29,7 +29,7 @@ const uint NUM_MISSION_OPTIONS = 8; bool mainLoop(); // render all -void renderScene(); +void doRenderScene(bool wantTraversals, bool keepTraversals); void renderScene(bool forceFullDetail, bool bloom); void setDefaultChatWindow(CChatWindow *defaultChatWindow); From 7c39f7d33b4bbfe048de26871669db353e51dc56 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 01:04:58 +0200 Subject: [PATCH 074/240] Specify monitor when changing display mode --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/driver.h | 3 +- code/nel/include/nel/3d/stereo_debugger.h | 5 + code/nel/include/nel/3d/stereo_display.h | 5 + code/nel/include/nel/3d/stereo_ovr_04.h | 11 +++ code/nel/include/nel/3d/u_driver.h | 4 +- code/nel/src/3d/driver.cpp | 3 +- .../3d/driver/opengl/driver_opengl_window.cpp | 93 +++++++++++++++++-- code/nel/src/3d/driver_user.cpp | 6 +- code/nel/src/3d/scene.cpp | 7 +- code/nel/src/3d/stereo_debugger.cpp | 14 ++- code/nel/src/3d/stereo_ovr_04.cpp | 43 ++++++++- code/ryzom/client/src/connection.cpp | 7 ++ code/ryzom/client/src/main_loop_utilities.cpp | 10 +- 13 files changed, 187 insertions(+), 24 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index f19428cfb..8738a7dda 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -72,6 +72,7 @@ struct IOcclusionQuery; /// A Graphic Mode descriptor. struct GfxMode { + std::string DisplayDevice; bool OffScreen; bool Windowed; uint16 Width; @@ -90,7 +91,7 @@ struct GfxMode Frequency = 0; AntiAlias = -1; } - GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1); + GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string()); }; // **************************************************************************** diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index cd66a4fdc..81432d672 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -72,6 +72,11 @@ public: void getTextures(); void recycleTextures(); + /// Attach the driver to the display + virtual void attachToDisplay(); + /// Detach the driver from the display + virtual void detachFromDisplay(); + /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 52ec37354..2e37f0663 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -94,6 +94,11 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver) = 0; + + /// Attach the driver to the display + virtual void attachToDisplay() = 0; + /// Detach the driver from the display + virtual void detachFromDisplay() = 0; /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height) = 0; diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 7523819a5..f87ba2754 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,11 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver); + /// Attach the driver to the display + virtual void attachToDisplay(); + /// Detach the driver from the display + virtual void detachFromDisplay(); + /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera @@ -194,6 +200,11 @@ private: UMaterial m_UnlitMat; + UDriver::CMode m_OriginalMode; + sint32 m_OriginalWinPosX; + sint32 m_OriginalWinPosY; + bool m_AttachedDisplay; + /* NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index a64e13dd6..dc2b02e56 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -92,6 +92,7 @@ public: /// A Graphic Mode descriptor. struct CMode { + std::string DisplayDevice; bool Windowed; uint16 Width; uint16 Height; @@ -108,8 +109,9 @@ public: Frequency = 0; AntiAlias = -1; } - CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1) + CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string()) { + DisplayDevice = displayDevice; Windowed = windowed; Width = w; Height = h; diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 134c24410..791172700 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -123,8 +123,9 @@ bool IDriver::release(void) // *************************************************************************** -GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa) +GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa, const std::string &displayDevice) { + DisplayDevice = displayDevice; Windowed = windowed; Width = w; Height = h; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 03796206c..cb93a900c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1271,10 +1271,62 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info) // *************************************************************************** +#if defined(NL_OS_WINDOWS) + +struct CMonitorEnumParams +{ +public: + HWND Window; + const char *deviceName; +}; + +static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + CMonitorEnumParams *p = reinterpret_cast(dwData); + + MONITORINFOEXA monitorInfo; + memset(&monitorInfo, 0, sizeof(monitorInfo)); + monitorInfo.cbSize = sizeof(monitorInfo); + GetMonitorInfoA(hMonitor, &monitorInfo); + nldebug("3D: Monitor: '%s'", monitorInfo.szDevice); + + size_t devLen = strlen(monitorInfo.szDevice); + size_t targetLen = strlen(p->deviceName); + + nlassert(devLen < 32); + size_t minLen = min(devLen, targetLen); + if (!memcmp(monitorInfo.szDevice, p->deviceName, minLen)) + { + if (devLen == targetLen + || (devLen < targetLen && (p->deviceName[minLen] == '\\')) + || (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\'))) + { + nldebug("3D: Remap '%s' to '%s'", p->deviceName, monitorInfo.szDevice); + nldebug("Found our monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); + LONG dwStyle = GetWindowLong(p->Window, GWL_STYLE); + SetWindowLong(p->Window, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); + SetWindowPos(p->Window, NULL, + monitorInfo.rcMonitor.left, + monitorInfo.rcMonitor.top, + monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, + monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, + SWP_FRAMECHANGED); + return FALSE; + } + } + return TRUE; // continue +}; + +#endif + +// *************************************************************************** + bool CDriverGL::setScreenMode(const GfxMode &mode) { H_AUTO_OGL(CDriverGL_setScreenMode) + nldebug("3D: setScreenMode"); + if (mode.Windowed) { // if fullscreen, switch back to desktop screen mode @@ -1284,13 +1336,16 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) return true; } + if (!mode.DisplayDevice.empty()) + restoreScreenMode(); + // save previous screen mode only if switching from windowed to fullscreen if (_CurrentMode.Windowed) saveScreenMode(); // if switching exactly to the same screen mode, doesn't change it GfxMode previousMode; - if (getCurrentScreenMode(previousMode) + if (mode.DisplayDevice.empty() && getCurrentScreenMode(previousMode) && mode.Width == previousMode.Width && mode.Height == previousMode.Height && mode.Depth == previousMode.Depth @@ -1299,7 +1354,9 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) #if defined(NL_OS_WINDOWS) - DEVMODE devMode; + const char *deviceName = mode.DisplayDevice.c_str(); + + DEVMODEA devMode; memset(&devMode, 0, sizeof(DEVMODE)); devMode.dmSize = sizeof(DEVMODE); devMode.dmDriverExtra = 0; @@ -1307,22 +1364,42 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) devMode.dmPelsWidth = mode.Width; devMode.dmPelsHeight = mode.Height; - if(mode.Depth > 0) + if (mode.Depth > 0) { devMode.dmBitsPerPel = mode.Depth; devMode.dmFields |= DM_BITSPERPEL; } - if(mode.Frequency > 0) + if (mode.Frequency > 0) { devMode.dmDisplayFrequency = mode.Frequency; devMode.dmFields |= DM_DISPLAYFREQUENCY; } - - if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + + if (deviceName[0]) { - nlwarning("3D: Fullscreen mode switch failed"); - return false; + // First attempt exclusive fullscreen + nldebug("3D: ChangeDisplaySettingsEx"); + LONG resex; + if ((resex = ChangeDisplaySettingsExA(deviceName, &devMode, NULL, CDS_FULLSCREEN, NULL)) != DISP_CHANGE_SUCCESSFUL) + { + nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex); + // Workaround, resize to monitor and make borderless + CMonitorEnumParams p; + p.deviceName = deviceName; + p.Window = _win; + EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p); + return false; // FIXME: This is a hack, don't process further + } + } + else + { + nldebug("3D: ChangeDisplaySettings"); + if (ChangeDisplaySettingsA(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + { + nlwarning("3D: Fullscreen mode switch failed"); + return false; + } } #elif defined(NL_OS_MAC) diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 403b5859c..c4dc97655 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -249,7 +249,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool NL3D_HAUTO_UI_DRIVER; // window init. - if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias), show, resizeable)) + if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice), show, resizeable)) { // Always true nlverify (activate()); @@ -293,7 +293,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool // *************************************************************************** bool CDriverUser::setMode(const CMode& mode) { - return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias)); + return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice)); } // ---------------------------------------------------------------------------- @@ -319,7 +319,7 @@ bool CDriverUser::getModes(std::vector &modes) bool res = _Driver->getModes(vTmp); modes.clear(); for (uint i = 0; i < vTmp.size(); ++i) - modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias)); + modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias, vTmp[i].DisplayDevice)); std::sort(modes.begin(), modes.end(), CModeSorter()); diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index b58ad046c..67465eb8c 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -629,11 +629,8 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, boo // clip ClipTrav.traverse(); - if (doTrav) - { - // animDetail - AnimDetailTrav.traverse(); - } + // animDetail + AnimDetailTrav.traverse(); // loadBalance LoadBalancingTrav.traverse(); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index f8067d99d..940ada508 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -211,6 +211,16 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } } +void CStereoDebugger::attachToDisplay() +{ + +} + +void CStereoDebugger::detachFromDisplay() +{ + +} + void CStereoDebugger::getTextures() { nlassert(!m_LeftTexU); @@ -437,12 +447,12 @@ bool CStereoDebugger::wantInterface2D() bool CStereoDebugger::isSceneFirst() { - return m_Stage == 1; + return m_Stage != 3; } bool CStereoDebugger::isSceneLast() { - return m_Stage == 2; + return m_Stage != 3; } /// Returns true if a new render target was set, always fase if not using render targets diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 0f1f0738e..0fd4b9ba2 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -165,7 +165,7 @@ static float lerp(float f0, float f1, float factor) return (f1 * factor) + (f0 * (1.0f - factor)); } -CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f), m_AttachedDisplay(false) { nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count); @@ -371,6 +371,11 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL CStereoOVR::~CStereoOVR() { + if (m_AttachedDisplay) + { + detachFromDisplay(); + } + if (!m_UnlitMat.empty()) { m_Driver->deleteMaterial(m_UnlitMat); @@ -439,6 +444,38 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height) return false; } +void CStereoOVR::attachToDisplay() +{ + nldebug("OVR: Attach to display '%s'", m_DevicePtr->DisplayDeviceName); + + if (!m_AttachedDisplay) + { + m_Driver->getCurrentScreenMode(m_OriginalMode); + m_Driver->getWindowPos(m_OriginalWinPosX, m_OriginalWinPosY); + } + + UDriver::CMode mode; + mode.DisplayDevice = m_DevicePtr->DisplayDeviceName; + mode.Windowed = false; + mode.Width = m_DevicePtr->Resolution.w; + mode.Height = m_DevicePtr->Resolution.h; + m_Driver->setMode(mode); + m_AttachedDisplay = true; +} + +void CStereoOVR::detachFromDisplay() +{ + if (!m_OriginalMode.Windowed) + { + m_OriginalMode.Windowed = true; + m_Driver->setMode(m_OriginalMode); + m_OriginalMode.Windowed = false; + } + m_Driver->setMode(m_OriginalMode); + m_Driver->setWindowPos(m_OriginalWinPosX, m_OriginalWinPosY); + m_AttachedDisplay = false; +} + void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { m_OriginalFrustum[cid] = camera->getFrustum(); @@ -679,6 +716,8 @@ bool CStereoOVR::isSceneFirst() { case 3: return true; + case 4: + return false; } return m_Driver->getPolygonMode() != UDriver::Filled; } @@ -687,6 +726,8 @@ bool CStereoOVR::isSceneLast() { switch (m_Stage) { + case 3: + return false; case 4: return true; } diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 9376b6059..58dbca399 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -31,6 +31,7 @@ // 3D Interface. #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" +#include // Game Share //#include "game_share/gd_time.h" // \todo GUIGUI : TO DELETE/CHANGE #include "game_share/gender.h" @@ -217,6 +218,9 @@ void connectionRestaureVideoMode () setVideoMode(mode); } + if (StereoDisplay) + StereoDisplay->attachToDisplay(); + // And setup hardware mouse if we have to InitMouseWithCursor (ClientCfg.HardwareCursor); SetMouseFreeLook (); @@ -253,6 +257,9 @@ void setOutGameFullScreen() // NB: don't setup fullscreen if player wants to play in window if (!ClientCfg.Local && ClientCfg.SelectCharacter == -1) { + if (StereoDisplay) + StereoDisplay->detachFromDisplay(); + UDriver::CMode currMode; Driver->getCurrentScreenMode(currMode); UDriver::CMode wantedMode; diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index 0fe52e53c..7db7cc0bb 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "game_share/scenario_entry_points.h" @@ -60,6 +61,8 @@ void updateFromClientCfg() nldebug("Apply VR device change"); releaseStereoDisplayDevice(); initStereoDisplayDevice(); + if (StereoDisplay) + StereoDisplay->attachToDisplay(); } // GRAPHICS - GENERAL @@ -70,8 +73,11 @@ void updateFromClientCfg() (ClientCfg.Depth != LastClientCfg.Depth) || (ClientCfg.Frequency != LastClientCfg.Frequency)) { - setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, - ClientCfg.Windowed, ClientCfg.Frequency)); + if (!StereoDisplay) // TODO + { + setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, + ClientCfg.Windowed, ClientCfg.Frequency)); + } } if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) From 400f479fe1eff303067a1743fd31da1103333c8b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 04:18:17 +0200 Subject: [PATCH 075/240] GL: Handle borderless fullscreen to specified monitor internally --HG-- branch : multipass-stereo --- .../src/3d/driver/opengl/driver_opengl.cpp | 4 + code/nel/src/3d/driver/opengl/driver_opengl.h | 6 + .../3d/driver/opengl/driver_opengl_window.cpp | 110 ++++++++++++++---- code/nel/src/3d/stereo_ovr_04.cpp | 4 +- 4 files changed, 100 insertions(+), 24 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index ce60d7f42..e9965e0f1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -234,6 +234,10 @@ CDriverGL::CDriverGL() _CursorScale = 1.f; _MouseCaptured = false; +#if defined(NL_OS_WINDOWS) + _BorderlessFullscreen = false; +#endif + _NeedToRestaureGammaRamp = false; _win = EmptyWindow; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index c4540b9da..fb6069447 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -996,6 +996,12 @@ private: EWindowStyle getWindowStyle() const; bool setWindowStyle(EWindowStyle windowStyle); +#if defined(NL_OS_WINDOWS) + static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData); + bool _BorderlessFullscreen; +#endif + std::string _CurrentDisplayDevice; + // Methods to manage screen resolutions bool restoreScreenMode(); bool saveScreenMode(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index cb93a900c..2e9da2431 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1276,11 +1276,12 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info) struct CMonitorEnumParams { public: - HWND Window; - const char *deviceName; + CDriverGL *Driver; + const char *DeviceName; + bool Success; }; -static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +BOOL CALLBACK CDriverGL::monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) { CMonitorEnumParams *p = reinterpret_cast(dwData); @@ -1291,29 +1292,36 @@ static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, L nldebug("3D: Monitor: '%s'", monitorInfo.szDevice); size_t devLen = strlen(monitorInfo.szDevice); - size_t targetLen = strlen(p->deviceName); + size_t targetLen = strlen(p->DeviceName); nlassert(devLen < 32); size_t minLen = min(devLen, targetLen); - if (!memcmp(monitorInfo.szDevice, p->deviceName, minLen)) + if (!memcmp(monitorInfo.szDevice, p->DeviceName, minLen)) { if (devLen == targetLen - || (devLen < targetLen && (p->deviceName[minLen] == '\\')) + || (devLen < targetLen && (p->DeviceName[minLen] == '\\')) || (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\'))) { - nldebug("3D: Remap '%s' to '%s'", p->deviceName, monitorInfo.szDevice); - nldebug("Found our monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); - LONG dwStyle = GetWindowLong(p->Window, GWL_STYLE); - SetWindowLong(p->Window, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); - SetWindowPos(p->Window, NULL, + nldebug("3D: Remapping '%s' to '%s'", p->DeviceName, monitorInfo.szDevice); + nldebug("3D: Found requested monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); + LONG dwStyle = GetWindowLong(p->Driver->_win, GWL_STYLE); + SetWindowLong(p->Driver->_win, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); + SetWindowPos(p->Driver->_win, NULL, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, SWP_FRAMECHANGED); + p->Driver->_WindowX = monitorInfo.rcMonitor.left; + p->Driver->_WindowY = monitorInfo.rcMonitor.top; + p->Driver->_CurrentDisplayDevice = std::string(p->DeviceName); + p->Driver->_BorderlessFullscreen = true; + p->Driver->_CurrentMode.Windowed = false; + p->Success = true; return FALSE; } } + p->Success = false; return TRUE; // continue }; @@ -1327,6 +1335,19 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) nldebug("3D: setScreenMode"); +#if defined(NL_OS_WINDOWS) + if (_BorderlessFullscreen) + { + _BorderlessFullscreen = false; + LONG dwStyle = GetWindowLong(_win, GWL_STYLE); + dwStyle |= WS_OVERLAPPEDWINDOW; + if (!_Resizable) dwStyle ^= WS_MAXIMIZEBOX|WS_THICKFRAME; + SetWindowLong(_win, GWL_STYLE, dwStyle); + SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + _CurrentMode.Windowed = true; + } +#endif + if (mode.Windowed) { // if fullscreen, switch back to desktop screen mode @@ -1336,7 +1357,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) return true; } - if (!mode.DisplayDevice.empty()) + if (_CurrentDisplayDevice != mode.DisplayDevice) restoreScreenMode(); // save previous screen mode only if switching from windowed to fullscreen @@ -1345,7 +1366,8 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) // if switching exactly to the same screen mode, doesn't change it GfxMode previousMode; - if (mode.DisplayDevice.empty() && getCurrentScreenMode(previousMode) + if (_CurrentDisplayDevice == mode.DisplayDevice + && getCurrentScreenMode(previousMode) && mode.Width == previousMode.Width && mode.Height == previousMode.Height && mode.Depth == previousMode.Depth @@ -1386,10 +1408,10 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex); // Workaround, resize to monitor and make borderless CMonitorEnumParams p; - p.deviceName = deviceName; - p.Window = _win; + p.DeviceName = deviceName; + p.Driver = this; EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p); - return false; // FIXME: This is a hack, don't process further + return p.Success; } } else @@ -1805,7 +1827,11 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) dwNewStyle |= WS_VISIBLE; if (dwStyle != dwNewStyle) + { SetWindowLong(_win, GWL_STYLE, dwNewStyle); + if (windowStyle == EWSWindowed) + SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + } // if (windowStyle == EWSMaximized && isVisible && !isMaximized) // ShowWindow(_hWnd, SW_SHOWMAXIMIZED); @@ -1925,17 +1951,32 @@ bool CDriverGL::setMode(const GfxMode& mode) if (!_DestroyWindow) return true; +#if defined(NL_OS_WINDOWS) + // save relative cursor + POINT cursorPos; + BOOL cursorPosOk = isSystemCursorInClientArea() + && GetCursorPos(&cursorPos) + && ScreenToClient(_win, &cursorPos); + sint curX = (sint)cursorPos.x * (sint)mode.Width; + sint curY = (sint)cursorPos.y * (sint)mode.Height; + if (_BorderlessFullscreen) + ReleaseCapture(); +#endif + if (!setScreenMode(mode)) return false; - // when changing window style, it's possible system change window size too - setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); + if (!_BorderlessFullscreen) + { + // when changing window style, it's possible system change window size too + setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); - if (!mode.Windowed) - _CurrentMode.Depth = mode.Depth; + if (!mode.Windowed) + _CurrentMode.Depth = mode.Depth; - setWindowSize(mode.Width, mode.Height); - setWindowPos(_WindowX, _WindowY); + setWindowSize(mode.Width, mode.Height); + setWindowPos(_WindowX, _WindowY); + } switch (_CurrentMode.Depth) { @@ -1944,6 +1985,19 @@ bool CDriverGL::setMode(const GfxMode& mode) case 32: _ColorDepth = ColorDepth32; break; } +#if defined(NL_OS_WINDOWS) + // restore relative cursor + if (cursorPosOk) + { + cursorPos.x = curX / (sint)mode.Width; + cursorPos.y = curY / (sint)mode.Height; + ClientToScreen(_win, &cursorPos); + SetCursorPos(cursorPos.x, cursorPos.y); + if (_BorderlessFullscreen) + SetCapture(_win); + } +#endif + // set color depth for custom cursor updateCursor(true); @@ -2359,8 +2413,20 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y) #ifdef NL_OS_WINDOWS + // save relative cursor + POINT cursorPos; + BOOL cursorPosOk = isSystemCursorInClientArea() + && GetCursorPos(&cursorPos) + && ScreenToClient(_win, &cursorPos); + SetWindowPos(_win, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); + if (cursorPosOk) + { + ClientToScreen(_win, &cursorPos); + SetCursorPos(cursorPos.x, cursorPos.y); + } + #elif defined(NL_OS_MAC) // get the rect (position, size) of the screen with menu bar NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 0fd4b9ba2..3eb666360 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -465,12 +465,12 @@ void CStereoOVR::attachToDisplay() void CStereoOVR::detachFromDisplay() { - if (!m_OriginalMode.Windowed) + /*if (!m_OriginalMode.Windowed) { m_OriginalMode.Windowed = true; m_Driver->setMode(m_OriginalMode); m_OriginalMode.Windowed = false; - } + }*/ m_Driver->setMode(m_OriginalMode); m_Driver->setWindowPos(m_OriginalWinPosX, m_OriginalWinPosY); m_AttachedDisplay = false; From e2bfb5d542601941e5c96e7c6f2316cf12feb1a8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 04:36:51 +0200 Subject: [PATCH 076/240] Clean handling of display mode switching in client --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_debugger.h | 2 +- code/nel/include/nel/3d/stereo_display.h | 4 ++-- code/nel/include/nel/3d/stereo_ovr_04.h | 2 +- .../src/3d/driver/opengl/driver_opengl_window.cpp | 2 +- code/nel/src/3d/stereo_debugger.cpp | 4 ++-- code/nel/src/3d/stereo_ovr_04.cpp | 3 ++- code/ryzom/client/src/connection.cpp | 14 ++++++++------ code/ryzom/client/src/global.cpp | 1 + code/ryzom/client/src/global.h | 1 + code/ryzom/client/src/main_loop_utilities.cpp | 14 ++++++++++++-- 10 files changed, 31 insertions(+), 16 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index 81432d672..6c974f93d 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -73,7 +73,7 @@ public: void recycleTextures(); /// Attach the driver to the display - virtual void attachToDisplay(); + virtual bool attachToDisplay(); /// Detach the driver from the display virtual void detachFromDisplay(); diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 2e37f0663..3b6fdbb21 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -95,8 +95,8 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver) = 0; - /// Attach the driver to the display - virtual void attachToDisplay() = 0; + /// Attach the driver to the display, return true if attached + virtual bool attachToDisplay() = 0; /// Detach the driver from the display virtual void detachFromDisplay() = 0; diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index f87ba2754..a424eff2e 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -91,7 +91,7 @@ public: virtual void setDriver(NL3D::UDriver *driver); /// Attach the driver to the display - virtual void attachToDisplay(); + virtual bool attachToDisplay(); /// Detach the driver from the display virtual void detachFromDisplay(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 2e9da2431..65f219fc7 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -2419,7 +2419,7 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y) && GetCursorPos(&cursorPos) && ScreenToClient(_win, &cursorPos); - SetWindowPos(_win, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); + SetWindowPos(_win, NULL, x, y, 0, 0, /*SWP_NOZORDER | SWP_NOACTIVATE |*/ SWP_NOSIZE); if (cursorPosOk) { diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 940ada508..6650e1c2b 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -211,9 +211,9 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } } -void CStereoDebugger::attachToDisplay() +bool CStereoDebugger::attachToDisplay() { - + return false; } void CStereoDebugger::detachFromDisplay() diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 3eb666360..fb6b86411 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -444,7 +444,7 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height) return false; } -void CStereoOVR::attachToDisplay() +bool CStereoOVR::attachToDisplay() { nldebug("OVR: Attach to display '%s'", m_DevicePtr->DisplayDeviceName); @@ -461,6 +461,7 @@ void CStereoOVR::attachToDisplay() mode.Height = m_DevicePtr->Resolution.h; m_Driver->setMode(mode); m_AttachedDisplay = true; + return true; } void CStereoOVR::detachFromDisplay() diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 58dbca399..d9051d820 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -206,9 +206,13 @@ void connectionRestaureVideoMode () if (ClientCfg.Width < 800) ClientCfg.Width = 800; if (ClientCfg.Height < 600) ClientCfg.Height = 600; - if ((ClientCfg.Windowed != mode.Windowed) || + if (StereoDisplay) + StereoDisplayAttached = StereoDisplay->attachToDisplay(); + + if (!StereoDisplayAttached && ( + (ClientCfg.Windowed != mode.Windowed) || (ClientCfg.Width != mode.Width) || - (ClientCfg.Height != mode.Height)) + (ClientCfg.Height != mode.Height))) { mode.Windowed = ClientCfg.Windowed; mode.Depth = uint8(ClientCfg.Depth); @@ -218,9 +222,6 @@ void connectionRestaureVideoMode () setVideoMode(mode); } - if (StereoDisplay) - StereoDisplay->attachToDisplay(); - // And setup hardware mouse if we have to InitMouseWithCursor (ClientCfg.HardwareCursor); SetMouseFreeLook (); @@ -257,8 +258,9 @@ void setOutGameFullScreen() // NB: don't setup fullscreen if player wants to play in window if (!ClientCfg.Local && ClientCfg.SelectCharacter == -1) { - if (StereoDisplay) + if (StereoDisplayAttached) StereoDisplay->detachFromDisplay(); + StereoDisplayAttached = false; UDriver::CMode currMode; Driver->getCurrentScreenMode(currMode); diff --git a/code/ryzom/client/src/global.cpp b/code/ryzom/client/src/global.cpp index 83be0e04f..7c298ca58 100644 --- a/code/ryzom/client/src/global.cpp +++ b/code/ryzom/client/src/global.cpp @@ -28,6 +28,7 @@ using namespace NLMISC; NL3D::UDriver *Driver = NULL; // The main 3D Driver NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display +bool StereoDisplayAttached = false; // Is stereo display handling the display mode CSoundManager *SoundMngr = NULL; // the sound manager NL3D::UMaterial GenericMat; // Generic Material NL3D::UTextContext *TextContext = NULL; // Context for all the text in the client. diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h index ac47b22cc..de9aa6a73 100644 --- a/code/ryzom/client/src/global.h +++ b/code/ryzom/client/src/global.h @@ -82,6 +82,7 @@ const float ExtraZoneLoadingVision = 100.f; extern NL3D::UDriver *Driver; // The main 3D Driver extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display extern NL3D::IStereoHMD *StereoHMD; // Head mount display +extern bool StereoDisplayAttached; // Is stereo display handling the display mode extern CSoundManager *SoundMngr; // the sound manager extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UTextContext *TextContext; // Context for all the text in the client. diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index 7db7cc0bb..ecf3c7fae 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -59,10 +59,20 @@ void updateFromClientCfg() ))) { nldebug("Apply VR device change"); + // detach display mode + if (StereoDisplay && StereoDisplayAttached) + StereoDisplay->detachFromDisplay(); + StereoDisplayAttached = false; + // re-init releaseStereoDisplayDevice(); initStereoDisplayDevice(); + // try attach display mode if (StereoDisplay) - StereoDisplay->attachToDisplay(); + StereoDisplayAttached = StereoDisplay->attachToDisplay(); + // set latest config display mode if not attached + if (!StereoDisplayAttached) + setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, + ClientCfg.Windowed, ClientCfg.Frequency)); } // GRAPHICS - GENERAL @@ -73,7 +83,7 @@ void updateFromClientCfg() (ClientCfg.Depth != LastClientCfg.Depth) || (ClientCfg.Frequency != LastClientCfg.Frequency)) { - if (!StereoDisplay) // TODO + if (!StereoDisplayAttached) { setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, ClientCfg.Windowed, ClientCfg.Frequency)); From aff0cab54e5e6fc74714082f30d42ee98c581ef2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 04:45:14 +0200 Subject: [PATCH 077/240] GL: Fix switch from different resolution fullscreen to borderless display --HG-- branch : multipass-stereo --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 65f219fc7..4e08884b0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1304,6 +1304,9 @@ BOOL CALLBACK CDriverGL::monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPREC { nldebug("3D: Remapping '%s' to '%s'", p->DeviceName, monitorInfo.szDevice); nldebug("3D: Found requested monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); + p->Driver->_CurrentMode.Windowed = false; + p->Driver->setWindowStyle(CDriverGL::EWSWindowed); + p->Driver->setWindowSize(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top); LONG dwStyle = GetWindowLong(p->Driver->_win, GWL_STYLE); SetWindowLong(p->Driver->_win, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); SetWindowPos(p->Driver->_win, NULL, From 38a418503d2851a1abe302a6aa3954311cc8b04e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 05:09:11 +0200 Subject: [PATCH 078/240] Non-functional direct to rift --HG-- branch : multipass-stereo --- code/nel/src/3d/stereo_ovr_04.cpp | 32 +++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index fb6b86411..dc814222e 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -454,14 +454,30 @@ bool CStereoOVR::attachToDisplay() m_Driver->getWindowPos(m_OriginalWinPosX, m_OriginalWinPosY); } - UDriver::CMode mode; - mode.DisplayDevice = m_DevicePtr->DisplayDeviceName; - mode.Windowed = false; - mode.Width = m_DevicePtr->Resolution.w; - mode.Height = m_DevicePtr->Resolution.h; - m_Driver->setMode(mode); - m_AttachedDisplay = true; - return true; +#if defined(NL_OS_WINDOWS) + if ((m_DevicePtr->HmdCaps & ovrHmdCap_ExtendDesktop) != ovrHmdCap_ExtendDesktop) + { + nldebug("OVR: Direct Rift"); + CDriverUser *dru = static_cast(m_Driver); + IDriver *drv = dru->getDriver(); + m_AttachedDisplay = ovrHmd_AttachToWindow(m_DevicePtr, (void *)drv->getDisplay(), NULL, NULL); + if (!m_AttachedDisplay) + nlwarning("OVR: Direct Rift failed!"); + } + else +#endif + { + nldebug("OVR: Extended Rift"); + UDriver::CMode mode; + mode.DisplayDevice = m_DevicePtr->DisplayDeviceName; + mode.Windowed = false; + mode.Width = m_DevicePtr->Resolution.w; + mode.Height = m_DevicePtr->Resolution.h; + m_Driver->setMode(mode); + m_AttachedDisplay = true; + } + + return m_AttachedDisplay; } void CStereoOVR::detachFromDisplay() From 38abf2193fe14e49b08fb50e6b619e6ee8400c07 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 18:49:05 +0200 Subject: [PATCH 079/240] Project client loading screens into 3D space for HMD --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr_04.h | 1 + code/nel/src/3d/stereo_ovr_04.cpp | 64 ++++- code/ryzom/client/src/progress.cpp | 359 ++++++++++++++---------- 3 files changed, 275 insertions(+), 149 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index a424eff2e..8bda88c88 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -168,6 +168,7 @@ public: private: ovrHmd m_DevicePtr; + bool m_DebugDevice; int m_Stage; int m_SubStage; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index dc814222e..121855fb8 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -175,6 +175,7 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL return; } + m_DebugDevice = factory->DebugDevice; if (factory->DebugDevice) m_DevicePtr = ovrHmd_CreateDebug(factory->DebugDeviceType); else m_DevicePtr = ovrHmd_Create(factory->DeviceIndex); @@ -448,6 +449,9 @@ bool CStereoOVR::attachToDisplay() { nldebug("OVR: Attach to display '%s'", m_DevicePtr->DisplayDeviceName); + if (m_DebugDevice) + return false; + if (!m_AttachedDisplay) { m_Driver->getCurrentScreenMode(m_OriginalMode); @@ -792,7 +796,7 @@ void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix) void CStereoOVR::renderGUI() { m_Driver->setModelMatrix(m_InterfaceCameraMatrix); - +/* { NLMISC::CLine line(NLMISC::CVector(0, 5, 2), NLMISC::CVector(0, 5, 3)); @@ -807,7 +811,42 @@ void CStereoOVR::renderGUI() m_Driver->deleteMaterial(mat); } - + + { + NL3D::UMaterial mat = m_Driver->createMaterial(); + mat.setZWrite(false); + mat.setZFunc(UMaterial::always); // Not nice! + mat.setDoubleSided(true); + mat.setBlend(false); + NLMISC::CLine line; + + mat.setColor(NLMISC::CRGBA::Red); + line = NLMISC::CLine(NLMISC::CVector(0, 3, -3), NLMISC::CVector(0, 3, 3)); // YPos + m_Driver->drawLine(line, mat); + + mat.setColor(NLMISC::CRGBA::Green); + line = NLMISC::CLine(NLMISC::CVector(3, 0, -3), NLMISC::CVector(3, 0, 3)); // XPos + m_Driver->drawLine(line, mat); + + mat.setColor(NLMISC::CRGBA::Magenta); + line = NLMISC::CLine(NLMISC::CVector(0, -3, -3), NLMISC::CVector(0, -3, 3)); // YNeg + m_Driver->drawLine(line, mat); + + mat.setColor(NLMISC::CRGBA::Cyan); + line = NLMISC::CLine(NLMISC::CVector(-3, 0, -3), NLMISC::CVector(-3, 0, 3)); // XNeg + m_Driver->drawLine(line, mat); + + mat.setColor(NLMISC::CRGBA::Blue); + line = NLMISC::CLine(NLMISC::CVector(0, -3, 3), NLMISC::CVector(0, 3, 3)); // ZPos + m_Driver->drawLine(line, mat); + + mat.setColor(NLMISC::CRGBA::Blue); + line = NLMISC::CLine(NLMISC::CVector(0, -3, -3), NLMISC::CVector(0, 3, -3)); // ZNeg + m_Driver->drawLine(line, mat); + + m_Driver->deleteMaterial(mat); + } + */ { nlassert(m_GUITexture); @@ -910,6 +949,24 @@ void CStereoOVR::renderGUI() // m_Driver->drawQuad(quadUV, umat); m_Driver->deleteMaterial(umat); + + /*{ + // nldebug("Render GUI lines"); + NL3D::UMaterial rmat = m_Driver->createMaterial(); + rmat.setZWrite(false); + rmat.setZFunc(UMaterial::always); // Not nice! + rmat.setDoubleSided(true); + rmat.setColor(NLMISC::CRGBA::Red); + rmat.setBlend(false); + + m_Driver->setPolygonMode(UDriver::Line); + driver->activeVertexBuffer(vb); + driver->activeIndexBuffer(ib); + driver->renderTriangles(*rmat.getObjectPtr(), 0, nbQuads * 2); + m_Driver->setPolygonMode(UDriver::Filled); + + m_Driver->deleteMaterial(rmat); + }*/ } } @@ -1131,7 +1188,8 @@ NLMISC::CQuat CStereoOVR::getOrientation() const } else { - nlwarning("OVR: No orientation returned"); + if (!m_DebugDevice) + nlwarning("OVR: No orientation returned"); // return old orientation m_OrientationCached = true; return m_OrientationCache; diff --git a/code/ryzom/client/src/progress.cpp b/code/ryzom/client/src/progress.cpp index 0d5d4e4c9..8b5f72941 100644 --- a/code/ryzom/client/src/progress.cpp +++ b/code/ryzom/client/src/progress.cpp @@ -33,6 +33,7 @@ #include "client_cfg.h" #include "bg_downloader_access.h" #include "nel/misc/system_utils.h" +#include "nel/3d/stereo_hmd.h" using namespace std; using namespace NLMISC; @@ -173,186 +174,252 @@ void CProgress::internalProgress (float value) if (Driver->AsyncListener.isKeyPushed (KeyUP)) selectTipsOfTheDay (TipsOfTheDayIndex+1); - // Font factor - float fontFactor = 1; - if (Driver->getWindowHeight() > 0) - fontFactor = (float)Driver->getWindowHeight() / 600.f; - fontFactor *= _FontFactor; - // Set 2d view. - Driver->setMatrixMode2D11(); - Driver->clearBuffers (CRGBA(0,0,0,0)); + // Create camera for stereo mode + bool stereoHMD = StereoHMD && !MainCam.empty() && (MainCam.getTransformMode() == UCamera::RotQuat); + CVector oldPos; + CQuat oldQuat; + if (stereoHMD) + { + MainCam.getPos(oldPos); + MainCam.getRotQuat(oldQuat); + StereoHMD->setInterfaceMatrix(CMatrix()); // identity + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); + NLMISC::CMatrix camMatrix; + camMatrix.identity(); + NLMISC::CMatrix hmdMatrix; + hmdMatrix.setRot(hmdOrient); + NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future + posMatrix.translate(StereoHMD->getEyePosition()); + NLMISC::CMatrix mat = ((camMatrix * hmdMatrix) * posMatrix); + MainCam.setPos(mat.getPos()); + MainCam.setRotQuat(mat.getRot()); + StereoDisplay->updateCamera(0, &MainCam); + } + uint i = 0; + while ((!stereoHMD && i == 0) || (stereoHMD && StereoDisplay->nextPass())) + { + ++i; + if (stereoHMD) + { + // modify cameras for stereo display + const CViewport &vp = StereoDisplay->getCurrentViewport(); + Driver->setViewport(vp); + StereoDisplay->getCurrentMatrix(0, &MainCam); + StereoDisplay->getCurrentFrustum(0, &MainCam); - // Display the loading background. - drawLoadingBitmap (value); + // begin current pass + StereoDisplay->beginRenderTarget(); - // temporary values for conversions - float x, y, width, height; + nldebug("Cam pos: %f, %f, %f", MainCam.getPos().x, MainCam.getPos().y, MainCam.getPos().z); + } - for(uint i = 0; i < ClientCfg.Logos.size(); i++) - { - std::vector res; - explode(ClientCfg.Logos[i], std::string(":"), res); - if(res.size()==9 && iwantClear()) { - fromString(res[1], x); - fromString(res[2], y); - fromString(res[3], width); - fromString(res[4], height); - Driver->drawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + Driver->clearBuffers(CRGBA(0, 0, 0, 0)); } - } - if (TextContext != NULL) - { - // Init the Pen. - TextContext->setKeep800x600Ratio(false); - TextContext->setColor(CRGBA(255,255,255)); - TextContext->setFontSize((uint)(12.f * fontFactor)); - TextContext->setHotSpot(UTextContext::TopRight); + if (stereoHMD && StereoDisplay->wantScene()) + { + Driver->setMatrixMode3D(MainCam); + } + + if (!stereoHMD || StereoDisplay->wantInterface2D()) + { + nldebug("Draw progress 2D"); + + // Font factor + float fontFactor = 1; + if (Driver->getWindowHeight() > 0) + fontFactor = (float)Driver->getWindowHeight() / 600.f; + fontFactor *= _FontFactor; + + // Set 2d view. + Driver->setMatrixMode2D11(); + + // Display the loading background. + drawLoadingBitmap(value); + + // temporary values for conversions + float x, y, width, height; + + for(uint i = 0; i < ClientCfg.Logos.size(); i++) + { + std::vector res; + explode(ClientCfg.Logos[i], std::string(":"), res); + if(res.size()==9 && idrawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + } + } + + if (TextContext != NULL) + { + // Init the Pen. + TextContext->setKeep800x600Ratio(false); + TextContext->setColor(CRGBA(255,255,255)); + TextContext->setFontSize((uint)(12.f * fontFactor)); + TextContext->setHotSpot(UTextContext::TopRight); #if !FINAL_VERSION - // Display the Text. - TextContext->printAt(1, 0.98f, _ProgressMessage); + // Display the Text. + TextContext->printAt(1, 0.98f, _ProgressMessage); #else - if( ClientCfg.LoadingStringCount > 0 ) - { - TextContext->printAt(1, 0.98f, _ProgressMessage); - } + if( ClientCfg.LoadingStringCount > 0 ) + { + TextContext->printAt(1, 0.98f, _ProgressMessage); + } #endif // FINAL_VERSION - // Display the build version. - TextContext->setFontSize((uint)(12.f * fontFactor)); - TextContext->setHotSpot(UTextContext::TopRight); - string str; + // Display the build version. + TextContext->setFontSize((uint)(12.f * fontFactor)); + TextContext->setHotSpot(UTextContext::TopRight); + string str; #if FINAL_VERSION - str = "FV "; + str = "FV "; #else - str = "DEV "; + str = "DEV "; #endif - str += RYZOM_VERSION; - TextContext->printfAt(1.0f,1.0f, str.c_str()); - - // Display the tips of the day. - TextContext->setFontSize((uint)(16.f * fontFactor)); - TextContext->setHotSpot(UTextContext::MiddleTop); - ucstring::size_type index = 0; - ucstring::size_type end = TipsOfTheDay.find((ucchar)'\n'); - if (end == string::npos) - end = TipsOfTheDay.size(); - float fY = ClientCfg.TipsY; - if (!TipsOfTheDay.empty()) - { - while (index < end) - { - // Get the line - ucstring line = TipsOfTheDay.substr (index, end-index); - - // Draw the line - TextContext->printAt(0.5f, fY, line); - fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); - - index=end+1; - end = TipsOfTheDay.find((ucchar)'\n', index); - if (end == ucstring::npos) + str += RYZOM_VERSION; + TextContext->printfAt(1.0f,1.0f, str.c_str()); + + // Display the tips of the day. + TextContext->setFontSize((uint)(16.f * fontFactor)); + TextContext->setHotSpot(UTextContext::MiddleTop); + ucstring::size_type index = 0; + ucstring::size_type end = TipsOfTheDay.find((ucchar)'\n'); + if (end == string::npos) end = TipsOfTheDay.size(); - } + float fY = ClientCfg.TipsY; + if (!TipsOfTheDay.empty()) + { + while (index < end) + { + // Get the line + ucstring line = TipsOfTheDay.substr (index, end-index); - // More help - TextContext->setFontSize((uint)(12.f * fontFactor)); - /* todo tips of the day uncomment - ucstring ucstr = CI18N::get ("uiTipsEnd"); - TextContext->printAt(0.5f, fY, ucstr); */ - fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); - fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); - } + // Draw the line + TextContext->printAt(0.5f, fY, line); + fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); + index=end+1; + end = TipsOfTheDay.find((ucchar)'\n', index); + if (end == ucstring::npos) + end = TipsOfTheDay.size(); + } + // More help + TextContext->setFontSize((uint)(12.f * fontFactor)); + /* todo tips of the day uncomment + ucstring ucstr = CI18N::get ("uiTipsEnd"); + TextContext->printAt(0.5f, fY, ucstr); */ + fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); + fY = nextLine (TextContext->getFontSize(), Driver->getWindowHeight(), fY); + } - if (!_TPReason.empty()) - { - TextContext->setHotSpot(UTextContext::MiddleMiddle); - TextContext->setFontSize((uint)(14.f * fontFactor)); - TextContext->printAt(0.5f, 0.5f, _TPReason); - TextContext->setHotSpot(UTextContext::BottomLeft); - TextContext->setColor(NLMISC::CRGBA::White); - } + if (!_TPReason.empty()) + { + TextContext->setHotSpot(UTextContext::MiddleMiddle); + TextContext->setFontSize((uint)(14.f * fontFactor)); + TextContext->printAt(0.5f, 0.5f, _TPReason); + TextContext->setHotSpot(UTextContext::BottomLeft); + TextContext->setColor(NLMISC::CRGBA::White); + } - if (!_TPCancelText.empty()) - { - if (ClientCfg.Width != 0 && ClientCfg.Height != 0) - { - TextContext->setFontSize((uint)(15.f * fontFactor)); - TextContext->setHotSpot(UTextContext::BottomLeft); - ucstring uc = CI18N::get("uiR2EDTPEscapeToInteruptLoading") + " (" + _TPCancelText + ") - " + CI18N::get("uiDelayedTPCancel"); - UTextContext::CStringInfo info = TextContext->getStringInfo(uc); - float stringX = 0.5f - info.StringWidth/(ClientCfg.Width*2); - TextContext->printAt(stringX, 7.f / ClientCfg.Height, uc); - } - } + if (!_TPCancelText.empty()) + { + if (ClientCfg.Width != 0 && ClientCfg.Height != 0) + { + TextContext->setFontSize((uint)(15.f * fontFactor)); + TextContext->setHotSpot(UTextContext::BottomLeft); - // Teleport help - //fY = ClientCfg.TeleportInfoY; - if (!ApplyTextCommands && LoadingContinent && !LoadingContinent->Indoor) - { - TextContext->setFontSize((uint)(13.f * fontFactor)); - - // Print some more info - uint32 day = RT.getRyzomDay(); - str = toString (CI18N::get ("uiTipsTeleport").toUtf8().c_str(), - CI18N::get (LoadingContinent->LocalizedName).toUtf8().c_str(), - day, - (uint)RT.getRyzomTime(), - CI18N::get ("uiSeason"+toStringEnum(CRyzomTime::getSeasonByDay(day))).toUtf8().c_str(), - CI18N::get (WeatherManager.getCurrWeatherState().LocalizedName).toUtf8().c_str()); - ucstring ucstr; - ucstr.fromUtf8 (str); - TextContext->setHotSpot(UTextContext::MiddleBottom); - TextContext->setColor(CRGBA(186, 179, 163, 255)); - TextContext->printAt(0.5f, 25/768.f, ucstr); - } + ucstring uc = CI18N::get("uiR2EDTPEscapeToInteruptLoading") + " (" + _TPCancelText + ") - " + CI18N::get("uiDelayedTPCancel"); + UTextContext::CStringInfo info = TextContext->getStringInfo(uc); + float stringX = 0.5f - info.StringWidth/(ClientCfg.Width*2); + TextContext->printAt(stringX, 7.f / ClientCfg.Height, uc); + } + } - // apply text commands - if( ApplyTextCommands ) - { - std::vector printfCommands = ClientCfg.PrintfCommands; - if(FreeTrial) printfCommands = ClientCfg.PrintfCommandsFreeTrial; - if( !printfCommands.empty() ) - { - TextContext->setHotSpot(UTextContext::MiddleBottom); + // Teleport help + //fY = ClientCfg.TeleportInfoY; + if (!ApplyTextCommands && LoadingContinent && !LoadingContinent->Indoor) + { + TextContext->setFontSize((uint)(13.f * fontFactor)); + + // Print some more info + uint32 day = RT.getRyzomDay(); + str = toString (CI18N::get ("uiTipsTeleport").toUtf8().c_str(), + CI18N::get (LoadingContinent->LocalizedName).toUtf8().c_str(), + day, + (uint)RT.getRyzomTime(), + CI18N::get ("uiSeason"+toStringEnum(CRyzomTime::getSeasonByDay(day))).toUtf8().c_str(), + CI18N::get (WeatherManager.getCurrWeatherState().LocalizedName).toUtf8().c_str()); + ucstring ucstr; + ucstr.fromUtf8 (str); + TextContext->setHotSpot(UTextContext::MiddleBottom); + TextContext->setColor(CRGBA(186, 179, 163, 255)); + TextContext->printAt(0.5f, 25/768.f, ucstr); + } - vector::iterator itpc; - for( itpc = printfCommands.begin(); itpc != printfCommands.end(); ++itpc ) + // apply text commands + if( ApplyTextCommands ) { - float x = 0.5f;//((*itpc).X / 1024.f); - float y = ((*itpc).Y / 768.f); - TextContext->setColor( (*itpc).Color ); - TextContext->setFontSize( (uint)(16.f * fontFactor)); - - // build the ucstr(s) - ucstring ucstr = CI18N::get((*itpc).Text); - vector vucstr; - ucstring sep("\n"); - splitUCString(ucstr,sep,vucstr); - - // Letter size - UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); - uint fontHeight = (uint) si.StringHeight + 2; // we add 2 pixels for the gap - - uint i; - float newy = y; - for( i=0; i printfCommands = ClientCfg.PrintfCommands; + if(FreeTrial) printfCommands = ClientCfg.PrintfCommandsFreeTrial; + + if( !printfCommands.empty() ) { - TextContext->printAt(x,newy, vucstr[i]); - newy = nextLine(fontHeight, Driver->getWindowHeight(), newy); + TextContext->setHotSpot(UTextContext::MiddleBottom); + + vector::iterator itpc; + for( itpc = printfCommands.begin(); itpc != printfCommands.end(); ++itpc ) + { + float x = 0.5f;//((*itpc).X / 1024.f); + float y = ((*itpc).Y / 768.f); + TextContext->setColor( (*itpc).Color ); + TextContext->setFontSize( (uint)(16.f * fontFactor)); + + // build the ucstr(s) + ucstring ucstr = CI18N::get((*itpc).Text); + vector vucstr; + ucstring sep("\n"); + splitUCString(ucstr,sep,vucstr); + + // Letter size + UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); + uint fontHeight = (uint) si.StringHeight + 2; // we add 2 pixels for the gap + + uint i; + float newy = y; + for( i=0; iprintAt(x,newy, vucstr[i]); + newy = nextLine(fontHeight, Driver->getWindowHeight(), newy); + } + } } } } } + + if (stereoHMD) + { + StereoDisplay->endRenderTarget(); + } + } /* stereo loop */ + + if (stereoHMD) + { + MainCam.setPos(oldPos); + MainCam.setRotQuat(oldQuat); } // Clamp From 93376226c4802777869bd9dae5fd128851afc09c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 7 Aug 2014 19:45:26 +0200 Subject: [PATCH 080/240] Use software cursor with attached display --HG-- branch : multipass-stereo --- code/ryzom/client/src/connection.cpp | 8 +++++--- code/ryzom/client/src/init_main_loop.cpp | 3 ++- code/ryzom/client/src/input.cpp | 3 ++- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/client/src/main_loop_utilities.cpp | 4 +++- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index d9051d820..8b07cc7f2 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -223,7 +223,7 @@ void connectionRestaureVideoMode () } // And setup hardware mouse if we have to - InitMouseWithCursor (ClientCfg.HardwareCursor); + InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); SetMouseFreeLook (); SetMouseCursor (); SetMouseSpeed (ClientCfg.CursorSpeed); @@ -278,6 +278,8 @@ void setOutGameFullScreen() { setVideoMode(wantedMode); } + + InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); /* InitMouseWithCursor (true); Driver->showCursor(false); @@ -396,7 +398,7 @@ bool connection (const string &cookie, const string &fsaddr) // not initialized at login and remain hardware until here ... // Re-initialise the mouse (will be now in hardware mode, if required) - //InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup + //InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup // no ui init if character selection is automatic //SetMouseFreeLook (); @@ -556,7 +558,7 @@ bool reconnection() { // Re-initialise the mouse (will be now in hardware mode, if required) SetMousePosFirstTime = true; - InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup + InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup // no ui init if character selection is automatic SetMouseFreeLook (); diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index ff72726ba..15b8b997b 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -1261,7 +1261,7 @@ void initMainLoop() // Re-initialise the mouse (will be now in hardware mode, if required) SetMousePosFirstTime = true; - InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup + InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup // Re-initialise the keyboard, now in low-level mode, if required // NB nico : done at end of loading @@ -1504,6 +1504,7 @@ void initWelcomeWindow() // *************************************************************************** +// NOTE: This feature is not really used anymore, it is a patch transition void initHardwareCursor(bool secondCall) { CInterfaceManager * pIM = CInterfaceManager::getInstance(); diff --git a/code/ryzom/client/src/input.cpp b/code/ryzom/client/src/input.cpp index 888d202bd..6d0834f07 100644 --- a/code/ryzom/client/src/input.cpp +++ b/code/ryzom/client/src/input.cpp @@ -21,6 +21,7 @@ ///////////// #include "stdpch.h" // Client +#include "global.h" #include "actions.h" #include "input.h" #include "interface_v3/interface_manager.h" @@ -310,6 +311,6 @@ CNiceInputAuto::~CNiceInputAuto() nlassert(_Count >= 0); if (_Count == 0) { - InitMouseWithCursor(ClientCfg.HardwareCursor); + InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); } } diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 628cc7624..17571fe88 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -867,7 +867,7 @@ bool login() SetMouseSpeed (ClientCfg.CursorSpeed); SetMouseAcceleration (ClientCfg.CursorAcceleration); SetMousePosFirstTime = true; - InitMouseWithCursor (ClientCfg.HardwareCursor); + InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // if (ClientCfg.TestBrowser) // { diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index ecf3c7fae..cdd3f8394 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -73,6 +73,8 @@ void updateFromClientCfg() if (!StereoDisplayAttached) setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, ClientCfg.Windowed, ClientCfg.Frequency)); + // force software cursor when attached + InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); } // GRAPHICS - GENERAL @@ -292,7 +294,7 @@ void updateFromClientCfg() { if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) { - InitMouseWithCursor (ClientCfg.HardwareCursor); + InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); } } From 993f2ffab7d4a749d1877bac2b1feacac255b3c5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 12 Aug 2014 21:11:55 +0200 Subject: [PATCH 081/240] Snowballs update --HG-- branch : multipass-stereo --- code/snowballs2/client/src/camera.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 9d9a5f777..0b7971192 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -128,6 +128,7 @@ void initCamera() StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter } StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation + StereoDisplay->attachToDisplay(); } } } From cc7e93c96e71d1675bd503c6bd504fc6374a14f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 12 Sep 2014 19:19:51 +0200 Subject: [PATCH 083/240] Added GUI for expression editor. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/CMakeLists.txt | 2 + .../plugins/gui_editor/expression_editor.cpp | 88 +++++++++++++++++++ .../plugins/gui_editor/expression_editor.h | 51 +++++++++++ .../plugins/gui_editor/expression_editor.ui | 34 +++++++ .../plugins/gui_editor/gui_editor_window.cpp | 14 +++ .../plugins/gui_editor/gui_editor_window.h | 3 + 6 files changed, 192 insertions(+) create mode 100644 code/studio/src/plugins/gui_editor/expression_editor.cpp create mode 100644 code/studio/src/plugins/gui_editor/expression_editor.h create mode 100644 code/studio/src/plugins/gui_editor/expression_editor.ui diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 4b50ec8d1..77ca5a335 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -34,6 +34,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR texture_chooser.h action_property_manager.h texture_property_manager.h + expression_editor.h ) SET(OVQT_PLUGIN_GUI_EDITOR_UIS @@ -51,6 +52,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS add_widget_widget.ui action_list.ui texture_chooser.ui + expression_editor.ui ) SET(QT_USE_QTGUI TRUE) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp new file mode 100644 index 000000000..81ea74941 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -0,0 +1,88 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expression_editor.h" +#include +#include +#include +#include + +ExpressionEditor::ExpressionEditor( QWidget *parent ) : +QWidget( parent ) +{ + m_ui.setupUi( this ); + + m_selection = NULL; + + m_scene = new QGraphicsScene( this ); + m_ui.view->setScene( m_scene ); + + m_scene->addSimpleText( "Hello" ); + + connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); +} + +ExpressionEditor::~ExpressionEditor() +{ + m_scene = NULL; +} + +void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) +{ + QMenu menu; + + QAction *a = NULL; + a = menu.addAction( "Add rect" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onAddRect() ) ); + + if( m_selection != NULL ) + { + a = menu.addAction( "Remove" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) ); + } + + menu.exec( e->globalPos() ); +} + +void ExpressionEditor::onAddRect() +{ + QGraphicsRectItem *item = new QGraphicsRectItem( 0, 0, 100, 100 ); + item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + m_scene->addItem( item ); +} + +void ExpressionEditor::onDeleteSelection() +{ + m_scene->removeItem( m_selection ); +} + +void ExpressionEditor::onSelectionChanged() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + if( l.isEmpty() ) + { + m_selection = NULL; + return; + } + + m_selection = l[ 0 ]; +} + + + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h new file mode 100644 index 000000000..31fb64d73 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -0,0 +1,51 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPRESSION_EDITOR +#define EXPRESSION_EDITOR + +#include "ui_expression_editor.h" + +class QGraphicsScene; +class QGraphicsItem; + +class ExpressionEditor : public QWidget +{ + Q_OBJECT +public: + ExpressionEditor( QWidget *parent = NULL ); + ~ExpressionEditor(); + +protected: + void contextMenuEvent( QContextMenuEvent *e ); + +private Q_SLOTS: + void onAddRect(); + void onDeleteSelection(); + void onSelectionChanged(); + +private: + Ui::ExpressionEditor m_ui; + QGraphicsScene *m_scene; + + QGraphicsItem *m_selection; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui new file mode 100644 index 000000000..80480ad39 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.ui @@ -0,0 +1,34 @@ + + + ExpressionEditor + + + Qt::ApplicationModal + + + + 0 + 0 + 724 + 522 + + + + Expression Editor + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOn + + + + + + + + diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 3f4e318db..f6adacc8a 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -46,6 +46,8 @@ #include "add_widget_widget.h" #include "texture_chooser.h" +#include "expression_editor.h" + namespace GUIEditor { QString _lastDir; @@ -72,6 +74,7 @@ namespace GUIEditor widgetInfoTree = new CWidgetInfoTree; tc = new TextureChooser(); + ee = new ExpressionEditor(); createMenus(); readSettings(); @@ -120,6 +123,8 @@ namespace GUIEditor delete tc; tc = NULL; + delete ee; + ee = NULL; delete messageProcessor; messageProcessor = NULL; @@ -365,6 +370,11 @@ namespace GUIEditor tc->exec(); } + void GUIEditorWindow::onEEClicked() + { + ee->show(); + } + void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); @@ -415,6 +425,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTCClicked() ) ); m->addAction( a ); + a = new QAction( "Expression Editor", this ); + connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onEEClicked() ) ); + m->addAction( a ); + menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index d18a24813..d0dbe628e 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -29,6 +29,7 @@ class QtTreePropertyBrowser; class QMenu; class TextureChooser; +class ExpressionEditor; namespace GUIEditor { @@ -68,6 +69,7 @@ private Q_SLOTS: void onAddWidgetClicked(); void onTreeChanged(); void onTCClicked(); + void onEEClicked(); protected: @@ -103,6 +105,7 @@ private: QMenu *menu; TextureChooser *tc; + ExpressionEditor *ee; }; } From e2ea5a74b8ebaf539e9c29a90714fc52dc51dcfa Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 12 Sep 2014 19:47:28 +0200 Subject: [PATCH 084/240] We can select multiple items --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 18 +++++++++--------- .../src/plugins/gui_editor/expression_editor.h | 3 +-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 81ea74941..e4d749dcd 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -28,7 +28,7 @@ QWidget( parent ) { m_ui.setupUi( this ); - m_selection = NULL; + m_hasSelection = false; m_scene = new QGraphicsScene( this ); m_ui.view->setScene( m_scene ); @@ -51,7 +51,7 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Add rect" ); connect( a, SIGNAL( triggered() ), this, SLOT( onAddRect() ) ); - if( m_selection != NULL ) + if( m_hasSelection ) { a = menu.addAction( "Remove" ); connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) ); @@ -69,19 +69,19 @@ void ExpressionEditor::onAddRect() void ExpressionEditor::onDeleteSelection() { - m_scene->removeItem( m_selection ); + QList< QGraphicsItem* > l = m_scene->selectedItems(); + QListIterator< QGraphicsItem* > itr( l ); + while( itr.hasNext() ) + m_scene->removeItem( itr.next() ); } void ExpressionEditor::onSelectionChanged() { QList< QGraphicsItem* > l = m_scene->selectedItems(); if( l.isEmpty() ) - { - m_selection = NULL; - return; - } - - m_selection = l[ 0 ]; + m_hasSelection = false; + else + m_hasSelection = true; } diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 31fb64d73..b73f8029f 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -23,7 +23,6 @@ #include "ui_expression_editor.h" class QGraphicsScene; -class QGraphicsItem; class ExpressionEditor : public QWidget { @@ -44,7 +43,7 @@ private: Ui::ExpressionEditor m_ui; QGraphicsScene *m_scene; - QGraphicsItem *m_selection; + bool m_hasSelection; }; #endif From 07ee9a4469c2569fe838a35bfc6e5f90b0a464cc Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Sep 2014 20:29:50 +0200 Subject: [PATCH 085/240] Add missing r2_islands_textures tool --HG-- branch : develop --- .../src/game_share}/bmp4image.h | 0 .../server/src/ai_data_service/pacs_scan.cpp | 2 +- code/ryzom/tools/CMakeLists.txt | 4 +- code/ryzom/tools/client/CMakeLists.txt | 13 +- .../client/r2_islands_textures/CMakeLists.txt | 17 + .../tools/client/r2_islands_textures/main.cpp | 29 + .../screenshot_islands.cpp | 2326 +++++++++++++++++ .../r2_islands_textures/screenshot_islands.h | 241 ++ 8 files changed, 2624 insertions(+), 8 deletions(-) rename code/ryzom/{server/src/server_share => common/src/game_share}/bmp4image.h (100%) create mode 100644 code/ryzom/tools/client/r2_islands_textures/CMakeLists.txt create mode 100644 code/ryzom/tools/client/r2_islands_textures/main.cpp create mode 100644 code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp create mode 100644 code/ryzom/tools/client/r2_islands_textures/screenshot_islands.h diff --git a/code/ryzom/server/src/server_share/bmp4image.h b/code/ryzom/common/src/game_share/bmp4image.h similarity index 100% rename from code/ryzom/server/src/server_share/bmp4image.h rename to code/ryzom/common/src/game_share/bmp4image.h diff --git a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp index 5fc1ed6b5..28e55559c 100644 --- a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp +++ b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp @@ -48,7 +48,7 @@ // Server share -#include "server_share/bmp4image.h" +#include "game_share/bmp4image.h" #include "server_share/continent_container.h" diff --git a/code/ryzom/tools/CMakeLists.txt b/code/ryzom/tools/CMakeLists.txt index 0bf9fb632..041ba210e 100644 --- a/code/ryzom/tools/CMakeLists.txt +++ b/code/ryzom/tools/CMakeLists.txt @@ -23,9 +23,7 @@ IF(WITH_LIGO AND WITH_NET) ADD_SUBDIRECTORY(sheets_packer) ENDIF(WITH_LIGO AND WITH_NET) -IF(WITH_RYZOM_CLIENT) - ADD_SUBDIRECTORY(client) -ENDIF(WITH_RYZOM_CLIENT) +ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(server) diff --git a/code/ryzom/tools/client/CMakeLists.txt b/code/ryzom/tools/client/CMakeLists.txt index ff7516ccc..aabc3142c 100644 --- a/code/ryzom/tools/client/CMakeLists.txt +++ b/code/ryzom/tools/client/CMakeLists.txt @@ -1,5 +1,10 @@ -ADD_SUBDIRECTORY( client_patcher ) -IF( WITH_QT ) -ADD_SUBDIRECTORY( client_config_qt ) -ENDIF( WITH_QT ) +IF(WITH_RYZOM_CLIENT) + ADD_SUBDIRECTORY( client_patcher ) + + IF( WITH_QT ) + ADD_SUBDIRECTORY( client_config_qt ) + ENDIF( WITH_QT ) +ENDIF(WITH_RYZOM_CLIENT) + +ADD_SUBDIRECTORY( r2_islands_textures ) diff --git a/code/ryzom/tools/client/r2_islands_textures/CMakeLists.txt b/code/ryzom/tools/client/r2_islands_textures/CMakeLists.txt new file mode 100644 index 000000000..0fc6c65a2 --- /dev/null +++ b/code/ryzom/tools/client/r2_islands_textures/CMakeLists.txt @@ -0,0 +1,17 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(r2_islands_textures ${SRC}) + +INCLUDE_DIRECTORIES(${RZ_SERVER_SRC_DIR} ${LIBXML2_INCLUDE_DIR}) +TARGET_LINK_LIBRARIES(r2_islands_textures + ryzom_gameshare + ryzom_aishare + ${LIBXML2_LIBRARIES} + nelmisc + nel3d) +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) + +NL_DEFAULT_PROPS(r2_islands_textures "Ryzom, Tools, Server: R2 Islands Textures") +NL_ADD_RUNTIME_FLAGS(r2_islands_textures) + +INSTALL(TARGETS r2_islands_textures RUNTIME DESTINATION ${RYZOM_BIN_PREFIX} COMPONENT tools) diff --git a/code/ryzom/tools/client/r2_islands_textures/main.cpp b/code/ryzom/tools/client/r2_islands_textures/main.cpp new file mode 100644 index 000000000..cbde8b9d4 --- /dev/null +++ b/code/ryzom/tools/client/r2_islands_textures/main.cpp @@ -0,0 +1,29 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "screenshot_islands.h" + +using namespace NLMISC; +using namespace R2; + +int main(int argc, char **argv) +{ + CScreenshotIslands screenshotIslands = CScreenshotIslands::getInstance(); + screenshotIslands.buildScreenshots(); + + return 0; +} diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp new file mode 100644 index 000000000..e6d490a0a --- /dev/null +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -0,0 +1,2326 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "screenshot_islands.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// AI share +#include + +#include + +#include + +using namespace NLMISC; +using namespace NL3D; +using namespace std; +using namespace EGSPD; +using namespace NLGEORGES; +using namespace RYAI_MAP_CRUNCH; + + +// The 3d driver +UDriver *driver = NULL; +CLandscapeIGManager LandscapeIGManager; + +uint ScreenShotWidth; +uint ScreenShotHeight; + +UMaterial sceneMaterial; + +namespace R2 +{ + +const TBufferEntry InteriorValue= (TBufferEntry)(~0u-1); +const TBufferEntry ValueBorder= (TBufferEntry)(~0u-2); +const uint32 BigValue= 15*5; +const float limitValue = 200.0; + +//------------------------------------------------------------------------------------------------- +CScreenshotIslands::CScreenshotIslands() +{ + _BackColor = CRGBA(255, 255, 255, 255); +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::init() +{ + // Create a driver + driver = UDriver::createDriver(); + nlassert(driver); + + sceneMaterial = driver->createMaterial(); + sceneMaterial.getObjectPtr()->setLighting(true); + sceneMaterial.getObjectPtr()->setSpecular(CRGBA(255, 255, 255, 255)); + sceneMaterial.getObjectPtr()->setShininess(50); + sceneMaterial.getObjectPtr()->setDiffuse(CRGBA(100, 100, 100, 255)); + sceneMaterial.getObjectPtr()->setEmissive(CRGBA(25, 25, 25, 255)); + + // load and parse the configfile + CConfigFile cf; + cf.load("IslandScreenshots.cfg"); + + CPath::remapExtension("dds", "tga", true); + + // get the value of searchPaths + CConfigFile::CVar * searchPaths = cf.getVarPtr("SearchPaths"); + if(searchPaths) + { + for(int i = 0; i < searchPaths->size(); i++) + { + CPath::addSearchPath(searchPaths->asString(i).c_str(), true, false); + } + } + + // get the scenario entry points file + CConfigFile::CVar * epFile = cf.getVarPtr("CompleteIslandsFile"); + if(epFile) + { + _CompleteIslandsFile = epFile->asString(); + } + + // get the out directory path + CConfigFile::CVar * outDir = cf.getVarPtr("OutDir"); + if(outDir) + { + _OutDirectory = outDir->asString(); + } + + // get the vegetation option + CConfigFile::CVar * veget = cf.getVarPtr("Vegetation"); + if(veget) + { + _Vegetation = veget->asBool(); + } + + // get the vegetation option + CConfigFile::CVar * inverseZTest = cf.getVarPtr("InverseZTest"); + if(inverseZTest) + { + _InverseZTest = inverseZTest->asBool(); + } + + // get list of continents + CConfigFile::CVar * continents = cf.getVarPtr("Continents"); + vector continentsName(continents->size()); + for(int i = 0; i < continents->size(); i++) + { + continentsName[i] = continents->asString(i); + } + + // get continents data (light, coarseMesh,...) + UFormLoader * formLoader; + for(uint i=0; i form = formLoader->loadForm(CPath::lookup(georgeFileName).c_str()); + if(form) + { + CContinentData continentData; + + UFormElm &formRoot = form->getRootNode(); + + const UFormElm *elm; + if(formRoot.getNodeByName(&elm, "LightLandscapeDay") && elm) + { + CDirLightSetup landscapeLightDay; + landscapeLightDay.build(*elm); + continentData.Ambiant = landscapeLightDay.Ambiant; + continentData.Diffuse = landscapeLightDay.Diffuse; + + if(continentsName[i]=="r2_jungle" || continentsName[i]=="r2_forest" || continentsName[i]=="r2_roots") + { + continentData.Ambiant = CRGBA(255, 255, 255, 255); + continentData.Diffuse = CRGBA(255, 255, 255, 255); + } + } + + formRoot.getValueByName(continentData.IGFile, "LandscapeIG"); + string zoneMin, zoneMax; + formRoot.getValueByName(zoneMin, "ZoneMin"); + formRoot.getValueByName(zoneMax, "ZoneMax"); + + getPosFromZoneName(zoneMin, continentData.ZoneMin); + getPosFromZoneName(zoneMax, continentData.ZoneMax); + + string filename; + if(formRoot.getValueByName(filename, "Ecosystem")) + { + UFormLoader *formLoaderEco = UFormLoader::createLoader(); + if(formLoaderEco) + { + // Load the form + CSmartPtr formEco = formLoaderEco->loadForm(filename.c_str()); + + if(formEco) + { + // Root node + UFormElm &formRootEco = formEco->getRootNode(); + + // Small bank. + formRootEco.getValueByName(continentData.SmallBank, "SmallBank"); + + // Far bank. + formRootEco.getValueByName(continentData.FarBank, "FarBank"); + + // Coarse mesh texture. + formRootEco.getValueByName(continentData.CoarseMeshMap, "CoarseMeshMap"); + } + else + { + nlwarning("CScreenshotIslands::init : Can't load form %s.", filename.c_str()); + } + UFormLoader::releaseLoader(formLoaderEco); + } + } + + _ContinentsData[continentsName[i]] = continentData; + } + UFormLoader::releaseLoader(formLoader); + } + + + // load islands + loadIslands(); + + searchIslandsBorders(); + + // get seasons + CConfigFile::CVar * seasonSuffixes = cf.getVarPtr("SeasonSuffixes"); + if(seasonSuffixes) + { + for(uint i = 0; i < (uint)seasonSuffixes->size(); i++) + { + _SeasonSuffixes.push_back(seasonSuffixes->asString(i)); + } + } + + // get the meter size in pixels + CConfigFile::CVar * meterSize = cf.getVarPtr("MeterPixelSize"); + if(meterSize) + { + _MeterPixelSize = meterSize->asInt(); + } +} + +//------------------------------------------------------------------------------------------------- +bool CScreenshotIslands::getPosFromZoneName(const std::string &name, NLMISC::CVector2f &dest) +{ + if(name.empty()) + { + nlwarning ("getPosFromZoneName(): empty name, can't getPosFromZoneName"); + return false; + } + + static std::string zoneName; + static string xStr, yStr; + xStr.clear(); + yStr.clear(); + zoneName = CFile::getFilenameWithoutExtension(name); + uint32 i = 0; + while(zoneName[i] != '_') + { + if(!::isdigit(zoneName[i])) return false; + yStr += zoneName[i]; ++i; + if(i == zoneName.size()) + return false; + } + ++i; + while(i < zoneName.size()) + { + if(!::isalpha(zoneName[i])) return false; + xStr += (char) ::toupper(zoneName[i]); ++i; + } + if(xStr.size() != 2) return false; + dest.x = 160.f * ((xStr[0] - 'A') * 26 + (xStr[1] - 'A')); + dest.y = 160.f * -atoi(yStr.c_str()); + return true; +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::searchIslandsBorders() +{ + vector filenames; + list zonelFiles; + + map< CVector2f, bool> islandsMap; + + TContinentsData::iterator itCont(_ContinentsData.begin()), lastCont(_ContinentsData.end()); + for( ; itCont != lastCont ; ++itCont) + { + // for each continent we recover a map of zonel files whith position of + // left/bottom point of each zone for keys + filenames.clear(); + zonelFiles.clear(); + + string bnpFileName = itCont->first + ".bnp"; + CBigFile::getInstance().list(bnpFileName.c_str(), filenames); + + for(uint i=0; i::iterator itZonel(zonelFiles.begin()), lastZonel(zonelFiles.end()); + for( ; itZonel != lastZonel ; ++itZonel) + { + CVector2f position; + getPosFromZoneName(*itZonel, position); + + islandsMap[position] = true; + } + + // search for island borders + CContinentData & continent = itCont->second; + list< string >::const_iterator itIsland(continent.Islands.begin()), lastIsland(continent.Islands.end()); + for( ; itIsland != lastIsland ; ++itIsland) + { + if(_IslandsData.find(itIsland->c_str()) != _IslandsData.end()) + { + const CProximityZone & islandData = _IslandsData[itIsland->c_str()]; + + sint32 xmin = islandData.getBoundXMin(); + sint32 xmax = islandData.getBoundXMax(); + sint32 ymin = islandData.getBoundYMin(); + sint32 ymax = islandData.getBoundYMax(); + + sint32 width = xmax-xmin; + sint32 height = ymax-ymin; + + sint32 zonelXMin = ((uint)(xmin/160)) * 160; + sint32 zonelYMin = ((uint)(ymin/160) - 1) * 160; + sint32 zonelXMax = ((uint)(xmax/160)) * 160; + sint32 zonelYMax = ((uint)(ymax/160) - 1) * 160; + + list< CVector2f > leftBorders, rightBorders, bottomBorders, topBorders; + + // search for left and right borders on lines + for(sint32 y = zonelYMin; y<=zonelYMax; y+=160 ) + { + sint32 x=zonelXMin; + CVector2f vec((float)x, (float)y); + bool lastZoneFull = (islandsMap.find(vec) != islandsMap.end()); + bool currentZoneFull; + + while(x<=zonelXMax) + { + vec = CVector2f((float)x, (float)y); + currentZoneFull = (islandsMap.find(vec) != islandsMap.end()); + + if(lastZoneFull && !currentZoneFull && vec.x-1 >= xmin) + { + rightBorders.push_back(CVector2f(vec.x-1, vec.y)); + } + else if(!lastZoneFull && currentZoneFull) + { + leftBorders.push_back(vec); + } + x += 160; + lastZoneFull = currentZoneFull; + } + } + + // search for bottom and top borders on columns + for(sint32 x = zonelXMin; x<=zonelXMax; x+=160 ) + { + sint32 y=zonelYMin; + CVector2f vec((float)x, (float)y); + bool lastZoneFull = (islandsMap.find(vec) != islandsMap.end()); + bool currentZoneFull; + + while(y<=zonelYMax) + { + vec = CVector2f((float)x, (float)y); + currentZoneFull = (islandsMap.find(vec) != islandsMap.end()); + + if(lastZoneFull && !currentZoneFull && vec.y-1 >= ymin) + { + topBorders.push_back(CVector2f(vec.x, vec.y-1)); + } + else if(!lastZoneFull && currentZoneFull) + { + bottomBorders.push_back(vec); + } + y += 160; + lastZoneFull = currentZoneFull; + } + } + + _BorderIslands[*itIsland + "/right"] = rightBorders; + _BorderIslands[*itIsland + "/left"] = leftBorders; + _BorderIslands[*itIsland + "/bottom"] = bottomBorders; + _BorderIslands[*itIsland + "/top"] = topBorders; + } + } + } +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::attenuateIslandBorders(const std::string & islandName, CBitmap & islandBitmap, + const CProximityZone & islandData) +{ + list< CVector2f > leftBorders, rightBorders, bottomBorders, topBorders; + rightBorders = _BorderIslands[islandName + "/right"]; + leftBorders = _BorderIslands[islandName + "/left"]; + bottomBorders = _BorderIslands[islandName + "/bottom"]; + topBorders = _BorderIslands[islandName + "/top"]; + + sint32 xmin = islandData.getBoundXMin(); + sint32 xmax = islandData.getBoundXMax(); + sint32 ymin = islandData.getBoundYMin(); + sint32 ymax = islandData.getBoundYMax(); + + sint32 width = xmax-xmin; + sint32 height = ymax-ymin; + uint8 *dest = &(islandBitmap.getPixels(0)[0]); + + list< CVector2f >::iterator itBorder; + + for(itBorder=leftBorders.begin(); itBorder!=leftBorders.end(); itBorder++) + { + const CVector2f initPoint = *itBorder; + sint32 x = (sint32)initPoint.x - xmin; + sint32 y = (sint32)initPoint.y - ymin; + sint32 maxBorder = 160; + if(y<0) + { + maxBorder += y; + y = 0; + } + sint32 inity = y; + + while(y<(inity+maxBorder) && y<(sint32)height) + { + double noiseValue = (1+cos(((y-inity)*2*Pi)/maxBorder))*5; + double evalNoise = 10 + noiseValue; + double diffAlpha = 255/evalNoise; + + CRGBA color = islandBitmap.getPixelColor(x, height-y-1); + sint32 currentX = x-1; + + while((currentX>=x-evalNoise) && currentX>=0) + { + uint8 *pixel = &(islandBitmap.getPixels(0)[((height-y-1)*width + currentX)*4]); + uint alpha = (uint)(255-diffAlpha*(x-currentX)); + uint invAlpha = 255-alpha; + + *pixel = (uint8) (((invAlpha * *pixel) + (alpha * color.R)) >> 8); + *(pixel + 1) = (uint8) (((invAlpha * *(pixel + 1)) + (alpha * color.G)) >> 8); + *(pixel + 2) = (uint8) (((invAlpha * *(pixel + 2)) + (alpha * color.B)) >> 8); + *(pixel + 3) = (uint8) 255; + + currentX--; + } + y++; + } + } + + for(itBorder=rightBorders.begin(); itBorder!=rightBorders.end(); itBorder++) + { + const CVector2f initPoint = *itBorder; + sint32 x = (sint32)initPoint.x - xmin; + sint32 y = (sint32)initPoint.y - ymin; + sint32 maxBorder = 160; + if(y<0) + { + maxBorder += y; + y = 0; + } + sint32 inity = y; + + while(y<(inity+maxBorder) && y<(sint32)height) + { + double noiseValue = (1+cos(((y-inity)*2*Pi)/maxBorder))*5; + double evalNoise = 10 + noiseValue; + double diffAlpha = 255/evalNoise; + + CRGBA color = islandBitmap.getPixelColor(x, height-y-1); + sint32 currentX = x+1; + + while((currentX<=x+evalNoise) && currentX> 8); + *(pixel + 1) = (uint8) (((invAlpha * *(pixel + 1)) + (alpha * color.G)) >> 8); + *(pixel + 2) = (uint8) (((invAlpha * *(pixel + 2)) + (alpha * color.B)) >> 8); + *(pixel + 3) = (uint8) 255; + + currentX++; + } + + y++; + } + } + + for(itBorder=bottomBorders.begin(); itBorder!=bottomBorders.end(); itBorder++) + { + const CVector2f initPoint = *itBorder; + sint32 x = (sint32)initPoint.x - xmin; + sint32 y = (sint32)initPoint.y - ymin; + sint32 maxBorder = 160; + if(x<0) + { + maxBorder += x; + x = 0; + } + sint32 initx = x; + + while(x<(initx+maxBorder) && x<(sint32)width) + { + double noiseValue = (1+cos(((x-initx)*2*Pi)/maxBorder))*5; + double evalNoise = 10 + noiseValue; + double diffAlpha = 255/evalNoise; + + CRGBA color = islandBitmap.getPixelColor(x, height-y-1); + sint32 currentY = y-1; + + while((currentY>=y-evalNoise) && currentY>=0) + { + uint8 *pixel = &(islandBitmap.getPixels(0)[((height-currentY-1)*width + x)*4]); + uint alpha = (uint)(255-diffAlpha*(y-currentY)); + uint invAlpha = 255-alpha; + + *pixel = (uint8) (((invAlpha * *pixel) + (alpha * color.R)) >> 8); + *(pixel + 1) = (uint8) (((invAlpha * *(pixel + 1)) + (alpha * color.G)) >> 8); + *(pixel + 2) = (uint8) (((invAlpha * *(pixel + 2)) + (alpha * color.B)) >> 8); + *(pixel + 3) = (uint8) 255; + + currentY--; + } + + x++; + } + } + + for(itBorder=topBorders.begin(); itBorder!=topBorders.end(); itBorder++) + { + const CVector2f initPoint = *itBorder; + sint32 x = (sint32)initPoint.x - xmin; + sint32 y = (sint32)initPoint.y - ymin; + sint32 maxBorder = 160; + if(x<0) + { + maxBorder += x; + x = 0; + } + sint32 initx = x; + + while(x<(initx+maxBorder) && x<(sint32)width) + { + double noiseValue = (1+cos(((x-initx)*2*Pi)/maxBorder))*5; + double evalNoise = 10 + noiseValue; + double diffAlpha = 255/evalNoise; + + CRGBA color = islandBitmap.getPixelColor(x, height-y-1); + sint32 currentY = y+1; + + while((currentY<=y+evalNoise) && currentY> 8); + *(pixel + 1) = (uint8) (((invAlpha * *(pixel + 1)) + (alpha * color.G)) >> 8); + *(pixel + 2) = (uint8) (((invAlpha * *(pixel + 2)) + (alpha * color.B)) >> 8); + *(pixel + 3) = (uint8) 255; + + currentY++; + } + + x++; + } + } +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::buildScreenshots() +{ + init(); + buildIslandsTextures(); +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::writeProximityBufferToTgaFile(const std::string& fileName,const TBuffer& buffer,uint32 scanWidth,uint32 scanHeight) +{ + uint imageWidth = (scanWidth+15)&~15; + uint imageHeight = (scanHeight); + + CTGAImageGrey tgaImage; + tgaImage.setup((uint16)imageWidth, (uint16)imageHeight, fileName, 0, 0); + for (uint32 y=0;y255*5)?255:value/5); + } + tgaImage.writeLine(); + } +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::processProximityBuffer(TBuffer & inputBuffer, uint32 lineLength, TBuffer& resultBuffer) +{ + // a couple of constants to control the range over which our degressive filter is to be applied + const uint32 smallValue= 2*5; + + float a = 5*((255.0 - limitValue)/(float(100-BigValue))); + float b = (float)(limitValue*5 - a*BigValue); + + // determine numer of lines in the buffer... + uint32 numLines= inputBuffer.size()/ lineLength; + + // clear out the result buffer and reset all values to 5*255, remembering that this is the correct value for the image edges + resultBuffer.clear(); + resultBuffer.resize(inputBuffer.size(),(TBufferEntry)5*255); + + for (uint32 y=1;yBigValue) value=5*255; + else value= (uint32)(((1.0-cos(Pi*(float(value-smallValue)/(float)(BigValue-smallValue))))/2.0)*float(5*255)); + */ + + if (value==ValueBorder); + else if ((value>=0) && (valueBigValue) + { + if(value==InteriorValue) + { + value = (uint)(5*limitValue); + } + else + { + value = (uint)(a*value+b); + if(value > 5*255) value = 5*255; + } + } + else if((value>=smallValue) && (value<=BigValue)) + { + value= (uint32)(((1.0-cos(Pi*(float(value-smallValue)/(float)(BigValue-smallValue))))/2.0)*float(5*limitValue)); + } + + // store the value into the result buffer + resultBuffer[offset]= (TBufferEntry)value; + } + } + + // modify inputBuffer to store "bigValue" limit + for (uint32 y=1;y0) + { + uint16 nextValue = resultBuffer[offset-1]; + uint16 prevValue = (TBufferEntry)(5*limitValue); + if(nextValue!=(TBufferEntry)(5*limitValue)) + { + uint32 count = x-1; + while((count>x-7) && (count>0) && ((nextValue=resultBuffer[lineOffset+count])!=0) + && nextValue!=(TBufferEntry)(5*limitValue) && (nextValue!=ValueBorder)) + { + uint16 newValue = (TBufferEntry)(prevValue+5*7); + if(newValue < nextValue) + { + resultBuffer[lineOffset+count] = newValue; + } + + prevValue = newValue; + count--; + } + } + } + } + } + } + + //columns + for (uint32 x=0;x=startOffset) + { + uint16 nextValue = resultBuffer[offset-lineLength]; + uint16 prevValue = (TBufferEntry)(5*limitValue); + if(nextValue!=(TBufferEntry)(5*limitValue)) + { + uint32 count = offset-lineLength; + while((count>offset-7*lineLength) && (count>=startOffset) && + ((nextValue=resultBuffer[count])!=0) && nextValue!=(TBufferEntry)(5*limitValue) && (nextValue!=ValueBorder)) + { + uint16 newValue = (TBufferEntry)(prevValue+5*7); + if(newValue < nextValue) + { + resultBuffer[count] = newValue; + } + + prevValue = newValue; + count -= lineLength; + } + } + } + } + } + } + */ + + //----------------------------------------------------------------------------- + // search for pixels of borders + map< CVector2f, bool > bordersPixels; + for (uint32 y=0;y leftBorders, rightBorders, bottomBorders, topBorders; + for (uint32 y=0;y0) + { + for(uint32 xc=(uint32)firstPixelBorder.x; xc<(uint32)(firstPixelBorder.x+nbPixelsBorder); xc++) + { + if(resultBuffer[(y-1)*lineLength+xc]==(TBufferEntry)(5*255)) + { + bottom = true; + break; + } + } + } + + if(y+10) + { + for(uint32 yc=(uint32)firstPixelBorder.y; yc<(uint32)(firstPixelBorder.y+nbPixelsBorder); yc++) + { + if(resultBuffer[yc*lineLength+x-1]==(TBufferEntry)(5*255)) + { + left = true; + break; + } + } + } + + if(x+1=(uint32)(y-evalNoise)) && yc>=0) + { + uint16 newValue = (TBufferEntry)(5*(limitValue + diffAlpha*(y-yc))); + uint16 currentValue = (TBufferEntry)resultBuffer[yc*lineLength+xc]; + if(newValue=(uint32)(x-evalNoise)) && xc>=0) + { + uint16 newValue = (TBufferEntry)(5*(limitValue + diffAlpha*(x-xc))); + uint16 currentValue = (TBufferEntry)resultBuffer[yc*lineLength+xc]; + if(newValue islands; + CScenarioEntryPoints scenarioEntryPoints = CScenarioEntryPoints::getInstance(); + + scenarioEntryPoints.loadFromFile(); + const CScenarioEntryPoints::TEntryPoints& entryPoints = scenarioEntryPoints.getEntryPoints(); + + CScenarioEntryPoints::TEntryPoints::const_iterator entry(entryPoints.begin()), entryPoint(entryPoints.end()); + for( ; entry != entryPoint ; ++entry) + { + islands[entry->Island] = CVector2f((float)entry->X, (float)entry->Y); + } + + // search islands of each continent + map< string, CVector2f >::iterator itIsland(islands.begin()), lastIsland(islands.end()); + for( ; itIsland != lastIsland ; ++itIsland) + { + const CVector2f & entryPoint = itIsland->second; + + // search continent of this island + TContinentsData::iterator itCont(_ContinentsData.begin()), lastCont(_ContinentsData.end()); + for( ; itCont != lastCont ; ++itCont) + { + CContinentData & continent = itCont->second; + CVector2f zoneMax = continent.ZoneMax; + CVector2f zoneMin = continent.ZoneMin; + + if((zoneMin.x <= entryPoint.x) && (entryPoint.x <= zoneMax.x) + && (zoneMax.y <= entryPoint.y) && (entryPoint.y <= zoneMin.y)) + { + continent.Islands.push_back(itIsland->first); + break; + } + } + } + + // search data of each island + TContinentsData::iterator itCont(_ContinentsData.begin()), lastCont(_ContinentsData.end()); + for( ; itCont != lastCont ; ++itCont) + { + string aiFileName = itCont->first+"_0.cwmap2"; + + const CContinentData & continent = itCont->second; + + CProximityMapBuffer continentBuffer; + continentBuffer.load(CPath::lookup(aiFileName)); + + CProximityMapBuffer::TZones zones; + continentBuffer.calculateZones(zones); + + for (uint32 i=0;i::const_iterator itIsland(continent.Islands.begin()), lastIsland(continent.Islands.end()); + for( ; itIsland != lastIsland ; ++itIsland) + { + const CVector2f & entryPoint = islands[*itIsland]; + sint32 xmin = zones[i].getBoundXMin(); + sint32 xmax = zones[i].getBoundXMax(); + sint32 ymin = zones[i].getBoundYMin(); + sint32 ymax = zones[i].getBoundYMax(); + + if((xmin <= entryPoint.x) && (entryPoint.x <= xmax) + && (ymin <= entryPoint.y) && (entryPoint.y <= ymax)) + { + fileName = _OutDirectory + "/" + *itIsland + "_prox.tga"; + _IslandsData[*itIsland] = zones[i]; + break; + } + } + + // write the processed proximity map to an output file + if(fileName != "") + { + writeProximityBufferToTgaFile(fileName, cleanBuffer, zones[i].getZoneWidth(), zones[i].getZoneHeight()); + _TempFileNames.push_back(fileName); + + fileName = _OutDirectory + "/" + *itIsland + "_limit.tga"; + writeProximityBufferToTgaFile(fileName, zoneBuffer, zones[i].getZoneWidth(), zones[i].getZoneHeight()); + _TempFileNames.push_back(fileName); + } + else + { + nlinfo("Zone of island not found, tga not build"); + } + } + } + + + CScenarioEntryPoints::TCompleteIslands completeIslands(entryPoints.size()); + + uint completeIslandsNb = 0; + for(uint e=0; e::const_iterator itIsland(itCont->second.Islands.begin()), lastIsland(itCont->second.Islands.end()); + for( ; itIsland != lastIsland ; ++itIsland) + { + if(*itIsland == entry.Island) + { + completeIsland.Continent = CSString(itCont->first); + if(_IslandsData.find(entry.Island)!=_IslandsData.end()) + { + completeIsland.XMin = _IslandsData[entry.Island].getBoundXMin(); + completeIsland.YMin = _IslandsData[entry.Island].getBoundYMin(); + completeIsland.XMax = _IslandsData[entry.Island].getBoundXMax(); + completeIsland.YMax = _IslandsData[entry.Island].getBoundYMax(); + completeIslands[completeIslandsNb] = completeIsland; + completeIslandsNb++; + } + break; + } + } + } + } + completeIslands.resize(completeIslandsNb); + + CScenarioEntryPoints::getInstance().saveXMLFile(completeIslands, _CompleteIslandsFile); +} + +//-------------------------------------------------------------------------------- + +void CScreenshotIslands::getBuffer(UScene * scene, ULandscape * landscape, CBitmap &btm) +{ + // + if (ScreenShotWidth && ScreenShotHeight) + { + UCamera camera = scene->getCam(); + + // Destination image + CBitmap dest; + btm.resize(ScreenShotWidth, ScreenShotHeight, CBitmap::RGBA); + + uint windowWidth = driver->getWindowWidth(); + uint windowHeight = driver->getWindowHeight(); + + uint top; + uint bottom = min(windowHeight, ScreenShotHeight); + for (top=0; topclearBuffers(_BackColor); + + // store initial frustum and viewport + CFrustum Frustum = scene->getCam().getFrustum(); + CViewport Viewport = scene->getViewport(); + + // Build a new frustum + CFrustum frustumPart; + frustumPart.Left = Frustum.Left+(Frustum.Right-Frustum.Left)*((float)left/(float)ScreenShotWidth); + frustumPart.Right = Frustum.Left+(Frustum.Right-Frustum.Left)*((float)right/(float)ScreenShotWidth); + frustumPart.Top = ceil(Frustum.Top+(Frustum.Bottom-Frustum.Top)*((float)top/(float)ScreenShotHeight)); + frustumPart.Bottom = ceil(Frustum.Top+(Frustum.Bottom-Frustum.Top)*((float)bottom/(float)ScreenShotHeight)); + frustumPart.Near = Frustum.Near; + frustumPart.Far = Frustum.Far; + frustumPart.Perspective = Frustum.Perspective; + + // Build a new viewport + CViewport viewport; + viewport.init(0, 0, (float)(right-left)/windowWidth, + (float)(bottom-top)/windowHeight); + + // Activate all this + scene->getCam().setFrustum(frustumPart); + scene->setViewport(viewport); + + scene->setMaxSkeletonsInNotCLodForm(1000000); + scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); + + if(_InverseZTest) + { + // render scene with inversed ZBuffer test (keep greater distances) + driver->setColorMask(false, false, false, false); + sceneMaterial.setZFunc(UMaterial::less); + + // initialize ZBuffer with leak value + driver->setMatrixMode2D11(); + CQuad quad; + quad.V0 = CVector(0.0, 0.0, 0.0); + quad.V1 = CVector(1.0, 0.0, 0.0); + quad.V2 = CVector(1.0, 1.0, 0.0); + quad.V3 = CVector(0.0, 1.0, 0.0); + + driver->drawQuad(quad, sceneMaterial); + driver->setMatrixMode3D(camera); + driver->setColorMask(true, true, true, true); + + scene->enableElementRender(UScene::FilterWater, false); + } + + scene->render(); + + // display vegetables with normal ZBuffer test + if(_InverseZTest && _Vegetation) + { + scene->enableElementRender(UScene::FilterWater, false); + scene->enableElementRender(UScene::FilterLandscape, false); + scene->enableElementRender(UScene::FilterWater, true); + scene->render(); + scene->enableElementRender(UScene::FilterLandscape, true); + } + + // Get the bitmap + driver->getBuffer(dest); + btm.blit(dest, 0, windowHeight-(bottom-top), right-left, bottom-top, left, top); + + // restore camera + scene->getCam().setFrustum(Frustum); + scene->setViewport(Viewport); + + driver->flush(); + driver->swapBuffers(); + + // Next + right = std::min(right+windowWidth, ScreenShotWidth); + } + + // Next + bottom = std::min(bottom+windowHeight, ScreenShotHeight); + } + } + else + { + driver->getBuffer(btm); + } +} + + + +void CScreenshotIslands::buildIslandsTextures() +{ + int loop = 0; + int maxLoop = 6; + + // Create the window with config file values + driver->setDisplay(UDriver::CMode(1024, 768, 32, false)); + + // Create a scene + UScene * scene = driver->createScene(true); + scene->animate(CTime::ticksToSecond(CTime::getPerformanceTime())); + + // Create a camera + UCamera camera = scene->getCam(); + camera.setTransformMode(UTransformable::DirectMatrix); + + // Create and load landscape + ULandscape * landscape = scene->createLandscape(); + if(_InverseZTest) + { + landscape->setZFunc(UMaterial::greaterequal); + } + else + { + landscape->setZFunc(UMaterial::less); + } + + //Iteration on seasons + list< string >::iterator itSeason(_SeasonSuffixes.begin()), lastSeason(_SeasonSuffixes.end()); + for( ; itSeason != lastSeason ; ++itSeason) + { + string seasonSuffix = *itSeason; + + int season; + if(seasonSuffix=="_sp") season = CSeason::Spring; + else if(seasonSuffix=="_su") season = CSeason::Summer; + else if(seasonSuffix=="_au") season = CSeason::Autumn; + else if(seasonSuffix=="_wi") season = CSeason::Winter; + + // Iterations on Continents + TContinentsData::iterator itCont(_ContinentsData.begin()), lastCont(_ContinentsData.end()); + for( ; itCont != lastCont ; ++itCont) + { + const CContinentData & continent = itCont->second; + + // Light init + landscape->setupStaticLight(continent.Diffuse, continent.Ambiant, 1.0f); + + string coarseMeshFile = continent.CoarseMeshMap; + string coarseMeshWithoutExt = CFile::getFilenameWithoutExtension(coarseMeshFile); + string coarseMeshExt = CFile::getExtension(coarseMeshFile); + coarseMeshFile = coarseMeshWithoutExt + seasonSuffix + "." + coarseMeshExt; + scene->setCoarseMeshManagerTexture(coarseMeshFile.c_str()); + + // Load the landscape + string farBank = continent.FarBank; + string farBankWithoutExt = CFile::getFilenameWithoutExtension(farBank); + string farBankExt = CFile::getExtension(farBank); + farBank = farBankWithoutExt + seasonSuffix + "." + farBankExt; + landscape->loadBankFiles(continent.SmallBank, farBank); + + // Load vegatables + LandscapeIGManager.initIG(scene, continent.IGFile, driver, season, NULL); + + // Iterations on Islands + list< string >::const_iterator itIsland(continent.Islands.begin()), lastIsland(continent.Islands.end()); + for( ; itIsland != lastIsland ; ++itIsland) + { + loop = 0; + + if(_IslandsData.find(itIsland->c_str()) != _IslandsData.end()) + { + const CProximityZone & islandData = _IslandsData[itIsland->c_str()]; + + sint32 xmin = islandData.getBoundXMin(); + sint32 xmax = islandData.getBoundXMax(); + sint32 ymin = islandData.getBoundYMin(); + sint32 ymax = islandData.getBoundYMax(); + + float width = (float)(xmax-xmin); + float height = (float)(ymax-ymin); + ScreenShotWidth = (uint)(width*_MeterPixelSize); + ScreenShotHeight = (uint)(height*_MeterPixelSize); + + // position in island center + float posx = ((float)(xmax+xmin))/2; + float posy = ((float)(ymax+ymin))/2; + CVector entryPos(posx, posy, 400); + + // Setup camera + CMatrix startCamMatrix; + startCamMatrix.setPos(entryPos); + startCamMatrix.rotateX(-(float)Pi/2); + camera.setMatrix(startCamMatrix); + camera.setFrustum(width, height, -10000.0f, 10000.0f, false); + + // init lanscape + landscape->postfixTileFilename(seasonSuffix.c_str()); + + while(loop zonesAdded; + vector zonesRemoved; + IProgressCallback progress; + landscape->refreshAllZonesAround(camera.getMatrix().getPos(), 1000, zonesAdded, zonesRemoved, progress); + if(_Vegetation) + { + LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); + LandscapeIGManager.loadArrayZoneIG(zonesAdded); + + vector::iterator itName(zonesAdded.begin()), lastName(zonesAdded.end()); + for( ; itName != lastName ; ++itName) + { + UInstanceGroup * instanceGr = LandscapeIGManager.getIG(*itName); + if(instanceGr) + { + uint nbInst = instanceGr->getNumInstance(); + for(uint i=0; igetNumInstance(); i++) + { + instanceGr->setCoarseMeshDist(i, 100000); + instanceGr->setDistMax(i, 100000); + } + } + } + } + + // Clear all buffers + driver->clearBuffers(_BackColor); + + if(_InverseZTest) + { + // render scene with inversed ZBuffer test (keep greater distances) + driver->setColorMask(false, false, false, false); + sceneMaterial.setZFunc(UMaterial::less); + + // initialize ZBuffer with leak value + driver->setMatrixMode2D11(); + CQuad quad; + quad.V0 = CVector(0.0, 0.0, 0.0); + quad.V1 = CVector(1.0, 0.0, 0.0); + quad.V2 = CVector(1.0, 1.0, 0.0); + quad.V3 = CVector(0.0, 1.0, 0.0); + + driver->drawQuad(quad, sceneMaterial); + driver->setMatrixMode3D(camera); + driver->setColorMask(true, true, true, true); + + scene->enableElementRender(UScene::FilterWater, false); + } + + scene->render(); + + // display vegetables with normal ZBuffer test + if(_InverseZTest && _Vegetation) + { + scene->enableElementRender(UScene::FilterLandscape, false); + scene->enableElementRender(UScene::FilterWater, true); + scene->render(); + scene->enableElementRender(UScene::FilterLandscape, true); + } + + // Swap 3d buffers + driver->flush(); + driver->swapBuffers(); + + // Pump user input messages + driver->EventServer.pump(); + + loop += 1; + + // Screenshot + if(loop==maxLoop-1) + { + CBitmap islandBitmap; + getBuffer(scene, landscape, islandBitmap); + + buildBackTextureHLS(*itIsland, islandBitmap); + } + if(loop==maxLoop) + { + // create srcennshot bitmap of full island + CBitmap islandBitmap; + getBuffer(scene, landscape, islandBitmap); + + attenuateIslandBorders(*itIsland, islandBitmap, islandData); + + // load proximity bitmap + CBitmap proxBitmap; + std::string proxFileName = _OutDirectory + "/" + *itIsland + "_prox.tga"; + CIFile proxFS(proxFileName.c_str()); + proxBitmap.load(proxFS); + + // resize proximity bitmap + CBitmap tempBitmap; + int newWidth = islandBitmap.getWidth(); + int newHeight = islandBitmap.getHeight(); + tempBitmap.resize(newWidth, newHeight, islandBitmap.PixelFormat); + // blit src bitmap + tempBitmap.blit(proxBitmap, 0, 0, newWidth, newHeight, 0, 0); + + // swap them + proxBitmap.resize(newWidth, newHeight, proxBitmap.PixelFormat); + proxBitmap.swap(tempBitmap); + + + // create final bitmap + CBitmap bitmapDest; + bitmapDest.resize(islandBitmap.getWidth(), islandBitmap.getHeight(), islandBitmap.PixelFormat); + + + // mix black and full island bitmaps with blend factor of proximity bitmap pixels + uint numPix = islandBitmap.getWidth() * islandBitmap.getHeight(); + + const uint8 *alphaProx = &(proxBitmap.getPixels(0)[0]); + const uint8 *srcIsland = &(islandBitmap.getPixels(0)[0]); + uint8 *dest = &(bitmapDest.getPixels(0)[0]); + + + const uint8 *srcBack = &(_BackBitmap.getPixels(0)[0]); + + uint8 *endDest = dest + (numPix << 2); + + do + { + uint invblendFact = (uint) alphaProx[0]; + uint blendFact = 256 - invblendFact; + + // blend 4 component at each pass + *dest = (uint8) (((blendFact * *srcIsland) + (invblendFact * *srcBack)) >> 8); + *(dest + 1) = (uint8) (((blendFact * *(srcIsland + 1)) + (invblendFact * *(srcBack + 1))) >> 8); + *(dest + 2) = (uint8) (((blendFact * *(srcIsland + 2)) + (invblendFact * *(srcBack + 2))) >> 8); + *(dest + 3) = (uint8) 255; + + alphaProx = alphaProx + 4; + srcIsland = srcIsland + 4; + dest = dest + 4; + + srcBack = srcBack + 4; + } + while(dest != endDest); + + + // create tga file of avoidable place in island + string textureName = _OutDirectory + "/" + *itIsland + seasonSuffix + ".tga"; + + CBitmap bitmapLittle; + bitmapLittle.resize(bitmapDest.getWidth(), bitmapDest.getHeight(), bitmapDest.PixelFormat); + bitmapLittle = bitmapDest; + if(!isPowerOf2(bitmapDest.getWidth()) || !isPowerOf2(bitmapDest.getHeight()) ) + { + uint pow2w = NLMISC::raiseToNextPowerOf2(bitmapDest.getWidth()); + uint pow2h = NLMISC::raiseToNextPowerOf2(bitmapDest.getHeight()); + CBitmap enlargedBitmap; + enlargedBitmap.resize(pow2w, pow2h, bitmapDest.PixelFormat); + // blit src bitmap + enlargedBitmap.blit(&bitmapDest, 0, 0); + // swap them + bitmapDest.swap(enlargedBitmap); + } + + COFile fsDest(textureName.c_str()); + bitmapDest.writeTGA(fsDest,32); + + + // little tga + bitmapLittle.resample(bitmapLittle.getWidth()/10, bitmapLittle.getHeight()/10); + if(!isPowerOf2(bitmapLittle.getWidth()) || !isPowerOf2(bitmapLittle.getHeight()) ) + { + uint pow2w = NLMISC::raiseToNextPowerOf2(bitmapLittle.getWidth()); + uint pow2h = NLMISC::raiseToNextPowerOf2(bitmapLittle.getHeight()); + CBitmap enlargedBitmap; + enlargedBitmap.resize(pow2w, pow2h, bitmapLittle.PixelFormat); + // blit src bitmap + enlargedBitmap.blit(&bitmapLittle, 0, 0); + // swap them + bitmapLittle.swap(enlargedBitmap); + } + + textureName = _OutDirectory + "/" + *itIsland + seasonSuffix + "_little.tga"; + COFile fsLittle(textureName.c_str()); + bitmapLittle.writeTGA(fsLittle,32); + + _BackColor = CRGBA(255, 255, 255, 255); + } + } + } + } + + LandscapeIGManager.reset(); + landscape->removeAllZones(); + } + } + + // remove proximity tga + list::iterator itProx(_TempFileNames.begin()), lastProx(_TempFileNames.end()); + for( ; itProx != lastProx ; ++itProx) + { + CFile::deleteFile(*itProx); + }; +} + +//-------------------------------------------------------------------------------- +inline bool RGB2HSV(const CRGBA & rgba, uint & Hue, uint & Sat, uint & Val) +{ + double Min_, Max_, Delta, H, S, V; + + H = 0.0; + Min_ = min(min(rgba.R, rgba.G), rgba.B); + Max_ = max(max(rgba.R, rgba.G), rgba.B); + Delta = ( Max_ - Min_); + V = Max_; + + if(Max_ != 0.0) + { + S = 255.0*Delta/Max_; + } + else + { + S = 0.0; + H = -1; + return false; + } + + if(rgba.R == Max_) + { + H = (rgba.G - rgba.B) / Delta; + } + else if(rgba.G == Max_) + { + H = 2.0 + (rgba.B - rgba.R) / Delta; + } + else + { + H = 4.0 + (rgba.R - rgba.G) / Delta; + } + + H = H * 60; + if(H < 0.0) + { + H = H + 360.0; + } + + Hue = (uint)H ; // Hue -> 0..360 + Sat = (uint)S * 100 / 255; // Saturation -> 0..100 % + Val = (uint)V * 100 / 255; // Value - > 0..100 % + + return true; +} + +//------------------------------------------------------------------------------------------------- +inline bool infHLS(const CRGBA & rgba1, const CRGBA & rgba2) +{ + uint h1, s1, v1, h2, s2, v2; + RGB2HSV(rgba1, h1, s1, v1); + RGB2HSV(rgba2, h2, s2, v2); + + if(h1 != h2) + { + return (h1 < h2); + } + else if(s1 != s2) + { + return (s1 < s2); + } + else + { + return (v1 < v2); + } +} + +//------------------------------------------------------------------------------------------------- +void CScreenshotIslands::buildBackTextureHLS(const std::string & islandName, const CBitmap & islandBitmap) +{ + // load limit bitmap + CBitmap limBitmap; + std::string limFileName = _OutDirectory + "/" + islandName + "_limit.tga"; + + CIFile limFS(limFileName.c_str()); + limBitmap.load(limFS); + + list< CRGBA > limitPixels; + + // search for colors of limit pixels + for(uint x=0; x sortedHLS; + list< CRGBA >::iterator itCol, itHLS; + bool inserted = false; + for(itCol=limitPixels.begin(); itCol!=limitPixels.end(); itCol++) + { + inserted = false; + for(itHLS=sortedHLS.begin(); itHLS!=sortedHLS.end(); ++itHLS) + { + if(infHLS(*itCol, *itHLS)) + { + sortedHLS.insert(itHLS, *itCol); + inserted = true; + break; + } + } + if(inserted==false) sortedHLS.push_back(*itCol); + } + + + // keep more filled eighth of circle + itHLS = sortedHLS.begin(); + uint h, s, v; + RGB2HSV(*itHLS, h, s, v); + list< CRGBA > currentList, maxList; + + for(uint i=0; i<8; i++) + { + while(itHLS!=sortedHLS.end() && h maxList.size()) + { + maxList.clear(); + maxList = currentList; + currentList.clear(); + } + } + + vector< CRGBA > sortedColors(maxList.size()); + uint colorsNb = 0; + CRGBA lastColor(0, 0, 0, 0); + CRGBA maxColor; + uint maxColorNb = 0; + uint currentColorNb = 0; + for(itHLS=maxList.begin(); itHLS!=maxList.end(); ++itHLS) + { + if(lastColor==*itHLS) + { + currentColorNb++; + } + else + { + currentColorNb = 1; + } + + if(currentColorNb>maxColorNb) + { + maxColorNb = currentColorNb; + maxColor = *itHLS; + } + + lastColor = *itHLS; + + RGB2HSV(*itHLS, h, s, v); + if(v>25 && v<75 && s>25 && s<75) + { + sortedColors[colorsNb] = *itHLS; + colorsNb++; + } + } + + if(colorsNb < 5) + { + colorsNb = 0; + for(itHLS=maxList.begin(); itHLS!=maxList.end(); ++itHLS) + { + sortedColors[colorsNb] = *itHLS; + colorsNb++; + } + } + + sortedColors.resize(colorsNb); + + _BackBitmap.resize(islandBitmap.getWidth(), islandBitmap.getHeight(), islandBitmap.PixelFormat); + + if(sortedColors.size()!=0) + { + _BackColor = maxColor; + + CRandom randomGenerator; + + uint8 * backPixels = &(_BackBitmap.getPixels(0)[0]); + + for(uint x=0; x<_BackBitmap.getWidth(); x++) + { + for(uint y=0; y<_BackBitmap.getHeight(); y++) + { + sint32 randomVal = randomGenerator.rand(colorsNb-1); + const CRGBA & color = sortedColors[randomVal]; + + *backPixels = (uint8) color.R; + *(backPixels + 1) = (uint8) color.G; + *(backPixels + 2) = (uint8) color.B; + *(backPixels + 3) = (uint8) 255; + + backPixels = backPixels+4; + } + } + } + + /* + //TEST + CBitmap HLSBitmap; + HLSBitmap.resize(640, sortedColors.size()*4, islandBitmap.PixelFormat); + + uint8 * hlsPixels = &(HLSBitmap.getPixels(0)[0]); + + for(uint i=0; i < sortedColors.size(); i++) + { + uint count = 0; + while(count<640*4) + { + *hlsPixels = (uint8) sortedColors[i].R; + *(hlsPixels + 1) = (uint8) sortedColors[i].G; + *(hlsPixels + 2) = (uint8) sortedColors[i].B; + *(hlsPixels + 3) = (uint8) sortedColors[i].A; + + hlsPixels = hlsPixels+4; + count++; + } + } + + + string textureName = _OutDirectory + "/" + islandName + "_HLS2.tga"; + COFile fsHLS(textureName.c_str()); + HLSBitmap.writeTGA(fsHLS,32); + */ +} + + +//-------------------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------- +// methods CProximityMapBuffer +//------------------------------------------------------------------------------------------------- + +void CProximityMapBuffer::load(const std::string& name) +{ + // load the AI collision map file + CWorldMap worldMap; + CIFile f(name); + f.serial(worldMap); + + // lookup the map bounds + CMapPosition min, max; + worldMap.getBounds(min, max); + + // calculate a handful of constants relating to the bounds of the image... + _ScanWidth = max.x()-min.x(); + _ScanHeight = max.y()-min.y(); + _XOffset= min.x(); + _YOffset= (sint16)min.y(); + + // redimension buffer to correct size + _Buffer.resize(_ScanWidth*_ScanHeight); + + // setup a position variable to mark the start point of each line + CMapPosition scanpos(min.x(),min.y()); + + // iterate over the scan area looking for points that are accessible + for (uint32 y=0; y<_ScanHeight; ++y, scanpos = scanpos.getStepN()) + { + CMapPosition pos(scanpos); + + // scan a line of the map + for (uint32 x=0; x<_ScanWidth; ++x, pos = pos.getStepE()) + { + bool isAccessible= false; + // if the cell pointer is NULL it means that the 16x16 cell in question is inaccessible + if (worldMap.getRootCellCst(pos) != NULL) + { + // run through the surfaces in the cell looking for a match for this position (may be as many as 3 surfaces per cell max) + for (uint32 ns=0; ns<3; ++ns) + { + isAccessible |= worldMap.getSafeWorldPosition(pos, CSlot(ns)).isValid(); + } + } + // setup the next pixel in the output buffers... + _Buffer[y*_ScanWidth+x]= (isAccessible? 0: (TBufferEntry)~0u); + } + } +} + +//------------------------------------------------------------------------------------------------- +void CProximityMapBuffer::calculateZones(TZones& zones) +{ + // clear out the result buffer before starting work + zones.clear(); + + // setup a container to hold the accessible points within this buffer + typedef std::set TAccessiblePoints; + TAccessiblePoints accessiblePoints; + + // start by building the set of all accessible points + for (uint32 i=0;i<_Buffer.size();++i) + { + if (_Buffer[i]==0) + accessiblePoints.insert(i); + } + + // while there are still points remaining in the set we must have another zone to process + while (!accessiblePoints.empty()) + { + // append a new zone to the zones vector and get a refference to it + zones.push_back( CProximityZone(_ScanWidth,_ScanHeight,_XOffset,_YOffset) ); + CProximityZone& theZone= zones.back(); + + // setup a todo list representing points that are part of the surface that we are dealing with + // that haven't yet been treated to check for neighbours, etc + std::vector todo; + + // get hold of the first point in the accessilbe points set and push it onto the todo list + todo.push_back(*accessiblePoints.begin()); + accessiblePoints.erase(todo.back()); + + // while we have more points to deal with ... + while (!todo.empty()) + { + // pop the next point off the todo list + uint32 thePoint= todo.back(); + todo.pop_back(); + + // add the point to the zone + theZone.add(thePoint); + + // a little macro for the code to perform for each movement test... + #define TEST_MOVE(xoffs,yoffs)\ + {\ + TAccessiblePoints::iterator it= accessiblePoints.find(thePoint+xoffs+_ScanWidth*yoffs);\ + if (it!=accessiblePoints.end())\ + {\ + todo.push_back(*it);\ + accessiblePoints.erase(it);\ + }\ + } + + // N, S, W, E moves + TEST_MOVE( 0, 1); + TEST_MOVE( 0,-1); + TEST_MOVE( 1, 0); + TEST_MOVE(-1, 0); + + // NW, NE, WS, SE moves + TEST_MOVE( 1, 1); + TEST_MOVE(-1, 1); + TEST_MOVE( 1,-1); + TEST_MOVE(-1,-1); + + #undef TEST_MOVE + } + } + + nlinfo("Found %u zones",zones.size()); +} + +//------------------------------------------------------------------------------------------------- +void CProximityMapBuffer::_prepareBufferForZoneProximityMap(const CProximityZone& zone,TBuffer& zoneBuffer,TOffsetsVector& accessiblePoints) +{ + // the length of runs that we consider too short to deal with... + const uint32 shortRunLength=5; + + // redimention and initialise the zone buffer + uint32 zoneWidth= zone.getZoneWidth(); + uint32 zoneHeight= zone.getZoneHeight(); + zoneBuffer.clear(); + zoneBuffer.resize(zoneWidth*zoneHeight,(TBufferEntry)~0u); + + // setup the buffer's accessible points and prime vects[0] with the set of accessible points in the zone buffer + for (uint32 i=0;istartOffset && zoneBuffer[endOffset]!=0; endOffset-= zoneWidth) {} + + for (uint32 offset=startOffset, marker=startOffset;offset<=endOffset;offset+=zoneWidth) + { + // see if this is an accessible position + if (zoneBuffer[offset]!=0) + { + zoneBuffer[offset]= InteriorValue; + + if(offset-1>=startOffset && zoneBuffer[offset-1]==(TBufferEntry)~0u) + { + zoneBuffer[offset-1] = ValueBorder; + } + if(offset+1<=endOffset && zoneBuffer[offset+1]==(TBufferEntry)~0u) + { + zoneBuffer[offset+1] = ValueBorder; + } + } + } + } + + // continue by dealing with all points that belong to a short run in the x direction + for (uint32 i=0;istartOffset && zoneBuffer[endOffset]!=0; --endOffset) {} + + for (uint32 offset=startOffset, marker=startOffset;offset<=endOffset;++offset) + { + // see if this is an accessible position + if (zoneBuffer[offset]!=0) + { + zoneBuffer[offset]= InteriorValue; + + if(offset-zoneWidth>0 && zoneBuffer[offset-zoneWidth]==(TBufferEntry)~0u) + { + zoneBuffer[offset-zoneWidth] = ValueBorder; + } + if(offset+zoneWidth BigValue) + || (zoneBuffer[val]==ValueBorder && dist > BigValue)) + continue; + + // write the new distance into this buffer entry + zoneBuffer[val]=dist; + + // decompose into x and y in order to manage identification of neighbour cells correctly + uint32 x= val% zoneWidth; + uint32 y= val/ zoneWidth; + + #define TEST_MOVE(xoffs,yoffs,newDist)\ + {\ + if (((uint32)(x+(xoffs)) BigValue) || (zoneBuffer[newVal]==ValueBorder && newDist > BigValue));\ + if (zoneBuffer[newVal]>(newDist) && !isInterior)\ + {\ + zoneBuffer[newVal]=(newDist);\ + vects[(newDist)&15].push_back(newVal);\ + ++entriesToTreat;\ + }\ + }\ + } + + // N, S, W, E moves + TEST_MOVE( 0, 1,dist+5); + TEST_MOVE( 0,-1,dist+5); + TEST_MOVE( 1, 0,dist+5); + TEST_MOVE(-1, 0,dist+5); + + // NW, NE, WS, SE moves + TEST_MOVE( 1, 1,dist+7); + TEST_MOVE(-1, 1,dist+7); + TEST_MOVE( 1,-1,dist+7); + TEST_MOVE(-1,-1,dist+7); + + // NNW, NNE, SSW, SSE moves + TEST_MOVE( 1, 2,dist+11); + TEST_MOVE(-1, 2,dist+11); + TEST_MOVE( 1,-2,dist+11); + TEST_MOVE(-1,-2,dist+11); + + // WNW, WSW, ENE, ESE moves + TEST_MOVE( 2, 1,dist+11); + TEST_MOVE(-2, 1,dist+11); + TEST_MOVE( 2,-1,dist+11); + TEST_MOVE(-2,-1,dist+11); + + #undef TEST_MOVE + } + + // clear out the vector + entriesToTreat-= vect.size(); + vect.clear(); + } +} + +//------------------------------------------------------------------------------------------------- +const TBuffer& CProximityMapBuffer::getBuffer() const +{ + return _Buffer; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityMapBuffer::getScanHeight() const +{ + return _ScanHeight; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityMapBuffer::getScanWidth() const +{ + return _ScanWidth; +} + +//----------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------- +// methods CProximityZone +//------------------------------------------------------------------------------------------------- + +CProximityZone::CProximityZone(uint32 scanWidth,uint32 scanHeight,sint32 xOffset, sint32 yOffset) +{ + _ScanWidth = scanWidth; + _ScanHeight = scanHeight; + _XOffset = xOffset; + _YOffset = yOffset; + + _MaxOffset = scanWidth * scanHeight -1; + + _XMin = ~0u; + _YMin = ~0u; + _XMax = 0; + _YMax = 0; + + _BorderPixels = 30; +} + +//------------------------------------------------------------------------------------------------- +bool CProximityZone::add(uint32 offset) +{ + // make sure the requested point is in the zone + if (offset>_MaxOffset) + return false; + + // calculate the x and y coordinates of the point + uint32 y= offset/ _ScanWidth; + uint32 x= offset% _ScanWidth; + + // update the bounding coordinates for this zone + if (x<_XMin) _XMin= x; + if (x>_XMax) _XMax= x; + if (y<_YMin) _YMin= y; + if (y>_YMax) _YMax= y; + + // add the point to the vector of points + _Offsets.push_back(offset); + return true; +} + +//------------------------------------------------------------------------------------------------- +const CProximityZone::TOffsets& CProximityZone::getOffsets() const +{ + return _Offsets; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getZoneWidth() const +{ + return getZoneXMax()- getZoneXMin() +1; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getZoneHeight() const +{ + return getZoneYMax()- getZoneYMin() +1; +} + +//------------------------------------------------------------------------------------------------- +sint32 CProximityZone::getZoneXMin() const +{ + return _XMin-_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +sint32 CProximityZone::getZoneYMin() const +{ + return _YMin-_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getZoneXMax() const +{ + return _XMax+_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getZoneYMax() const +{ + return _YMax+_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getBoundXMin() const +{ + return _XMin+_XOffset-_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getBoundYMin() const +{ + return _YMin+_YOffset-_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getBoundXMax() const +{ + return _XMax+_XOffset+_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::getBoundYMax() const +{ + return _YMax+_YOffset+_BorderPixels; +} + +//------------------------------------------------------------------------------------------------- +uint32 CProximityZone::remapOffset(uint32 bufferOffset) const +{ + // decompose input coordinates into x and y parts + uint32 bufferX= bufferOffset% _ScanWidth; + uint32 bufferY= bufferOffset/ _ScanWidth; + + // remap the offset from a _Buffer-relative offset to a zone-relative offset + return bufferX-getZoneXMin()+ (bufferY-getZoneYMin())*getZoneWidth(); +} + +} + diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.h b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.h new file mode 100644 index 000000000..7d47fa3e7 --- /dev/null +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.h @@ -0,0 +1,241 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_SCRRENSHOT_ISLANDS_H +#define CL_SCRRENSHOT_ISLANDS_H + +// Misc +#include "nel/misc/singleton.h" +#include "nel/misc/vector_2f.h" +#include "nel/misc/rgba.h" +#include "nel/misc/bitmap.h" + +#include + +namespace NL3D +{ + class UScene; + class ULandscape; +} + +namespace R2 +{ + class CProximityZone; + +typedef uint16 TBufferEntry; +typedef std::vector TBuffer; +typedef std::vector TOffsetsVector; + +//----------------------------------------------------------------------------- +// class CScreenshotIslands +//----------------------------------------------------------------------------- +struct CIslandData +{ + NLMISC::CVector2f EntryPoint; + NLMISC::CVector2f Max; + NLMISC::CVector2f Min; + + CIslandData() + { + EntryPoint = NLMISC::CVector2f(0, 0); + Max = NLMISC::CVector2f(0, 0); + Min = NLMISC::CVector2f(0, 0); + } + + CIslandData(float x, float y) + { + EntryPoint = NLMISC::CVector2f(x, y); + Max = NLMISC::CVector2f(0, 0); + Min = NLMISC::CVector2f(0, 0); + } +}; + +struct CContinentData +{ + std::string SmallBank; + std::string FarBank; + std::string IGFile; + std::string CoarseMeshMap; + NLMISC::CVector2f ZoneMin; + NLMISC::CVector2f ZoneMax; + std::list< std::string > Islands; + NLMISC::CRGBA Ambiant; + NLMISC::CRGBA Diffuse; + + CContinentData() {} +}; + +typedef std::map< const std::string, CProximityZone> TIslandsData; +typedef std::map< NLMISC::CVector2f, bool > TIslandsMap; +typedef std::map< const std::string, CContinentData > TContinentsData; +typedef std::map< std::string, std::list< NLMISC::CVector2f > > TIslandsBordersMap; + +class CScreenshotIslands : public NLMISC::CSingleton +{ + +public: + + CScreenshotIslands(); + + void buildScreenshots(); + +private: + + void init(); + + void loadIslands(); + + void buildIslandsTextures(); + + void getBuffer(NL3D::UScene * scene, NL3D::ULandscape * landscape, NLMISC::CBitmap &btm); + + bool getPosFromZoneName(const std::string &name, NLMISC::CVector2f &dest); + + void writeProximityBufferToTgaFile(const std::string& fileName,const TBuffer& buffer, + uint32 scanWidth,uint32 scanHeight); + + void processProximityBuffer(TBuffer& inputBuffer, uint32 lineLength, TBuffer& resultBuffer); + + void buildBackTextureHLS(const std::string & islandName, const NLMISC::CBitmap & islandBitmap); + + void searchIslandsBorders(); + + void attenuateIslandBorders(const std::string & islandName, NLMISC::CBitmap & islandBitmap, const CProximityZone & islandData); + + TIslandsData _IslandsData; + TIslandsMap _IslandsMap; + TContinentsData _ContinentsData; + std::list< std::string > _SeasonSuffixes; + int _MeterPixelSize; + std::string _OutDirectory; + std::list< std::string > _TempFileNames; + TIslandsBordersMap _BorderIslands; + bool _Vegetation; + bool _InverseZTest; + + NLMISC::CRGBA _BackColor; + NLMISC::CBitmap _BackBitmap; + std::string _CompleteIslandsFile; +}; + + + + + + +class CProximityZone +{ +public: + typedef std::vector TOffsets; + + // ctor + // scanWidth and scanHeight define the dimentions of the buffer that this zone is being extracted from + // xOffset and yOffset are for re-mapping coordinates from buffer-relative to absolute ryzom world coordinates + CProximityZone(uint32 scanWidth=0,uint32 scanHeight=0,sint32 xOffset=0, sint32 yOffset=0); + + // add an 'accessible position' to a zone (offset is y*scanWidth+x) + bool add(uint32 offset); + + // zone dimention accessors (note that zone dimentions line up with 160x160 world zones) + // note that this means that the zone bounds may extend outside the scan area + uint32 getZoneWidth() const; + uint32 getZoneHeight() const; + sint32 getZoneXMin() const; + sint32 getZoneYMin() const; + uint32 getZoneXMax() const; + uint32 getZoneYMax() const; + + // read accessors for the bounding limits that define the area occupied by the accessible points + uint32 getBoundXMin() const; + uint32 getBoundYMin() const; + uint32 getBoundXMax() const; + uint32 getBoundYMax() const; + + // read accessor for the _Offsets vector + // this is a vector of offsets into the scan area. It needs to be remapped to zone offsets + // via the remapOffset() routine in order to be used to index into a zone buffer + const TOffsets& getOffsets() const; + + // remap a scan buffer offset to a zone offset by decomposing into x and y parts and + // subtracting getZoneXMin() and getZoneYMin() + uint32 remapOffset(uint32 bufferOffset) const; + +private: + // parameters setup at construction time, giving info on the context that we're in + uint32 _ScanWidth; + uint32 _ScanHeight; + sint32 _XOffset; + sint32 _YOffset; + uint32 _MaxOffset; + + // the vector of points that are part of this zone + TOffsets _Offsets; + + // the min and max coords of the points that are part of this zone + uint32 _XMax; + uint32 _XMin; + uint32 _YMax; + uint32 _YMin; + + // border add to bouding zone (pixels number) + int _BorderPixels; +}; + +//------------------------------------------------------------------------------------------------- +// class CProximityMapBuffer +//------------------------------------------------------------------------------------------------- + +class CProximityMapBuffer +{ +public: + typedef std::vector TZones; + + // load a cwmap2 file and setup this object from its contents + // the 'name' parameter is the full file name of the file to load with path and extension + void load(const std::string& name); + + // scan the buffer to generate the set of non-connecting zones that it contains + void calculateZones(TZones& zones); + + // generate the proximity map for a given zone + void generateZoneProximityMap(const CProximityZone& zone,TBuffer& zoneBuffer); + + // read accessors... + const TBuffer& getBuffer() const; + uint32 getScanHeight() const; + uint32 getScanWidth() const; + + // buffer coordinate to world coordinate offsets... + sint32 _XOffset; + sint32 _YOffset; + +private: + // private routine used by generateZoneProximityMap() to setup the zoneBuffer with the accessible points set + void _prepareBufferForZoneProximityMap(const CProximityZone& zone,TBuffer& zoneBuffer,TOffsetsVector& accessiblePoints); + +private: + // the width and heilght of the scan zone (ie the dimentions of the buffer) + uint32 _ScanWidth; + uint32 _ScanHeight; + + // vector representing 2d array of points [_ScanHeight][_ScanWidth] + TBuffer _Buffer; +}; + + +} + +#endif \ No newline at end of file From 6bb136dca9cbdc23b9675615279f4a7edf2e5bc8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 12 Sep 2014 20:33:20 +0200 Subject: [PATCH 086/240] Change cfg name --HG-- branch : develop --- .../tools/client/r2_islands_textures/screenshot_islands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index e6d490a0a..c0fcb667d 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -97,7 +97,7 @@ void CScreenshotIslands::init() // load and parse the configfile CConfigFile cf; - cf.load("IslandScreenshots.cfg"); + cf.load("island_screenshots.cfg"); CPath::remapExtension("dds", "tga", true); From 83566116d926841f89585e6c7edaf40582cd0298 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 12 Sep 2014 21:01:29 +0200 Subject: [PATCH 087/240] Added link action. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 26 ++++++++++++++----- .../plugins/gui_editor/expression_editor.h | 4 ++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index e4d749dcd..2909b0835 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -28,7 +28,7 @@ QWidget( parent ) { m_ui.setupUi( this ); - m_hasSelection = false; + m_selectionCount = 0; m_scene = new QGraphicsScene( this ); m_ui.view->setScene( m_scene ); @@ -51,10 +51,16 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Add rect" ); connect( a, SIGNAL( triggered() ), this, SLOT( onAddRect() ) ); - if( m_hasSelection ) + if( m_selectionCount > 0 ) { a = menu.addAction( "Remove" ); connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) ); + + if( m_selectionCount == 2 ) + { + a = menu.addAction( "Link" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onLinkItems() ) ); + } } menu.exec( e->globalPos() ); @@ -78,11 +84,19 @@ void ExpressionEditor::onDeleteSelection() void ExpressionEditor::onSelectionChanged() { QList< QGraphicsItem* > l = m_scene->selectedItems(); - if( l.isEmpty() ) - m_hasSelection = false; - else - m_hasSelection = true; + m_selectionCount = l.count(); } +void ExpressionEditor::onLinkItems() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + QGraphicsItem *from = l[ 0 ]; + QGraphicsItem *to = l[ 1 ]; + + QGraphicsLineItem *line = new QGraphicsLineItem(); + line->setLine( QLineF( from->pos(), to->pos() ) ); + line->setPen( QPen( Qt::darkRed, 1.0 ) ); + m_scene->addItem( line ); +} diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index b73f8029f..70d2ad572 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -38,12 +38,14 @@ private Q_SLOTS: void onAddRect(); void onDeleteSelection(); void onSelectionChanged(); + void onLinkItems(); private: + Ui::ExpressionEditor m_ui; QGraphicsScene *m_scene; - bool m_hasSelection; + int m_selectionCount; }; #endif From adece7564a4b5a4c755964d4970cbe181768c7c3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 12 Sep 2014 23:45:57 +0200 Subject: [PATCH 088/240] Subclassed QGraphicsItem and QGraphicsItemLine. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 12 +++-- .../plugins/gui_editor/expression_link.cpp | 44 ++++++++++++++++ .../src/plugins/gui_editor/expression_link.h | 44 ++++++++++++++++ .../plugins/gui_editor/expression_node.cpp | 50 +++++++++++++++++++ .../src/plugins/gui_editor/expression_node.h | 37 ++++++++++++++ 5 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/expression_link.cpp create mode 100644 code/studio/src/plugins/gui_editor/expression_link.h create mode 100644 code/studio/src/plugins/gui_editor/expression_node.cpp create mode 100644 code/studio/src/plugins/gui_editor/expression_node.h diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 2909b0835..5fad4f054 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -23,6 +23,9 @@ #include #include +#include "expression_node.h" +#include "expression_link.h" + ExpressionEditor::ExpressionEditor( QWidget *parent ) : QWidget( parent ) { @@ -68,7 +71,7 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) void ExpressionEditor::onAddRect() { - QGraphicsRectItem *item = new QGraphicsRectItem( 0, 0, 100, 100 ); + QGraphicsItem *item = new ExpressionNode(); item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); m_scene->addItem( item ); } @@ -93,10 +96,9 @@ void ExpressionEditor::onLinkItems() QGraphicsItem *from = l[ 0 ]; QGraphicsItem *to = l[ 1 ]; - QGraphicsLineItem *line = new QGraphicsLineItem(); - line->setLine( QLineF( from->pos(), to->pos() ) ); - line->setPen( QPen( Qt::darkRed, 1.0 ) ); - m_scene->addItem( line ); + ExpressionLink *link = new ExpressionLink(); + link->link( from, to ); + m_scene->addItem( link ); } diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp new file mode 100644 index 000000000..55f0f8421 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -0,0 +1,44 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_link.h" +#include +#include + +ExpressionLink::ExpressionLink( QGraphicsItem *parent ) : +QGraphicsLineItem( parent ) +{ + m_from = NULL; + m_to = NULL; +} + +ExpressionLink::~ExpressionLink() +{ +} + +void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +{ + if( m_from != NULL ) + setLine( QLineF( m_from->pos(), m_to->pos() ) ); + + setPen( QPen( Qt::darkRed ) ); + + QGraphicsLineItem::paint( painter, option, widget ); +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h new file mode 100644 index 000000000..d45900691 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -0,0 +1,44 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_LINK +#define EXPRESSION_LINK + +#include + +class ExpressionLink : public QGraphicsLineItem +{ +public: + ExpressionLink( QGraphicsItem *parent = NULL ); + ~ExpressionLink(); + + void link( QGraphicsItem *from, QGraphicsItem *to ){ + m_from = from; + m_to = to; + } + + void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + +private: + QGraphicsItem *m_from; + QGraphicsItem *m_to; + +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp new file mode 100644 index 000000000..3fc0d7d2b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -0,0 +1,50 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expression_node.h" +#include +#include + +ExpressionNode::ExpressionNode( QGraphicsItem *parent ) : +QGraphicsItem( parent ) +{ +} + +ExpressionNode::~ExpressionNode() +{ +} + +QRectF ExpressionNode::boundingRect() const +{ + return QRectF( 0, 0, 100, 100 ); +} + +void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +{ + if( option->state & QStyle::State_Selected ) + { + QPen outline; + outline.setStyle( Qt::DotLine ); + painter->setPen( outline ); + + } + + painter->drawRect( boundingRect() ); +} + diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h new file mode 100644 index 000000000..354905c3e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -0,0 +1,37 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPRESSION_NODE +#define EXPRESSION_NODE + +#include + +class ExpressionNode : public QGraphicsItem +{ +public: + ExpressionNode( QGraphicsItem *parent = NULL ); + ~ExpressionNode(); + + QRectF boundingRect() const; + void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + +}; + +#endif + From d2c396bc84d1d13befab3d77f2cc591996b2bf86 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 00:43:00 +0200 Subject: [PATCH 089/240] Link nodes and remove and delete the link too when deleting one of the nodes. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 24 ++++++++++++++-- .../plugins/gui_editor/expression_link.cpp | 28 +++++++++++++++++-- .../src/plugins/gui_editor/expression_link.h | 14 ++++++---- .../plugins/gui_editor/expression_node.cpp | 12 ++++++++ .../src/plugins/gui_editor/expression_node.h | 11 ++++++++ 5 files changed, 77 insertions(+), 12 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 5fad4f054..48f807696 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -81,7 +81,24 @@ void ExpressionEditor::onDeleteSelection() QList< QGraphicsItem* > l = m_scene->selectedItems(); QListIterator< QGraphicsItem* > itr( l ); while( itr.hasNext() ) - m_scene->removeItem( itr.next() ); + { + QGraphicsItem *item = itr.next(); + + ExpressionNode *node = dynamic_cast< ExpressionNode* >( item ); + if( node != NULL ) + { + ExpressionLink *link = node->link(); + if( link != NULL ) + { + link->unlink(); + m_scene->removeItem( link ); + delete link; + } + } + + m_scene->removeItem( item ); + delete item; + } } void ExpressionEditor::onSelectionChanged() @@ -93,11 +110,12 @@ void ExpressionEditor::onSelectionChanged() void ExpressionEditor::onLinkItems() { QList< QGraphicsItem* > l = m_scene->selectedItems(); - QGraphicsItem *from = l[ 0 ]; - QGraphicsItem *to = l[ 1 ]; + ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] ); + ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] ); ExpressionLink *link = new ExpressionLink(); link->link( from, to ); + m_scene->addItem( link ); } diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 55f0f8421..9fa6aa536 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -17,6 +17,7 @@ // along with this program. If not, see . #include "expression_link.h" +#include "expression_node.h" #include #include @@ -25,17 +26,38 @@ QGraphicsLineItem( parent ) { m_from = NULL; m_to = NULL; + + setFlags( QGraphicsItem::ItemIsSelectable ); } ExpressionLink::~ExpressionLink() { + unlink(); } -void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to ) +{ + m_from = from; + m_to = to; + m_from->setLink( this ); + m_to->setLink( this ); + + nodeMoved(); +} + +void ExpressionLink::unlink() { - if( m_from != NULL ) - setLine( QLineF( m_from->pos(), m_to->pos() ) ); + m_from->setLink( NULL ); + m_to->setLink( NULL ); +} + +void ExpressionLink::nodeMoved() +{ + setLine( QLineF( m_from->pos(), m_to->pos() ) ); +} +void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +{ setPen( QPen( Qt::darkRed ) ); QGraphicsLineItem::paint( painter, option, widget ); diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h index d45900691..59644980a 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.h +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -21,22 +21,24 @@ #include +class ExpressionNode; + class ExpressionLink : public QGraphicsLineItem { public: ExpressionLink( QGraphicsItem *parent = NULL ); ~ExpressionLink(); - void link( QGraphicsItem *from, QGraphicsItem *to ){ - m_from = from; - m_to = to; - } + void link( ExpressionNode *from, ExpressionNode *to ); + void unlink(); + + void nodeMoved(); void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); private: - QGraphicsItem *m_from; - QGraphicsItem *m_to; + ExpressionNode *m_from; + ExpressionNode *m_to; }; diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 3fc0d7d2b..8e92b6705 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -18,12 +18,14 @@ #include "expression_node.h" +#include "expression_link.h" #include #include ExpressionNode::ExpressionNode( QGraphicsItem *parent ) : QGraphicsItem( parent ) { + m_link = NULL; } ExpressionNode::~ExpressionNode() @@ -48,3 +50,13 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o painter->drawRect( boundingRect() ); } + +void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) +{ + if( m_link != NULL ) + m_link->nodeMoved(); + + QGraphicsItem::mouseMoveEvent( e ); +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 354905c3e..a3bf701fd 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -22,6 +22,8 @@ #include +class ExpressionLink; + class ExpressionNode : public QGraphicsItem { public: @@ -31,6 +33,15 @@ public: QRectF boundingRect() const; void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + void setLink( ExpressionLink *link ){ m_link = link; } + ExpressionLink* link() const{ return m_link; } + +protected: + void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); + +private: + ExpressionLink *m_link; + }; #endif From af550acd62a85760e10b4055d432559015fb025b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 00:54:37 +0200 Subject: [PATCH 090/240] Throw an error message when trying to link nodes that are already linked. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expression_editor.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 48f807696..d942623ba 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -26,6 +26,8 @@ #include "expression_node.h" #include "expression_link.h" +#include + ExpressionEditor::ExpressionEditor( QWidget *parent ) : QWidget( parent ) { @@ -113,6 +115,14 @@ void ExpressionEditor::onLinkItems() ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] ); ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] ); + if( ( from->link() != NULL ) || ( to->link() != NULL ) ) + { + QMessageBox::information( this, + tr( "Failed to link nodes" ), + tr( "Unfortunately those nodes are already linked." ) ); + return; + } + ExpressionLink *link = new ExpressionLink(); link->link( from, to ); From 9678b56ed5873ef13725211f2cf2e47e47170c07 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 13 Sep 2014 11:13:25 +0200 Subject: [PATCH 091/240] Fix strange code --HG-- branch : develop --- .../tools/client/r2_islands_textures/screenshot_islands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index db115b154..8228c3e2e 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -590,7 +590,7 @@ void CScreenshotIslands::buildScreenshots() //------------------------------------------------------------------------------------------------- void CScreenshotIslands::writeProximityBufferToTgaFile(const std::string& fileName,const TBuffer& buffer,uint32 scanWidth,uint32 scanHeight) { - uint imageWidth = (scanWidth+15)&~15; + uint imageWidth = (scanWidth); // (scanWidth+15)&~15; uint imageHeight = (scanHeight); CTGAImageGrey tgaImage; From 7fed632c540ea86b9f6eed9ff0726257db5d5f7a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 13 Sep 2014 12:02:47 +0200 Subject: [PATCH 092/240] Fix includes --HG-- branch : develop --- .../phrase_manager/fg_prospection_phrase.cpp | 2 +- .../entities_game_service/phrase_manager/sabrina_area_debug.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp index 010176023..f2fc03eb0 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp @@ -1509,7 +1509,7 @@ NLMISC_DYNVARIABLE( uint32, RyzomSeason, "Get season number (0=Spring)" ) #ifdef DEPOSIT_MAP_GENERATION -#include "server_share/bmp4image.h" +#include "game_share/bmp4image.h" #include typedef std::map< std::string, pair< pair< float, float >, uint > > CSUMap; diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/sabrina_area_debug.h b/code/ryzom/server/src/entities_game_service/phrase_manager/sabrina_area_debug.h index 4964b78e1..a87c0a092 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/sabrina_area_debug.h +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/sabrina_area_debug.h @@ -23,7 +23,7 @@ #include "egs_mirror.h" #include "area_geometry.h" -#include "server_share/bmp4image.h" +#include "game_share/bmp4image.h" From 433d83e2fca8550de1311b8f14fce2cfb17d5906 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 13 Sep 2014 12:14:45 +0200 Subject: [PATCH 093/240] Increase texturing limits (*4), ref #203 (TODO: Update config translations) --HG-- branch : develop --- code/ryzom/client/src/init_main_loop.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index 537f322f8..390b82e15 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -153,8 +153,12 @@ bool UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING; #define ENTITY_TEXTURE_NORMAL_LEVEL 1 #define ENTITY_TEXTURE_HIGH_LEVEL 0 // Size in MB of the cache for entity texturing. -#define ENTITY_TEXTURE_NORMAL_MEMORY 10 -#define ENTITY_TEXTURE_HIGH_MEMORY 40 +#define ENTITY_TEXTURE_NORMAL_MEMORY 40 +#define ENTITY_TEXTURE_HIGH_MEMORY 160 +// Size in KB of max upload per frame +#define ENTITY_TEXTURE_LOW_MAXUP 64 +#define ENTITY_TEXTURE_NORMAL_MAXUP 128 +#define ENTITY_TEXTURE_HIGH_MAXUP 256 // Don't Modify, set true for debug purpose only const bool DBG_DisablePreloadShape= false; @@ -885,8 +889,10 @@ void initMainLoop() { // setup "v2 texture" (or 512*512) Driver->setupAsyncTextureLod(ENTITY_TEXTURE_COARSE_LEVEL, ENTITY_TEXTURE_HIGH_LEVEL); - // Allow a big cache for them (should be on 128 Mo card only) + // Allow a big cache for them (should be on 512 Mo card only) Driver->setupMaxTotalAsyncTextureSize(ENTITY_TEXTURE_HIGH_MEMORY*1024*1024); + // Allow high upload + Driver->setupAsyncTextureMaxUploadPerFrame(ENTITY_TEXTURE_HIGH_MAXUP*1024); } else { @@ -894,6 +900,8 @@ void initMainLoop() Driver->setupAsyncTextureLod(ENTITY_TEXTURE_COARSE_LEVEL, ENTITY_TEXTURE_NORMAL_LEVEL); // Allow a big cache for them Driver->setupMaxTotalAsyncTextureSize(ENTITY_TEXTURE_NORMAL_MEMORY*1024*1024); + // Allow normal upload + Driver->setupAsyncTextureMaxUploadPerFrame(ENTITY_TEXTURE_NORMAL_MAXUP*1024); } } else @@ -904,6 +912,8 @@ void initMainLoop() Driver->setupAsyncTextureLod(ENTITY_TEXTURE_COARSE_LEVEL-1, ENTITY_TEXTURE_NORMAL_LEVEL-1); // Allow a big cache for them Driver->setupMaxTotalAsyncTextureSize(ENTITY_TEXTURE_NORMAL_MEMORY*1024*1024); + // Allow low upload + Driver->setupAsyncTextureMaxUploadPerFrame(ENTITY_TEXTURE_LOW_MAXUP*1024); } } From aef69eef643ee56a1724a6d11045978515614d08 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 18:03:02 +0200 Subject: [PATCH 094/240] Add a little style. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_link.cpp | 2 +- .../plugins/gui_editor/expression_node.cpp | 35 ++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 9fa6aa536..c17ad8b30 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -58,7 +58,7 @@ void ExpressionLink::nodeMoved() void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) { - setPen( QPen( Qt::darkRed ) ); + setPen( QPen( Qt::black ) ); QGraphicsLineItem::paint( painter, option, widget ); } diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8e92b6705..334fd3042 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -39,15 +39,40 @@ QRectF ExpressionNode::boundingRect() const void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) { + QBrush br; + QPen p; + QColor c; + + QRectF rect = boundingRect(); + QRectF header = rect; + header.setHeight( header.height() * 0.2 ); + + // Draw filled rectangle, header + c.setRed( 44 ); + c.setGreen( 169 ); + c.setBlue( 232 ); + br.setColor( c ); + br.setStyle( Qt::SolidPattern ); + p.setColor( c ); + painter->setPen( p ); + painter->fillRect( header, br ); + + // Draw header text + p.setColor( Qt::black ); + painter->setPen( p ); + painter->drawText( header, Qt::AlignCenter, "Something" ); + + if( option->state & QStyle::State_Selected ) { - QPen outline; - outline.setStyle( Qt::DotLine ); - painter->setPen( outline ); - + p.setStyle( Qt::DotLine ); + p.setColor( Qt::red ); } - painter->drawRect( boundingRect() ); + // Draw outline of the entire thing + header + painter->setPen( p ); + painter->drawRect( rect ); + painter->drawRect( header ); } From 765e614c237c2327df6e65591d5c364f896a8597 Mon Sep 17 00:00:00 2001 From: botanic Date: Sat, 13 Sep 2014 10:30:58 -0700 Subject: [PATCH 095/240] Fix #122 --HG-- branch : develop --- code/web/private_php/ams/autoload/dblayer.php | 2 +- code/web/private_php/ams/autoload/helpers.php | 12 ++++- .../ams/ingame_templates/register.tpl | 4 ++ code/web/public_php/ams/css/custom.css | 4 ++ code/web/public_php/ams/inc/register.php | 1 + code/web/public_php/ams/inc/settings.php | 12 ++++- code/web/public_php/ams/templates/login.tpl | 7 ++- .../web/public_php/ams/templates/register.tpl | 4 ++ .../web/public_php/ams/templates/settings.tpl | 51 +++++++++++++++++++ 9 files changed, 92 insertions(+), 5 deletions(-) diff --git a/code/web/private_php/ams/autoload/dblayer.php b/code/web/private_php/ams/autoload/dblayer.php index d14e48e84..f7871ebcb 100644 --- a/code/web/private_php/ams/autoload/dblayer.php +++ b/code/web/private_php/ams/autoload/dblayer.php @@ -214,7 +214,7 @@ class DBLayer { } $field_option_values = ltrim($field_option_values, ','); try { - $sth = $this->PDO->prepare("UPDATE $tb_name SET $field_option_values WHERE $where "); + $sth = $this->PDO->prepare("UPDATE `$tb_name` SET $field_option_values WHERE $where "); foreach ($data as $key => $value) { $sth->bindValue(":$key", $value); diff --git a/code/web/private_php/ams/autoload/helpers.php b/code/web/private_php/ams/autoload/helpers.php index 0ebc6d8fc..bcfde1c02 100644 --- a/code/web/private_php/ams/autoload/helpers.php +++ b/code/web/private_php/ams/autoload/helpers.php @@ -23,7 +23,7 @@ class Helpers { global $AMS_TRANS; global $INGAME_LAYOUT; global $AMS_CACHEDIR; - global $AMS_PLUGINS; + global $AMS_PLUGINS; // define('SMARTY_SPL_AUTOLOAD',1); require_once $AMS_LIB . '/smarty/libs/Smarty.class.php'; @@ -34,7 +34,7 @@ class Helpers { $smarty -> setCacheDir( $AMS_CACHEDIR ); $smarty -> setConfigDir( $SITEBASE . '/configs/' ); // turn smarty debugging on/off - $smarty -> debugging = false; + $smarty -> debugging = true; // caching must be disabled for multi-language support $smarty -> caching = false; $smarty -> cache_lifetime = 300; @@ -89,6 +89,14 @@ class Helpers { $id = session_id(); $smarty -> assign( "sessionid", $id ); + + $dbl = new DBLayer("lib"); + $statement = $dbl->executeWithoutParams("SELECT * FROM settings"); + $rows = $statement->fetchAll(); + + foreach ($rows as &$value) { + $smarty -> assign( $value['Setting'], $value['Value'] ); + } // smarty inheritance for loading the matching wrapper layout (with the matching menu bar) if ( isset( $vars['permission'] ) && $vars['permission'] == 3 ) { diff --git a/code/web/private_php/ams/ingame_templates/register.tpl b/code/web/private_php/ams/ingame_templates/register.tpl index 9fa8fef32..7f34e8639 100644 --- a/code/web/private_php/ams/ingame_templates/register.tpl +++ b/code/web/private_php/ams/ingame_templates/register.tpl @@ -7,6 +7,8 @@ {$welcome_message} + {if $userRegistration == '0'|| $userRegistration == '1'} +
@@ -89,6 +91,8 @@
+ + {/if}
executeWithoutParams("SELECT * FROM settings"); + $rows = $statement->fetchAll(); + + foreach ($rows as &$value) { + $result[$value['Setting']] = $value['Value']; + } + return $result; }else{ //ERROR: not logged in! diff --git a/code/web/public_php/ams/templates/login.tpl b/code/web/public_php/ams/templates/login.tpl index 7acdf3bbe..23834554a 100644 --- a/code/web/public_php/ams/templates/login.tpl +++ b/code/web/public_php/ams/templates/login.tpl @@ -12,6 +12,7 @@
{$login_info}
+
@@ -42,9 +43,13 @@ {$login_error_message}
{/if} + + + +
{/block} diff --git a/code/web/public_php/ams/templates/register.tpl b/code/web/public_php/ams/templates/register.tpl index b5ea3980d..24aac42a2 100644 --- a/code/web/public_php/ams/templates/register.tpl +++ b/code/web/public_php/ams/templates/register.tpl @@ -12,6 +12,7 @@
{$welcome_message}
+ {if $userRegistration == '0'|| $userRegistration == '2'} {$title} @@ -111,6 +112,9 @@

+ {else} + Registration Disabled! + {/if} diff --git a/code/web/public_php/ams/templates/settings.tpl b/code/web/public_php/ams/templates/settings.tpl index 4ee9f2c6a..94883c9de 100644 --- a/code/web/public_php/ams/templates/settings.tpl +++ b/code/web/public_php/ams/templates/settings.tpl @@ -323,6 +323,57 @@ + + {if $permission == '3'} +
+
+
+ User Registration +
+
+
+
+ User Registration + +
+
+ +
+ +
+ +
+ +
+
+ + + +
+ +
+ +
+
+
+
+
+
+
+ {/if} + From 9b813a5e4cfb9c0fc39bbe5394555da603eb4165 Mon Sep 17 00:00:00 2001 From: botanic Date: Sat, 13 Sep 2014 10:31:12 -0700 Subject: [PATCH 096/240] Fix #122 --HG-- branch : develop --- .../setup/sql/nel_ams_lib_00006.sql | 14 +++++++ .../public_php/ams/func/userRegistration.php | 42 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 code/web/private_php/setup/sql/nel_ams_lib_00006.sql create mode 100644 code/web/public_php/ams/func/userRegistration.php diff --git a/code/web/private_php/setup/sql/nel_ams_lib_00006.sql b/code/web/private_php/setup/sql/nel_ams_lib_00006.sql new file mode 100644 index 000000000..8a344379c --- /dev/null +++ b/code/web/private_php/setup/sql/nel_ams_lib_00006.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS `settings` ( +`idSettings` int(11) NOT NULL, + `Setting` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `Value` varchar(32) COLLATE utf8_unicode_ci NOT NULL +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +INSERT INTO `settings` (`idSettings`, `Setting`, `Value`) VALUES +(1, 'userRegistration', '0'); + +ALTER TABLE `settings` + ADD PRIMARY KEY (`idSettings`), ADD UNIQUE KEY `idSettings` (`idSettings`), ADD KEY `idSettings_2` (`idSettings`); + +ALTER TABLE `settings` +MODIFY `idSettings` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2; \ No newline at end of file diff --git a/code/web/public_php/ams/func/userRegistration.php b/code/web/public_php/ams/func/userRegistration.php new file mode 100644 index 000000000..632c0681d --- /dev/null +++ b/code/web/public_php/ams/func/userRegistration.php @@ -0,0 +1,42 @@ +update("settings", Array('Value' => $_POST['userRegistration']), "`Setting` = 'userRegistration'"); + + $result['target_id'] = $_GET['id']; + global $SITEBASE; + require_once($SITEBASE . '/inc/settings.php'); + $pageElements = settings(); + $pageElements = array_merge(settings(), $result); + $pageElements['permission'] = unserialize($_SESSION['ticket_user'])->getPermission(); + // pass error and reload template accordingly + helpers :: loadtemplate( 'settings', $pageElements); + throw new SystemExit(); + + } else { + //ERROR: user is not logged in + header("Location: index.php"); + throw new SystemExit(); + } + + } + catch (PDOException $e) { + //go to error page or something, because can't access website db + print_r($e); + throw new SystemExit(); + } + +} \ No newline at end of file From 3c01c5c8119250bfa340e0b188921f20c25cc145 Mon Sep 17 00:00:00 2001 From: botanic Date: Sat, 13 Sep 2014 10:35:21 -0700 Subject: [PATCH 097/240] disable debug mode --HG-- branch : develop --- code/web/private_php/ams/autoload/helpers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/private_php/ams/autoload/helpers.php b/code/web/private_php/ams/autoload/helpers.php index bcfde1c02..94b45706d 100644 --- a/code/web/private_php/ams/autoload/helpers.php +++ b/code/web/private_php/ams/autoload/helpers.php @@ -34,7 +34,7 @@ class Helpers { $smarty -> setCacheDir( $AMS_CACHEDIR ); $smarty -> setConfigDir( $SITEBASE . '/configs/' ); // turn smarty debugging on/off - $smarty -> debugging = true; + $smarty -> debugging = false; // caching must be disabled for multi-language support $smarty -> caching = false; $smarty -> cache_lifetime = 300; From 53ea877a50ffe3afeb0f24cc9a76732a76476254 Mon Sep 17 00:00:00 2001 From: botanic Date: Sat, 13 Sep 2014 10:40:47 -0700 Subject: [PATCH 098/240] update lib sql version --HG-- branch : develop --- code/web/public_php/setup/database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/public_php/setup/database.php b/code/web/public_php/setup/database.php index 303df57d5..6a1b836ea 100644 --- a/code/web/public_php/setup/database.php +++ b/code/web/public_php/setup/database.php @@ -6,7 +6,7 @@ $db_nel_tool = 2; // Support $db_nel_ams = 1; -$db_nel_ams_lib = 5; +$db_nel_ams_lib = 6; // Domain $db_ring_domain = 1; From 7c930366de4ace47258e44b3e5264ab057384bd9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 21:34:47 +0200 Subject: [PATCH 099/240] Paint the connection text, boxes separately. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 2 - .../plugins/gui_editor/expression_link.cpp | 5 +- .../plugins/gui_editor/expression_node.cpp | 55 ++++++++++++++++++- .../src/plugins/gui_editor/expression_node.h | 2 + 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index d942623ba..313af23b5 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -38,8 +38,6 @@ QWidget( parent ) m_scene = new QGraphicsScene( this ); m_ui.view->setScene( m_scene ); - m_scene->addSimpleText( "Hello" ); - connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); } diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index c17ad8b30..1e7f7cf5f 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -58,7 +58,10 @@ void ExpressionLink::nodeMoved() void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) { - setPen( QPen( Qt::black ) ); + QPen p; + p.setColor( Qt::black ); + p.setWidth( 5 ); + setPen( p ); QGraphicsLineItem::paint( painter, option, widget ); } diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 334fd3042..fae024096 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -40,6 +40,7 @@ QRectF ExpressionNode::boundingRect() const void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) { QBrush br; + QBrush boxBrush; QPen p; QColor c; @@ -62,7 +63,6 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o painter->setPen( p ); painter->drawText( header, Qt::AlignCenter, "Something" ); - if( option->state & QStyle::State_Selected ) { p.setStyle( Qt::DotLine ); @@ -73,6 +73,8 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o painter->setPen( p ); painter->drawRect( rect ); painter->drawRect( header ); + + paintConnections( painter ); } @@ -84,4 +86,55 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) QGraphicsItem::mouseMoveEvent( e ); } +void ExpressionNode::paintConnections( QPainter *painter ) +{ + QRectF rect = boundingRect(); + QBrush boxBrush; + QPen p; + + boxBrush.setColor( Qt::black ); + boxBrush.setStyle( Qt::SolidPattern ); + p.setColor( Qt::black ); + + QRectF box = rect; + QRectF tbox = rect; + qreal wh = 10.0; + qreal tw = 25.0; + qreal th = 12.0; + + box.setTopLeft( QPoint( 0, rect.height() * 0.5 ) ); + box.setHeight( wh ); + box.setWidth( wh ); + + painter->fillRect( box, boxBrush ); + + tbox.setTopLeft( QPoint( 15, rect.height() * 0.50 ) ); + tbox.setHeight( th ); + tbox.setWidth( tw ); + painter->setPen( p ); + painter->drawText( tbox, Qt::AlignCenter, "Out" ); + + + for( int i = 0; i < 3; i++ ) + { + qreal x = rect.width() - wh; + qreal y = 30 + i * 20; + qreal tx = x - 5 - tw; + qreal ty = y - 2; + + box.setTopLeft( QPoint( x, y ) ); + box.setHeight( wh ); + box.setWidth( wh ); + + painter->fillRect( box, boxBrush ); + + tbox.setTopLeft( QPoint( tx, ty ) ); + tbox.setHeight( th ); + tbox.setWidth( tw ); + + QString text = 'A' + i; + painter->drawText( tbox, Qt::AlignRight, text ); + } +} + diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index a3bf701fd..6eebcb8a4 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -40,6 +40,8 @@ protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); private: + void paintConnections( QPainter *painter ); + ExpressionLink *m_link; }; From 07933bf52ca449477ae41efbf4cd8e87cc5d0469 Mon Sep 17 00:00:00 2001 From: botanic Date: Sat, 13 Sep 2014 13:09:48 -0700 Subject: [PATCH 100/240] Update smarty for admin to 2.6.28 --HG-- branch : develop --- .../admin/smarty/Config_File.class.php | 782 +-- .../public_php/admin/smarty/Smarty.class.php | 3896 +++++++------- .../admin/smarty/Smarty_Compiler.class.php | 4669 +++++++++-------- code/web/public_php/admin/smarty/debug.tpl | 209 +- .../internals/core.create_dir_structure.php | 2 +- .../internals/core.display_debug_console.php | 2 +- .../admin/smarty/internals/core.is_secure.php | 15 +- .../smarty/internals/core.is_trusted.php | 2 +- .../internals/core.process_cached_inserts.php | 2 +- .../core.process_compiled_include.php | 7 +- .../smarty/internals/core.read_cache_file.php | 10 - .../admin/smarty/internals/core.rmdir.php | 1 - .../internals/core.write_cache_file.php | 2 +- .../internals/core.write_compiled_include.php | 6 +- .../smarty/internals/core.write_file.php | 14 +- .../admin/smarty/plugins/block.textformat.php | 1 + .../admin/smarty/plugins/compiler.assign.php | 2 + .../plugins/function.assign_debug_info.php | 1 + .../smarty/plugins/function.config_load.php | 2 + .../admin/smarty/plugins/function.counter.php | 1 + .../admin/smarty/plugins/function.cycle.php | 6 +- .../admin/smarty/plugins/function.eval.php | 1 + .../admin/smarty/plugins/function.fetch.php | 5 +- .../smarty/plugins/function.html_image.php | 27 +- .../smarty/plugins/function.html_options.php | 40 +- .../smarty/plugins/function.html_radios.php | 20 +- .../plugins/function.html_select_date.php | 47 +- .../plugins/function.html_select_time.php | 2 + .../smarty/plugins/function.html_table.php | 60 +- .../admin/smarty/plugins/function.mailto.php | 4 +- .../admin/smarty/plugins/function.math.php | 10 +- .../admin/smarty/plugins/function.popup.php | 2 + .../smarty/plugins/function.popup_init.php | 1 + .../smarty/plugins/modifier.capitalize.php | 5 +- .../plugins/modifier.count_characters.php | 1 + .../plugins/modifier.count_paragraphs.php | 1 + .../plugins/modifier.count_sentences.php | 1 + .../smarty/plugins/modifier.count_words.php | 1 + .../smarty/plugins/modifier.date_format.php | 32 +- .../plugins/modifier.debug_print_var.php | 86 +- .../admin/smarty/plugins/modifier.default.php | 1 + .../admin/smarty/plugins/modifier.escape.php | 14 +- .../admin/smarty/plugins/modifier.indent.php | 1 + .../admin/smarty/plugins/modifier.lower.php | 1 + .../smarty/plugins/modifier.regex_replace.php | 23 +- .../admin/smarty/plugins/modifier.replace.php | 1 + .../admin/smarty/plugins/modifier.spacify.php | 1 + .../smarty/plugins/modifier.string_format.php | 1 + .../smarty/plugins/modifier.strip_tags.php | 1 + .../smarty/plugins/modifier.truncate.php | 21 +- .../admin/smarty/plugins/modifier.upper.php | 1 + .../smarty/plugins/modifier.wordwrap.php | 1 + .../plugins/outputfilter.trimwhitespace.php | 22 +- .../plugins/shared.escape_special_chars.php | 1 + .../smarty/plugins/shared.make_timestamp.php | 37 +- 55 files changed, 5226 insertions(+), 4879 deletions(-) diff --git a/code/web/public_php/admin/smarty/Config_File.class.php b/code/web/public_php/admin/smarty/Config_File.class.php index a7f61c9da..c25f2a0ea 100644 --- a/code/web/public_php/admin/smarty/Config_File.class.php +++ b/code/web/public_php/admin/smarty/Config_File.class.php @@ -1,389 +1,393 @@ - - * @access public - * @package Smarty - */ - -/* $Id: Config_File.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ - -/** - * Config file reading class - * @package Smarty - */ -class Config_File { - /**#@+ - * Options - * @var boolean - */ - /** - * Controls whether variables with the same name overwrite each other. - */ - var $overwrite = true; - - /** - * Controls whether config values of on/true/yes and off/false/no get - * converted to boolean values automatically. - */ - var $booleanize = true; - - /** - * Controls whether hidden config sections/vars are read from the file. - */ - var $read_hidden = true; - - /** - * Controls whether or not to fix mac or dos formatted newlines. - * If set to true, \r or \r\n will be changed to \n. - */ - var $fix_newlines = true; - /**#@-*/ - - /** @access private */ - var $_config_path = ""; - var $_config_data = array(); - /**#@-*/ - - /** - * Constructs a new config file class. - * - * @param string $config_path (optional) path to the config files - */ - function Config_File($config_path = NULL) - { - if (isset($config_path)) - $this->set_path($config_path); - } - - - /** - * Set the path where configuration files can be found. - * - * @param string $config_path path to the config files - */ - function set_path($config_path) - { - if (!empty($config_path)) { - if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { - $this->_trigger_error_msg("Bad config file path '$config_path'"); - return; - } - if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { - $config_path .= DIRECTORY_SEPARATOR; - } - - $this->_config_path = $config_path; - } - } - - - /** - * Retrieves config info based on the file, section, and variable name. - * - * @param string $file_name config file to get info for - * @param string $section_name (optional) section to get info for - * @param string $var_name (optional) variable to get info for - * @return string|array a value or array of values - */ - function &get($file_name, $section_name = NULL, $var_name = NULL) - { - if (empty($file_name)) { - $this->_trigger_error_msg('Empty config file name'); - return; - } else { - $file_name = $this->_config_path . $file_name; - if (!isset($this->_config_data[$file_name])) - $this->load_file($file_name, false); - } - - if (!empty($var_name)) { - if (empty($section_name)) { - return $this->_config_data[$file_name]["vars"][$var_name]; - } else { - if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) - return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; - else - return array(); - } - } else { - if (empty($section_name)) { - return (array)$this->_config_data[$file_name]["vars"]; - } else { - if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) - return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; - else - return array(); - } - } - } - - - /** - * Retrieves config info based on the key. - * - * @param $file_name string config key (filename/section/var) - * @return string|array same as get() - * @uses get() retrieves information from config file and returns it - */ - function &get_key($config_key) - { - list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); - $result = &$this->get($file_name, $section_name, $var_name); - return $result; - } - - /** - * Get all loaded config file names. - * - * @return array an array of loaded config file names - */ - function get_file_names() - { - return array_keys($this->_config_data); - } - - - /** - * Get all section names from a loaded file. - * - * @param string $file_name config file to get section names from - * @return array an array of section names from the specified file - */ - function get_section_names($file_name) - { - $file_name = $this->_config_path . $file_name; - if (!isset($this->_config_data[$file_name])) { - $this->_trigger_error_msg("Unknown config file '$file_name'"); - return; - } - - return array_keys($this->_config_data[$file_name]["sections"]); - } - - - /** - * Get all global or section variable names. - * - * @param string $file_name config file to get info for - * @param string $section_name (optional) section to get info for - * @return array an array of variables names from the specified file/section - */ - function get_var_names($file_name, $section = NULL) - { - if (empty($file_name)) { - $this->_trigger_error_msg('Empty config file name'); - return; - } else if (!isset($this->_config_data[$file_name])) { - $this->_trigger_error_msg("Unknown config file '$file_name'"); - return; - } - - if (empty($section)) - return array_keys($this->_config_data[$file_name]["vars"]); - else - return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); - } - - - /** - * Clear loaded config data for a certain file or all files. - * - * @param string $file_name file to clear config data for - */ - function clear($file_name = NULL) - { - if ($file_name === NULL) - $this->_config_data = array(); - else if (isset($this->_config_data[$file_name])) - $this->_config_data[$file_name] = array(); - } - - - /** - * Load a configuration file manually. - * - * @param string $file_name file name to load - * @param boolean $prepend_path whether current config path should be - * prepended to the filename - */ - function load_file($file_name, $prepend_path = true) - { - if ($prepend_path && $this->_config_path != "") - $config_file = $this->_config_path . $file_name; - else - $config_file = $file_name; - - ini_set('track_errors', true); - $fp = @fopen($config_file, "r"); - if (!is_resource($fp)) { - $this->_trigger_error_msg("Could not open config file '$config_file'"); - return false; - } - - $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; - fclose($fp); - - $this->_config_data[$config_file] = $this->parse_contents($contents); - return true; - } - - /** - * Store the contents of a file manually. - * - * @param string $config_file file name of the related contents - * @param string $contents the file-contents to parse - */ - function set_file_contents($config_file, $contents) - { - $this->_config_data[$config_file] = $this->parse_contents($contents); - return true; - } - - /** - * parse the source of a configuration file manually. - * - * @param string $contents the file-contents to parse - */ - function parse_contents($contents) - { - if($this->fix_newlines) { - // fix mac/dos formatted newlines - $contents = preg_replace('!\r\n?!', "\n", $contents); - } - - $config_data = array(); - $config_data['sections'] = array(); - $config_data['vars'] = array(); - - /* reference to fill with data */ - $vars =& $config_data['vars']; - - /* parse file line by line */ - preg_match_all('!^.*\r?\n?!m', $contents, $match); - $lines = $match[0]; - for ($i=0, $count=count($lines); $i<$count; $i++) { - $line = $lines[$i]; - if (empty($line)) continue; - - if ( $line{0} == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { - /* section found */ - if ($match[1]{0} == '.') { - /* hidden section */ - if ($this->read_hidden) { - $section_name = substr($match[1], 1); - } else { - /* break reference to $vars to ignore hidden section */ - unset($vars); - $vars = array(); - continue; - } - } else { - $section_name = $match[1]; - } - if (!isset($config_data['sections'][$section_name])) - $config_data['sections'][$section_name] = array('vars' => array()); - $vars =& $config_data['sections'][$section_name]['vars']; - continue; - } - - if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { - /* variable found */ - $var_name = rtrim($match[1]); - if (strpos($match[2], '"""') === 0) { - /* handle multiline-value */ - $lines[$i] = substr($match[2], 3); - $var_value = ''; - while ($i<$count) { - if (($pos = strpos($lines[$i], '"""')) === false) { - $var_value .= $lines[$i++]; - } else { - /* end of multiline-value */ - $var_value .= substr($lines[$i], 0, $pos); - break; - } - } - $booleanize = false; - - } else { - /* handle simple value */ - $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); - $booleanize = $this->booleanize; - - } - $this->_set_config_var($vars, $var_name, $var_value, $booleanize); - } - /* else unparsable line / means it is a comment / means ignore it */ - } - return $config_data; - } - - /**#@+ @access private */ - /** - * @param array &$container - * @param string $var_name - * @param mixed $var_value - * @param boolean $booleanize determines whether $var_value is converted to - * to true/false - */ - function _set_config_var(&$container, $var_name, $var_value, $booleanize) - { - if ($var_name{0} == '.') { - if (!$this->read_hidden) - return; - else - $var_name = substr($var_name, 1); - } - - if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { - $this->_trigger_error_msg("Bad variable name '$var_name'"); - return; - } - - if ($booleanize) { - if (preg_match("/^(on|true|yes)$/i", $var_value)) - $var_value = true; - else if (preg_match("/^(off|false|no)$/i", $var_value)) - $var_value = false; - } - - if (!isset($container[$var_name]) || $this->overwrite) - $container[$var_name] = $var_value; - else { - settype($container[$var_name], 'array'); - $container[$var_name][] = $var_value; - } - } - - /** - * @uses trigger_error() creates a PHP warning/error - * @param string $error_msg - * @param integer $error_type one of - */ - function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) - { - trigger_error("Config_File error: $error_msg", $error_type); - } - /**#@-*/ -} - -?> + + * @access public + * @package Smarty + */ + +/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */ + +/** + * Config file reading class + * @package Smarty + */ +class Config_File { + /**#@+ + * Options + * @var boolean + */ + /** + * Controls whether variables with the same name overwrite each other. + */ + var $overwrite = true; + + /** + * Controls whether config values of on/true/yes and off/false/no get + * converted to boolean values automatically. + */ + var $booleanize = true; + + /** + * Controls whether hidden config sections/vars are read from the file. + */ + var $read_hidden = true; + + /** + * Controls whether or not to fix mac or dos formatted newlines. + * If set to true, \r or \r\n will be changed to \n. + */ + var $fix_newlines = true; + /**#@-*/ + + /** @access private */ + var $_config_path = ""; + var $_config_data = array(); + /**#@-*/ + + /** + * Constructs a new config file class. + * + * @param string $config_path (optional) path to the config files + */ + function Config_File($config_path = NULL) + { + if (isset($config_path)) + $this->set_path($config_path); + } + + + /** + * Set the path where configuration files can be found. + * + * @param string $config_path path to the config files + */ + function set_path($config_path) + { + if (!empty($config_path)) { + if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { + $this->_trigger_error_msg("Bad config file path '$config_path'"); + return; + } + if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { + $config_path .= DIRECTORY_SEPARATOR; + } + + $this->_config_path = $config_path; + } + } + + + /** + * Retrieves config info based on the file, section, and variable name. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @param string $var_name (optional) variable to get info for + * @return string|array a value or array of values + */ + function get($file_name, $section_name = NULL, $var_name = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) + $this->load_file($file_name, false); + } + + if (!empty($var_name)) { + if (empty($section_name)) { + return $this->_config_data[$file_name]["vars"][$var_name]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) + return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; + else + return array(); + } + } else { + if (empty($section_name)) { + return (array)$this->_config_data[$file_name]["vars"]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) + return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; + else + return array(); + } + } + } + + + /** + * Retrieves config info based on the key. + * + * @param $file_name string config key (filename/section/var) + * @return string|array same as get() + * @uses get() retrieves information from config file and returns it + */ + function &get_key($config_key) + { + list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); + $result = &$this->get($file_name, $section_name, $var_name); + return $result; + } + + /** + * Get all loaded config file names. + * + * @return array an array of loaded config file names + */ + function get_file_names() + { + return array_keys($this->_config_data); + } + + + /** + * Get all section names from a loaded file. + * + * @param string $file_name config file to get section names from + * @return array an array of section names from the specified file + */ + function get_section_names($file_name) + { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + return array_keys($this->_config_data[$file_name]["sections"]); + } + + + /** + * Get all global or section variable names. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @return array an array of variables names from the specified file/section + */ + function get_var_names($file_name, $section = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + if (empty($section)) + return array_keys($this->_config_data[$file_name]["vars"]); + else + return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); + } + + + /** + * Clear loaded config data for a certain file or all files. + * + * @param string $file_name file to clear config data for + */ + function clear($file_name = NULL) + { + if ($file_name === NULL) + $this->_config_data = array(); + else if (isset($this->_config_data[$file_name])) + $this->_config_data[$file_name] = array(); + } + + + /** + * Load a configuration file manually. + * + * @param string $file_name file name to load + * @param boolean $prepend_path whether current config path should be + * prepended to the filename + */ + function load_file($file_name, $prepend_path = true) + { + if ($prepend_path && $this->_config_path != "") + $config_file = $this->_config_path . $file_name; + else + $config_file = $file_name; + + ini_set('track_errors', true); + $fp = @fopen($config_file, "r"); + if (!is_resource($fp)) { + $this->_trigger_error_msg("Could not open config file '$config_file'"); + return false; + } + + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; + fclose($fp); + + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * Store the contents of a file manually. + * + * @param string $config_file file name of the related contents + * @param string $contents the file-contents to parse + */ + function set_file_contents($config_file, $contents) + { + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * parse the source of a configuration file manually. + * + * @param string $contents the file-contents to parse + */ + function parse_contents($contents) + { + if($this->fix_newlines) { + // fix mac/dos formatted newlines + $contents = preg_replace('!\r\n?!', "\n", $contents); + } + + $config_data = array(); + $config_data['sections'] = array(); + $config_data['vars'] = array(); + + /* reference to fill with data */ + $vars =& $config_data['vars']; + + /* parse file line by line */ + preg_match_all('!^.*\r?\n?!m', $contents, $match); + $lines = $match[0]; + for ($i=0, $count=count($lines); $i<$count; $i++) { + $line = $lines[$i]; + if (empty($line)) continue; + + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { + /* section found */ + if (substr($match[1], 0, 1) == '.') { + /* hidden section */ + if ($this->read_hidden) { + $section_name = substr($match[1], 1); + } else { + /* break reference to $vars to ignore hidden section */ + unset($vars); + $vars = array(); + continue; + } + } else { + $section_name = $match[1]; + } + if (!isset($config_data['sections'][$section_name])) + $config_data['sections'][$section_name] = array('vars' => array()); + $vars =& $config_data['sections'][$section_name]['vars']; + continue; + } + + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { + /* variable found */ + $var_name = rtrim($match[1]); + if (strpos($match[2], '"""') === 0) { + /* handle multiline-value */ + $lines[$i] = substr($match[2], 3); + $var_value = ''; + while ($i<$count) { + if (($pos = strpos($lines[$i], '"""')) === false) { + $var_value .= $lines[$i++]; + } else { + /* end of multiline-value */ + $var_value .= substr($lines[$i], 0, $pos); + break; + } + } + $booleanize = false; + + } else { + /* handle simple value */ + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); + $booleanize = $this->booleanize; + + } + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); + } + /* else unparsable line / means it is a comment / means ignore it */ + } + return $config_data; + } + + /**#@+ @access private */ + /** + * @param array &$container + * @param string $var_name + * @param mixed $var_value + * @param boolean $booleanize determines whether $var_value is converted to + * to true/false + */ + function _set_config_var(&$container, $var_name, $var_value, $booleanize) + { + if (substr($var_name, 0, 1) == '.') { + if (!$this->read_hidden) + return; + else + $var_name = substr($var_name, 1); + } + + if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { + $this->_trigger_error_msg("Bad variable name '$var_name'"); + return; + } + + if ($booleanize) { + if (preg_match("/^(on|true|yes)$/i", $var_value)) + $var_value = true; + else if (preg_match("/^(off|false|no)$/i", $var_value)) + $var_value = false; + } + + if (!isset($container[$var_name]) || $this->overwrite) + $container[$var_name] = $var_value; + else { + settype($container[$var_name], 'array'); + $container[$var_name][] = $var_value; + } + } + + /** + * @uses trigger_error() creates a PHP warning/error + * @param string $error_msg + * @param integer $error_type one of + */ + function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Config_File error: $error_msg", $error_type); + } + /**#@-*/ +} + +?> diff --git a/code/web/public_php/admin/smarty/Smarty.class.php b/code/web/public_php/admin/smarty/Smarty.class.php index 40248fbd0..39eed5fc5 100644 --- a/code/web/public_php/admin/smarty/Smarty.class.php +++ b/code/web/public_php/admin/smarty/Smarty.class.php @@ -1,1934 +1,1962 @@ - - * @author Andrei Zmievski - * @package Smarty - * @version 2.6.9 - */ - -/* $Id: Smarty.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ - -/** - * DIR_SEP isn't used anymore, but third party apps might - */ -if(!defined('DIR_SEP')) { - define('DIR_SEP', DIRECTORY_SEPARATOR); -} - -/** - * set SMARTY_DIR to absolute path to Smarty library files. - * if not defined, include_path will be used. Sets SMARTY_DIR only if user - * application has not already defined it. - */ - -if (!defined('SMARTY_DIR')) { - define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); -} - -if (!defined('SMARTY_CORE_DIR')) { - define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); -} - -define('SMARTY_PHP_PASSTHRU', 0); -define('SMARTY_PHP_QUOTE', 1); -define('SMARTY_PHP_REMOVE', 2); -define('SMARTY_PHP_ALLOW', 3); - -/** - * @package Smarty - */ -class Smarty -{ - /**#@+ - * Smarty Configuration Section - */ - - /** - * The name of the directory where templates are located. - * - * @var string - */ - var $template_dir = 'templates'; - - /** - * The directory where compiled templates are located. - * - * @var string - */ - var $compile_dir = 'templates_c'; - - /** - * The directory where config files are located. - * - * @var string - */ - var $config_dir = 'configs'; - - /** - * An array of directories searched for plugins. - * - * @var array - */ - var $plugins_dir = array('plugins'); - - /** - * If debugging is enabled, a debug console window will display - * when the page loads (make sure your browser allows unrequested - * popup windows) - * - * @var boolean - */ - var $debugging = false; - - /** - * When set, smarty does uses this value as error_reporting-level. - * - * @var boolean - */ - var $error_reporting = null; - - /** - * This is the path to the debug console template. If not set, - * the default one will be used. - * - * @var string - */ - var $debug_tpl = ''; - - /** - * This determines if debugging is enable-able from the browser. - *
    - *
  • NONE => no debugging control allowed
  • - *
  • URL => enable debugging when SMARTY_DEBUG is found in the URL.
  • - *
- * @link http://www.foo.dom/index.php?SMARTY_DEBUG - * @var string - */ - var $debugging_ctrl = 'NONE'; - - /** - * This tells Smarty whether to check for recompiling or not. Recompiling - * does not need to happen unless a template or config file is changed. - * Typically you enable this during development, and disable for - * production. - * - * @var boolean - */ - var $compile_check = true; - - /** - * This forces templates to compile every time. Useful for development - * or debugging. - * - * @var boolean - */ - var $force_compile = false; - - /** - * This enables template caching. - *
    - *
  • 0 = no caching
  • - *
  • 1 = use class cache_lifetime value
  • - *
  • 2 = use cache_lifetime in cache file
  • - *
- * @var integer - */ - var $caching = 0; - - /** - * The name of the directory for cache files. - * - * @var string - */ - var $cache_dir = 'cache'; - - /** - * This is the number of seconds cached content will persist. - *
    - *
  • 0 = always regenerate cache
  • - *
  • -1 = never expires
  • - *
- * - * @var integer - */ - var $cache_lifetime = 3600; - - /** - * Only used when $caching is enabled. If true, then If-Modified-Since headers - * are respected with cached content, and appropriate HTTP headers are sent. - * This way repeated hits to a cached page do not send the entire page to the - * client every time. - * - * @var boolean - */ - var $cache_modified_check = false; - - /** - * This determines how Smarty handles "" tags in templates. - * possible values: - *
    - *
  • SMARTY_PHP_PASSTHRU -> print tags as plain text
  • - *
  • SMARTY_PHP_QUOTE -> escape tags as entities
  • - *
  • SMARTY_PHP_REMOVE -> remove php tags
  • - *
  • SMARTY_PHP_ALLOW -> execute php tags
  • - *
- * - * @var integer - */ - var $php_handling = SMARTY_PHP_PASSTHRU; - - /** - * This enables template security. When enabled, many things are restricted - * in the templates that normally would go unchecked. This is useful when - * untrusted parties are editing templates and you want a reasonable level - * of security. (no direct execution of PHP in templates for example) - * - * @var boolean - */ - var $security = false; - - /** - * This is the list of template directories that are considered secure. This - * is used only if {@link $security} is enabled. One directory per array - * element. {@link $template_dir} is in this list implicitly. - * - * @var array - */ - var $secure_dir = array(); - - /** - * These are the security settings for Smarty. They are used only when - * {@link $security} is enabled. - * - * @var array - */ - var $security_settings = array( - 'PHP_HANDLING' => false, - 'IF_FUNCS' => array('array', 'list', - 'isset', 'empty', - 'count', 'sizeof', - 'in_array', 'is_array', - 'true', 'false', 'null'), - 'INCLUDE_ANY' => false, - 'PHP_TAGS' => false, - 'MODIFIER_FUNCS' => array('count'), - 'ALLOW_CONSTANTS' => false - ); - - /** - * This is an array of directories where trusted php scripts reside. - * {@link $security} is disabled during their inclusion/execution. - * - * @var array - */ - var $trusted_dir = array(); - - /** - * The left delimiter used for the template tags. - * - * @var string - */ - var $left_delimiter = '{'; - - /** - * The right delimiter used for the template tags. - * - * @var string - */ - var $right_delimiter = '}'; - - /** - * The order in which request variables are registered, similar to - * variables_order in php.ini E = Environment, G = GET, P = POST, - * C = Cookies, S = Server - * - * @var string - */ - var $request_vars_order = 'EGPCS'; - - /** - * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) - * are uses as request-vars or $_*[]-vars. note: if - * request_use_auto_globals is true, then $request_vars_order has - * no effect, but the php-ini-value "gpc_order" - * - * @var boolean - */ - var $request_use_auto_globals = true; - - /** - * Set this if you want different sets of compiled files for the same - * templates. This is useful for things like different languages. - * Instead of creating separate sets of templates per language, you - * set different compile_ids like 'en' and 'de'. - * - * @var string - */ - var $compile_id = null; - - /** - * This tells Smarty whether or not to use sub dirs in the cache/ and - * templates_c/ directories. sub directories better organized, but - * may not work well with PHP safe mode enabled. - * - * @var boolean - * - */ - var $use_sub_dirs = false; - - /** - * This is a list of the modifiers to apply to all template variables. - * Put each modifier in a separate array element in the order you want - * them applied. example: array('escape:"htmlall"'); - * - * @var array - */ - var $default_modifiers = array(); - - /** - * This is the resource type to be used when not specified - * at the beginning of the resource path. examples: - * $smarty->display('file:index.tpl'); - * $smarty->display('db:index.tpl'); - * $smarty->display('index.tpl'); // will use default resource type - * {include file="file:index.tpl"} - * {include file="db:index.tpl"} - * {include file="index.tpl"} {* will use default resource type *} - * - * @var array - */ - var $default_resource_type = 'file'; - - /** - * The function used for cache file handling. If not set, built-in caching is used. - * - * @var null|string function name - */ - var $cache_handler_func = null; - - /** - * This indicates which filters are automatically loaded into Smarty. - * - * @var array array of filter names - */ - var $autoload_filters = array(); - - /**#@+ - * @var boolean - */ - /** - * This tells if config file vars of the same name overwrite each other or not. - * if disabled, same name variables are accumulated in an array. - */ - var $config_overwrite = true; - - /** - * This tells whether or not to automatically booleanize config file variables. - * If enabled, then the strings "on", "true", and "yes" are treated as boolean - * true, and "off", "false" and "no" are treated as boolean false. - */ - var $config_booleanize = true; - - /** - * This tells whether hidden sections [.foobar] are readable from the - * tempalates or not. Normally you would never allow this since that is - * the point behind hidden sections: the application can access them, but - * the templates cannot. - */ - var $config_read_hidden = false; - - /** - * This tells whether or not automatically fix newlines in config files. - * It basically converts \r (mac) or \r\n (dos) to \n - */ - var $config_fix_newlines = true; - /**#@-*/ - - /** - * If a template cannot be found, this PHP function will be executed. - * Useful for creating templates on-the-fly or other special action. - * - * @var string function name - */ - var $default_template_handler_func = ''; - - /** - * The file that contains the compiler class. This can a full - * pathname, or relative to the php_include path. - * - * @var string - */ - var $compiler_file = 'Smarty_Compiler.class.php'; - - /** - * The class used for compiling templates. - * - * @var string - */ - var $compiler_class = 'Smarty_Compiler'; - - /** - * The class used to load config vars. - * - * @var string - */ - var $config_class = 'Config_File'; - -/**#@+ - * END Smarty Configuration Section - * There should be no need to touch anything below this line. - * @access private - */ - /** - * where assigned template vars are kept - * - * @var array - */ - var $_tpl_vars = array(); - - /** - * stores run-time $smarty.* vars - * - * @var null|array - */ - var $_smarty_vars = null; - - /** - * keeps track of sections - * - * @var array - */ - var $_sections = array(); - - /** - * keeps track of foreach blocks - * - * @var array - */ - var $_foreach = array(); - - /** - * keeps track of tag hierarchy - * - * @var array - */ - var $_tag_stack = array(); - - /** - * configuration object - * - * @var Config_file - */ - var $_conf_obj = null; - - /** - * loaded configuration settings - * - * @var array - */ - var $_config = array(array('vars' => array(), 'files' => array())); - - /** - * md5 checksum of the string 'Smarty' - * - * @var string - */ - var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; - - /** - * Smarty version number - * - * @var string - */ - var $_version = '2.6.9'; - - /** - * current template inclusion depth - * - * @var integer - */ - var $_inclusion_depth = 0; - - /** - * for different compiled templates - * - * @var string - */ - var $_compile_id = null; - - /** - * text in URL to enable debug mode - * - * @var string - */ - var $_smarty_debug_id = 'SMARTY_DEBUG'; - - /** - * debugging information for debug console - * - * @var array - */ - var $_smarty_debug_info = array(); - - /** - * info that makes up a cache file - * - * @var array - */ - var $_cache_info = array(); - - /** - * default file permissions - * - * @var integer - */ - var $_file_perms = 0644; - - /** - * default dir permissions - * - * @var integer - */ - var $_dir_perms = 0771; - - /** - * registered objects - * - * @var array - */ - var $_reg_objects = array(); - - /** - * table keeping track of plugins - * - * @var array - */ - var $_plugins = array( - 'modifier' => array(), - 'function' => array(), - 'block' => array(), - 'compiler' => array(), - 'prefilter' => array(), - 'postfilter' => array(), - 'outputfilter' => array(), - 'resource' => array(), - 'insert' => array()); - - - /** - * cache serials - * - * @var array - */ - var $_cache_serials = array(); - - /** - * name of optional cache include file - * - * @var string - */ - var $_cache_include = null; - - /** - * indicate if the current code is used in a compiled - * include - * - * @var string - */ - var $_cache_including = false; - - /**#@-*/ - /** - * The class constructor. - */ - function Smarty() - { - $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] - : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); - } - - /** - * assigns values to template variables - * - * @param array|string $tpl_var the template variable name(s) - * @param mixed $value the value to assign - */ - function assign($tpl_var, $value = null) - { - if (is_array($tpl_var)){ - foreach ($tpl_var as $key => $val) { - if ($key != '') { - $this->_tpl_vars[$key] = $val; - } - } - } else { - if ($tpl_var != '') - $this->_tpl_vars[$tpl_var] = $value; - } - } - - /** - * assigns values to template variables by reference - * - * @param string $tpl_var the template variable name - * @param mixed $value the referenced value to assign - */ - function assign_by_ref($tpl_var, &$value) - { - if ($tpl_var != '') - $this->_tpl_vars[$tpl_var] = &$value; - } - - /** - * appends values to template variables - * - * @param array|string $tpl_var the template variable name(s) - * @param mixed $value the value to append - */ - function append($tpl_var, $value=null, $merge=false) - { - if (is_array($tpl_var)) { - // $tpl_var is an array, ignore $value - foreach ($tpl_var as $_key => $_val) { - if ($_key != '') { - if(!@is_array($this->_tpl_vars[$_key])) { - settype($this->_tpl_vars[$_key],'array'); - } - if($merge && is_array($_val)) { - foreach($_val as $_mkey => $_mval) { - $this->_tpl_vars[$_key][$_mkey] = $_mval; - } - } else { - $this->_tpl_vars[$_key][] = $_val; - } - } - } - } else { - if ($tpl_var != '' && isset($value)) { - if(!@is_array($this->_tpl_vars[$tpl_var])) { - settype($this->_tpl_vars[$tpl_var],'array'); - } - if($merge && is_array($value)) { - foreach($value as $_mkey => $_mval) { - $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; - } - } else { - $this->_tpl_vars[$tpl_var][] = $value; - } - } - } - } - - /** - * appends values to template variables by reference - * - * @param string $tpl_var the template variable name - * @param mixed $value the referenced value to append - */ - function append_by_ref($tpl_var, &$value, $merge=false) - { - if ($tpl_var != '' && isset($value)) { - if(!@is_array($this->_tpl_vars[$tpl_var])) { - settype($this->_tpl_vars[$tpl_var],'array'); - } - if ($merge && is_array($value)) { - foreach($value as $_key => $_val) { - $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; - } - } else { - $this->_tpl_vars[$tpl_var][] = &$value; - } - } - } - - - /** - * clear the given assigned template variable. - * - * @param string $tpl_var the template variable to clear - */ - function clear_assign($tpl_var) - { - if (is_array($tpl_var)) - foreach ($tpl_var as $curr_var) - unset($this->_tpl_vars[$curr_var]); - else - unset($this->_tpl_vars[$tpl_var]); - } - - - /** - * Registers custom function to be used in templates - * - * @param string $function the name of the template function - * @param string $function_impl the name of the PHP function to register - */ - function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) - { - $this->_plugins['function'][$function] = - array($function_impl, null, null, false, $cacheable, $cache_attrs); - - } - - /** - * Unregisters custom function - * - * @param string $function name of template function - */ - function unregister_function($function) - { - unset($this->_plugins['function'][$function]); - } - - /** - * Registers object to be used in templates - * - * @param string $object name of template object - * @param object &$object_impl the referenced PHP object to register - * @param null|array $allowed list of allowed methods (empty = all) - * @param boolean $smarty_args smarty argument format, else traditional - * @param null|array $block_functs list of methods that are block format - */ - function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) - { - settype($allowed, 'array'); - settype($smarty_args, 'boolean'); - $this->_reg_objects[$object] = - array(&$object_impl, $allowed, $smarty_args, $block_methods); - } - - /** - * Unregisters object - * - * @param string $object name of template object - */ - function unregister_object($object) - { - unset($this->_reg_objects[$object]); - } - - - /** - * Registers block function to be used in templates - * - * @param string $block name of template block - * @param string $block_impl PHP function to register - */ - function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) - { - $this->_plugins['block'][$block] = - array($block_impl, null, null, false, $cacheable, $cache_attrs); - } - - /** - * Unregisters block function - * - * @param string $block name of template function - */ - function unregister_block($block) - { - unset($this->_plugins['block'][$block]); - } - - /** - * Registers compiler function - * - * @param string $function name of template function - * @param string $function_impl name of PHP function to register - */ - function register_compiler_function($function, $function_impl, $cacheable=true) - { - $this->_plugins['compiler'][$function] = - array($function_impl, null, null, false, $cacheable); - } - - /** - * Unregisters compiler function - * - * @param string $function name of template function - */ - function unregister_compiler_function($function) - { - unset($this->_plugins['compiler'][$function]); - } - - /** - * Registers modifier to be used in templates - * - * @param string $modifier name of template modifier - * @param string $modifier_impl name of PHP function to register - */ - function register_modifier($modifier, $modifier_impl) - { - $this->_plugins['modifier'][$modifier] = - array($modifier_impl, null, null, false); - } - - /** - * Unregisters modifier - * - * @param string $modifier name of template modifier - */ - function unregister_modifier($modifier) - { - unset($this->_plugins['modifier'][$modifier]); - } - - /** - * Registers a resource to fetch a template - * - * @param string $type name of resource - * @param array $functions array of functions to handle resource - */ - function register_resource($type, $functions) - { - if (count($functions)==4) { - $this->_plugins['resource'][$type] = - array($functions, false); - - } elseif (count($functions)==5) { - $this->_plugins['resource'][$type] = - array(array(array(&$functions[0], $functions[1]) - ,array(&$functions[0], $functions[2]) - ,array(&$functions[0], $functions[3]) - ,array(&$functions[0], $functions[4])) - ,false); - - } else { - $this->trigger_error("malformed function-list for '$type' in register_resource"); - - } - } - - /** - * Unregisters a resource - * - * @param string $type name of resource - */ - function unregister_resource($type) - { - unset($this->_plugins['resource'][$type]); - } - - /** - * Registers a prefilter function to apply - * to a template before compiling - * - * @param string $function name of PHP function to register - */ - function register_prefilter($function) - { - $_name = (is_array($function)) ? $function[1] : $function; - $this->_plugins['prefilter'][$_name] - = array($function, null, null, false); - } - - /** - * Unregisters a prefilter function - * - * @param string $function name of PHP function - */ - function unregister_prefilter($function) - { - unset($this->_plugins['prefilter'][$function]); - } - - /** - * Registers a postfilter function to apply - * to a compiled template after compilation - * - * @param string $function name of PHP function to register - */ - function register_postfilter($function) - { - $_name = (is_array($function)) ? $function[1] : $function; - $this->_plugins['postfilter'][$_name] - = array($function, null, null, false); - } - - /** - * Unregisters a postfilter function - * - * @param string $function name of PHP function - */ - function unregister_postfilter($function) - { - unset($this->_plugins['postfilter'][$function]); - } - - /** - * Registers an output filter function to apply - * to a template output - * - * @param string $function name of PHP function - */ - function register_outputfilter($function) - { - $_name = (is_array($function)) ? $function[1] : $function; - $this->_plugins['outputfilter'][$_name] - = array($function, null, null, false); - } - - /** - * Unregisters an outputfilter function - * - * @param string $function name of PHP function - */ - function unregister_outputfilter($function) - { - unset($this->_plugins['outputfilter'][$function]); - } - - /** - * load a filter of specified type and name - * - * @param string $type filter type - * @param string $name filter name - */ - function load_filter($type, $name) - { - switch ($type) { - case 'output': - $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - break; - - case 'pre': - case 'post': - if (!isset($this->_plugins[$type . 'filter'][$name])) - $this->_plugins[$type . 'filter'][$name] = false; - break; - } - } - - /** - * clear cached content for the given template and cache id - * - * @param string $tpl_file name of template file - * @param string $cache_id name of cache_id - * @param string $compile_id name of compile_id - * @param string $exp_time expiration time - * @return boolean - */ - function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) - { - - if (!isset($compile_id)) - $compile_id = $this->compile_id; - - if (!isset($tpl_file)) - $compile_id = null; - - $_auto_id = $this->_get_auto_id($cache_id, $compile_id); - - if (!empty($this->cache_handler_func)) { - return call_user_func_array($this->cache_handler_func, - array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); - } else { - $_params = array('auto_base' => $this->cache_dir, - 'auto_source' => $tpl_file, - 'auto_id' => $_auto_id, - 'exp_time' => $exp_time); - require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); - return smarty_core_rm_auto($_params, $this); - } - - } - - - /** - * clear the entire contents of cache (all templates) - * - * @param string $exp_time expire time - * @return boolean results of {@link smarty_core_rm_auto()} - */ - function clear_all_cache($exp_time = null) - { - return $this->clear_cache(null, null, null, $exp_time); - } - - - /** - * test to see if valid cache exists for this template - * - * @param string $tpl_file name of template file - * @param string $cache_id - * @param string $compile_id - * @return string|false results of {@link _read_cache_file()} - */ - function is_cached($tpl_file, $cache_id = null, $compile_id = null) - { - if (!$this->caching) - return false; - - if (!isset($compile_id)) - $compile_id = $this->compile_id; - - $_params = array( - 'tpl_file' => $tpl_file, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id - ); - require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); - return smarty_core_read_cache_file($_params, $this); - } - - - /** - * clear all the assigned template variables. - * - */ - function clear_all_assign() - { - $this->_tpl_vars = array(); - } - - /** - * clears compiled version of specified template resource, - * or all compiled template files if one is not specified. - * This function is for advanced use only, not normally needed. - * - * @param string $tpl_file - * @param string $compile_id - * @param string $exp_time - * @return boolean results of {@link smarty_core_rm_auto()} - */ - function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) - { - if (!isset($compile_id)) { - $compile_id = $this->compile_id; - } - $_params = array('auto_base' => $this->compile_dir, - 'auto_source' => $tpl_file, - 'auto_id' => $compile_id, - 'exp_time' => $exp_time, - 'extensions' => array('.inc', '.php')); - require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); - return smarty_core_rm_auto($_params, $this); - } - - /** - * Checks whether requested template exists. - * - * @param string $tpl_file - * @return boolean - */ - function template_exists($tpl_file) - { - $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); - return $this->_fetch_resource_info($_params); - } - - /** - * Returns an array containing template variables - * - * @param string $name - * @param string $type - * @return array - */ - function &get_template_vars($name=null) - { - if(!isset($name)) { - return $this->_tpl_vars; - } - if(isset($this->_tpl_vars[$name])) { - return $this->_tpl_vars[$name]; - } - } - - /** - * Returns an array containing config variables - * - * @param string $name - * @param string $type - * @return array - */ - function &get_config_vars($name=null) - { - if(!isset($name) && is_array($this->_config[0])) { - return $this->_config[0]['vars']; - } else if(isset($this->_config[0]['vars'][$name])) { - return $this->_config[0]['vars'][$name]; - } - } - - /** - * trigger Smarty error - * - * @param string $error_msg - * @param integer $error_type - */ - function trigger_error($error_msg, $error_type = E_USER_WARNING) - { - trigger_error("Smarty error: $error_msg", $error_type); - } - - - /** - * executes & displays the template results - * - * @param string $resource_name - * @param string $cache_id - * @param string $compile_id - */ - function display($resource_name, $cache_id = null, $compile_id = null) - { - $this->fetch($resource_name, $cache_id, $compile_id, true); - } - - /** - * executes & returns or displays the template results - * - * @param string $resource_name - * @param string $cache_id - * @param string $compile_id - * @param boolean $display - */ - function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) - { - static $_cache_info = array(); - - $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) - ? $this->error_reporting : error_reporting() & ~E_NOTICE); - - if (!$this->debugging && $this->debugging_ctrl == 'URL') { - $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; - if (@strstr($_query_string, $this->_smarty_debug_id)) { - if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { - // enable debugging for this browser session - @setcookie('SMARTY_DEBUG', true); - $this->debugging = true; - } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { - // disable debugging for this browser session - @setcookie('SMARTY_DEBUG', false); - $this->debugging = false; - } else { - // enable debugging for this page - $this->debugging = true; - } - } else { - $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); - } - } - - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $_debug_start_time = smarty_core_get_microtime($_params, $this); - $this->_smarty_debug_info[] = array('type' => 'template', - 'filename' => $resource_name, - 'depth' => 0); - $_included_tpls_idx = count($this->_smarty_debug_info) - 1; - } - - if (!isset($compile_id)) { - $compile_id = $this->compile_id; - } - - $this->_compile_id = $compile_id; - $this->_inclusion_depth = 0; - - if ($this->caching) { - // save old cache_info, initialize cache_info - array_push($_cache_info, $this->_cache_info); - $this->_cache_info = array(); - $_params = array( - 'tpl_file' => $resource_name, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id, - 'results' => null - ); - require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); - if (smarty_core_read_cache_file($_params, $this)) { - $_smarty_results = $_params['results']; - if (!empty($this->_cache_info['insert_tags'])) { - $_params = array('plugins' => $this->_cache_info['insert_tags']); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - $_params = array('results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); - $_smarty_results = smarty_core_process_cached_inserts($_params, $this); - } - if (!empty($this->_cache_info['cache_serials'])) { - $_params = array('results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); - $_smarty_results = smarty_core_process_compiled_include($_params, $this); - } - - - if ($display) { - if ($this->debugging) - { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; - require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); - $_smarty_results .= smarty_core_display_debug_console($_params, $this); - } - if ($this->cache_modified_check) { - $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; - $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); - $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; - if (@count($this->_cache_info['insert_tags']) == 0 - && !$this->_cache_serials - && $_gmt_mtime == $_last_modified_date) { - if (php_sapi_name()=='cgi') - header('Status: 304 Not Modified'); - else - header('HTTP/1.1 304 Not Modified'); - - } else { - header('Last-Modified: '.$_gmt_mtime); - echo $_smarty_results; - } - } else { - echo $_smarty_results; - } - error_reporting($_smarty_old_error_level); - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - return true; - } else { - error_reporting($_smarty_old_error_level); - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - return $_smarty_results; - } - } else { - $this->_cache_info['template'][$resource_name] = true; - if ($this->cache_modified_check && $display) { - header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); - } - } - } - - // load filters that are marked as autoload - if (count($this->autoload_filters)) { - foreach ($this->autoload_filters as $_filter_type => $_filters) { - foreach ($_filters as $_filter) { - $this->load_filter($_filter_type, $_filter); - } - } - } - - $_smarty_compile_path = $this->_get_compile_path($resource_name); - - // if we just need to display the results, don't perform output - // buffering - for speed - $_cache_including = $this->_cache_including; - $this->_cache_including = false; - if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { - if ($this->_is_compiled($resource_name, $_smarty_compile_path) - || $this->_compile_resource($resource_name, $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - } else { - ob_start(); - if ($this->_is_compiled($resource_name, $_smarty_compile_path) - || $this->_compile_resource($resource_name, $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - $_smarty_results = ob_get_contents(); - ob_end_clean(); - - foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { - $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); - } - } - - if ($this->caching) { - $_params = array('tpl_file' => $resource_name, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id, - 'results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); - smarty_core_write_cache_file($_params, $this); - require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); - $_smarty_results = smarty_core_process_cached_inserts($_params, $this); - - if ($this->_cache_serials) { - // strip nocache-tags from output - $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' - ,'' - ,$_smarty_results); - } - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - } - $this->_cache_including = $_cache_including; - - if ($display) { - if (isset($_smarty_results)) { echo $_smarty_results; } - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); - require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); - echo smarty_core_display_debug_console($_params, $this); - } - error_reporting($_smarty_old_error_level); - return; - } else { - error_reporting($_smarty_old_error_level); - if (isset($_smarty_results)) { return $_smarty_results; } - } - } - - /** - * load configuration values - * - * @param string $file - * @param string $section - * @param string $scope - */ - function config_load($file, $section = null, $scope = 'global') - { - require_once($this->_get_plugin_filepath('function', 'config_load')); - smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); - } - - /** - * return a reference to a registered object - * - * @param string $name - * @return object - */ - function &get_registered_object($name) { - if (!isset($this->_reg_objects[$name])) - $this->_trigger_fatal_error("'$name' is not a registered object"); - - if (!is_object($this->_reg_objects[$name][0])) - $this->_trigger_fatal_error("registered '$name' is not an object"); - - return $this->_reg_objects[$name][0]; - } - - /** - * clear configuration values - * - * @param string $var - */ - function clear_config($var = null) - { - if(!isset($var)) { - // clear all values - $this->_config = array(array('vars' => array(), - 'files' => array())); - } else { - unset($this->_config[0]['vars'][$var]); - } - } - - /** - * get filepath of requested plugin - * - * @param string $type - * @param string $name - * @return string|false - */ - function _get_plugin_filepath($type, $name) - { - $_params = array('type' => $type, 'name' => $name); - require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); - return smarty_core_assemble_plugin_filepath($_params, $this); - } - - /** - * test if resource needs compiling - * - * @param string $resource_name - * @param string $compile_path - * @return boolean - */ - function _is_compiled($resource_name, $compile_path) - { - if (!$this->force_compile && file_exists($compile_path)) { - if (!$this->compile_check) { - // no need to check compiled file - return true; - } else { - // get file source and timestamp - $_params = array('resource_name' => $resource_name, 'get_source'=>false); - if (!$this->_fetch_resource_info($_params)) { - return false; - } - if ($_params['resource_timestamp'] <= filemtime($compile_path)) { - // template not expired, no recompile - return true; - } else { - // compile template - return false; - } - } - } else { - // compiled template does not exist, or forced compile - return false; - } - } - - /** - * compile the template - * - * @param string $resource_name - * @param string $compile_path - * @return boolean - */ - function _compile_resource($resource_name, $compile_path) - { - - $_params = array('resource_name' => $resource_name); - if (!$this->_fetch_resource_info($_params)) { - return false; - } - - $_source_content = $_params['source_content']; - $_cache_include = substr($compile_path, 0, -4).'.inc'; - - if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { - // if a _cache_serial was set, we also have to write an include-file: - if ($this->_cache_include_info) { - require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); - smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); - } - - $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); - require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); - smarty_core_write_compiled_resource($_params, $this); - - return true; - } else { - return false; - } - - } - - /** - * compile the given source - * - * @param string $resource_name - * @param string $source_content - * @param string $compiled_content - * @return boolean - */ - function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) - { - if (file_exists(SMARTY_DIR . $this->compiler_file)) { - require_once(SMARTY_DIR . $this->compiler_file); - } else { - // use include_path - require_once($this->compiler_file); - } - - - $smarty_compiler = new $this->compiler_class; - - $smarty_compiler->template_dir = $this->template_dir; - $smarty_compiler->compile_dir = $this->compile_dir; - $smarty_compiler->plugins_dir = $this->plugins_dir; - $smarty_compiler->config_dir = $this->config_dir; - $smarty_compiler->force_compile = $this->force_compile; - $smarty_compiler->caching = $this->caching; - $smarty_compiler->php_handling = $this->php_handling; - $smarty_compiler->left_delimiter = $this->left_delimiter; - $smarty_compiler->right_delimiter = $this->right_delimiter; - $smarty_compiler->_version = $this->_version; - $smarty_compiler->security = $this->security; - $smarty_compiler->secure_dir = $this->secure_dir; - $smarty_compiler->security_settings = $this->security_settings; - $smarty_compiler->trusted_dir = $this->trusted_dir; - $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; - $smarty_compiler->_reg_objects = &$this->_reg_objects; - $smarty_compiler->_plugins = &$this->_plugins; - $smarty_compiler->_tpl_vars = &$this->_tpl_vars; - $smarty_compiler->default_modifiers = $this->default_modifiers; - $smarty_compiler->compile_id = $this->_compile_id; - $smarty_compiler->_config = $this->_config; - $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; - - if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { - $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; - } - $smarty_compiler->_cache_include = $cache_include_path; - - - $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); - - if ($smarty_compiler->_cache_serial) { - $this->_cache_include_info = array( - 'cache_serial'=>$smarty_compiler->_cache_serial - ,'plugins_code'=>$smarty_compiler->_plugins_code - ,'include_file_path' => $cache_include_path); - - } else { - $this->_cache_include_info = null; - - } - - return $_results; - } - - /** - * Get the compile path for this resource - * - * @param string $resource_name - * @return string results of {@link _get_auto_filename()} - */ - function _get_compile_path($resource_name) - { - return $this->_get_auto_filename($this->compile_dir, $resource_name, - $this->_compile_id) . '.php'; - } - - /** - * fetch the template info. Gets timestamp, and source - * if get_source is true - * - * sets $source_content to the source of the template, and - * $resource_timestamp to its time stamp - * @param string $resource_name - * @param string $source_content - * @param integer $resource_timestamp - * @param boolean $get_source - * @param boolean $quiet - * @return boolean - */ - - function _fetch_resource_info(&$params) - { - if(!isset($params['get_source'])) { $params['get_source'] = true; } - if(!isset($params['quiet'])) { $params['quiet'] = false; } - - $_return = false; - $_params = array('resource_name' => $params['resource_name']) ; - if (isset($params['resource_base_path'])) - $_params['resource_base_path'] = $params['resource_base_path']; - else - $_params['resource_base_path'] = $this->template_dir; - - if ($this->_parse_resource_name($_params)) { - $_resource_type = $_params['resource_type']; - $_resource_name = $_params['resource_name']; - switch ($_resource_type) { - case 'file': - if ($params['get_source']) { - $params['source_content'] = $this->_read_file($_resource_name); - } - $params['resource_timestamp'] = filemtime($_resource_name); - $_return = is_file($_resource_name); - break; - - default: - // call resource functions to fetch the template source and timestamp - if ($params['get_source']) { - $_source_return = isset($this->_plugins['resource'][$_resource_type]) && - call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], - array($_resource_name, &$params['source_content'], &$this)); - } else { - $_source_return = true; - } - - $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && - call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], - array($_resource_name, &$params['resource_timestamp'], &$this)); - - $_return = $_source_return && $_timestamp_return; - break; - } - } - - if (!$_return) { - // see if we can get a template with the default template handler - if (!empty($this->default_template_handler_func)) { - if (!is_callable($this->default_template_handler_func)) { - $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); - } else { - $_return = call_user_func_array( - $this->default_template_handler_func, - array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); - } - } - } - - if (!$_return) { - if (!$params['quiet']) { - $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); - } - } else if ($_return && $this->security) { - require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); - if (!smarty_core_is_secure($_params, $this)) { - if (!$params['quiet']) - $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); - $params['source_content'] = null; - $params['resource_timestamp'] = null; - return false; - } - } - return $_return; - } - - - /** - * parse out the type and name from the resource - * - * @param string $resource_base_path - * @param string $resource_name - * @param string $resource_type - * @param string $resource_name - * @return boolean - */ - - function _parse_resource_name(&$params) - { - - // split tpl_path by the first colon - $_resource_name_parts = explode(':', $params['resource_name'], 2); - - if (count($_resource_name_parts) == 1) { - // no resource type given - $params['resource_type'] = $this->default_resource_type; - $params['resource_name'] = $_resource_name_parts[0]; - } else { - if(strlen($_resource_name_parts[0]) == 1) { - // 1 char is not resource type, but part of filepath - $params['resource_type'] = $this->default_resource_type; - $params['resource_name'] = $params['resource_name']; - } else { - $params['resource_type'] = $_resource_name_parts[0]; - $params['resource_name'] = $_resource_name_parts[1]; - } - } - - if ($params['resource_type'] == 'file') { - if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { - // relative pathname to $params['resource_base_path'] - // use the first directory where the file is found - foreach ((array)$params['resource_base_path'] as $_curr_path) { - $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; - if (file_exists($_fullpath) && is_file($_fullpath)) { - $params['resource_name'] = $_fullpath; - return true; - } - // didn't find the file, try include_path - $_params = array('file_path' => $_fullpath); - require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); - if(smarty_core_get_include_path($_params, $this)) { - $params['resource_name'] = $_params['new_file_path']; - return true; - } - } - return false; - } else { - /* absolute path */ - return file_exists($params['resource_name']); - } - } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { - $_params = array('type' => $params['resource_type']); - require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); - smarty_core_load_resource_plugin($_params, $this); - } - - return true; - } - - - /** - * Handle modifiers - * - * @param string|null $modifier_name - * @param array|null $map_array - * @return string result of modifiers - */ - function _run_mod_handler() - { - $_args = func_get_args(); - list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); - list($_func_name, $_tpl_file, $_tpl_line) = - $this->_plugins['modifier'][$_modifier_name]; - - $_var = $_args[0]; - foreach ($_var as $_key => $_val) { - $_args[0] = $_val; - $_var[$_key] = call_user_func_array($_func_name, $_args); - } - return $_var; - } - - /** - * Remove starting and ending quotes from the string - * - * @param string $string - * @return string - */ - function _dequote($string) - { - if (($string{0} == "'" || $string{0} == '"') && - $string{strlen($string)-1} == $string{0}) - return substr($string, 1, -1); - else - return $string; - } - - - /** - * read in a file - * - * @param string $filename - * @return string - */ - function _read_file($filename) - { - if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { - $contents = ($size = filesize($filename)) ? fread($fd, $size) : ''; - fclose($fd); - return $contents; - } else { - return false; - } - } - - /** - * get a concrete filename for automagically created content - * - * @param string $auto_base - * @param string $auto_source - * @param string $auto_id - * @return string - * @staticvar string|null - * @staticvar string|null - */ - function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) - { - $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; - $_return = $auto_base . DIRECTORY_SEPARATOR; - - if(isset($auto_id)) { - // make auto_id safe for directory names - $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); - // split into separate directories - $_return .= $auto_id . $_compile_dir_sep; - } - - if(isset($auto_source)) { - // make source name safe for filename - $_filename = urlencode(basename($auto_source)); - $_crc32 = sprintf('%08X', crc32($auto_source)); - // prepend %% to avoid name conflicts with - // with $params['auto_id'] names - $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . - substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; - $_return .= '%%' . $_crc32 . '%%' . $_filename; - } - - return $_return; - } - - /** - * unlink a file, possibly using expiration time - * - * @param string $resource - * @param integer $exp_time - */ - function _unlink($resource, $exp_time = null) - { - if(isset($exp_time)) { - if(time() - @filemtime($resource) >= $exp_time) { - return @unlink($resource); - } - } else { - return @unlink($resource); - } - } - - /** - * returns an auto_id for auto-file-functions - * - * @param string $cache_id - * @param string $compile_id - * @return string|null - */ - function _get_auto_id($cache_id=null, $compile_id=null) { - if (isset($cache_id)) - return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; - elseif(isset($compile_id)) - return $compile_id; - else - return null; - } - - /** - * trigger Smarty plugin error - * - * @param string $error_msg - * @param string $tpl_file - * @param integer $tpl_line - * @param string $file - * @param integer $line - * @param integer $error_type - */ - function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, - $file = null, $line = null, $error_type = E_USER_ERROR) - { - if(isset($file) && isset($line)) { - $info = ' ('.basename($file).", line $line)"; - } else { - $info = ''; - } - if (isset($tpl_line) && isset($tpl_file)) { - $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); - } else { - $this->trigger_error($error_msg . $info, $error_type); - } - } - - - /** - * callback function for preg_replace, to call a non-cacheable block - * @return string - */ - function _process_compiled_include_callback($match) { - $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; - ob_start(); - $_func($this); - $_ret = ob_get_contents(); - ob_end_clean(); - return $_ret; - } - - - /** - * called for included templates - * - * @param string $_smarty_include_tpl_file - * @param string $_smarty_include_vars - */ - - // $_smarty_include_tpl_file, $_smarty_include_vars - - function _smarty_include($params) - { - if ($this->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $debug_start_time = smarty_core_get_microtime($_params, $this); - $this->_smarty_debug_info[] = array('type' => 'template', - 'filename' => $params['smarty_include_tpl_file'], - 'depth' => ++$this->_inclusion_depth); - $included_tpls_idx = count($this->_smarty_debug_info) - 1; - } - - $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); - - // config vars are treated as local, so push a copy of the - // current ones onto the front of the stack - array_unshift($this->_config, $this->_config[0]); - - $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); - - - if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) - || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - - // pop the local vars off the front of the stack - array_shift($this->_config); - - $this->_inclusion_depth--; - - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; - } - - if ($this->caching) { - $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; - } - } - - - /** - * get or set an array of cached attributes for function that is - * not cacheable - * @return array - */ - function &_smarty_cache_attrs($cache_serial, $count) { - $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; - - if ($this->_cache_including) { - /* return next set of cache_attrs */ - $_return =& current($_cache_attrs); - next($_cache_attrs); - return $_return; - - } else { - /* add a reference to a new set of cache_attrs */ - $_cache_attrs[] = array(); - return $_cache_attrs[count($_cache_attrs)-1]; - - } - - } - - - /** - * wrapper for include() retaining $this - * @return mixed - */ - function _include($filename, $once=false, $params=null) - { - if ($once) { - return include_once($filename); - } else { - return include($filename); - } - } - - - /** - * wrapper for eval() retaining $this - * @return mixed - */ - function _eval($code, $params=null) - { - return eval($code); - } - /**#@-*/ - -} - -/* vim: set expandtab: */ - -?> + + * @author Andrei Zmievski + * @package Smarty + * @version 2.6.28 + */ + +/* $Id: Smarty.class.php 4660 2012-09-24 20:05:15Z uwe.tews@googlemail.com $ */ + +/** + * DIR_SEP isn't used anymore, but third party apps might + */ +if(!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user + * application has not already defined it. + */ + +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); +} + +if (!defined('SMARTY_CORE_DIR')) { + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +} + +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +/** + * @package Smarty + */ +class Smarty +{ + /**#@+ + * Smarty Configuration Section + */ + + /** + * The name of the directory where templates are located. + * + * @var string + */ + var $template_dir = 'templates'; + + /** + * The directory where compiled templates are located. + * + * @var string + */ + var $compile_dir = 'templates_c'; + + /** + * The directory where config files are located. + * + * @var string + */ + var $config_dir = 'configs'; + + /** + * An array of directories searched for plugins. + * + * @var array + */ + var $plugins_dir = array('plugins'); + + /** + * If debugging is enabled, a debug console window will display + * when the page loads (make sure your browser allows unrequested + * popup windows) + * + * @var boolean + */ + var $debugging = false; + + /** + * When set, smarty does uses this value as error_reporting-level. + * + * @var integer + */ + var $error_reporting = null; + + /** + * This is the path to the debug console template. If not set, + * the default one will be used. + * + * @var string + */ + var $debug_tpl = ''; + + /** + * This determines if debugging is enable-able from the browser. + *
    + *
  • NONE => no debugging control allowed
  • + *
  • URL => enable debugging when SMARTY_DEBUG is found in the URL.
  • + *
+ * @link http://www.foo.dom/index.php?SMARTY_DEBUG + * @var string + */ + var $debugging_ctrl = 'NONE'; + + /** + * This tells Smarty whether to check for recompiling or not. Recompiling + * does not need to happen unless a template or config file is changed. + * Typically you enable this during development, and disable for + * production. + * + * @var boolean + */ + var $compile_check = true; + + /** + * This forces templates to compile every time. Useful for development + * or debugging. + * + * @var boolean + */ + var $force_compile = false; + + /** + * This enables template caching. + *
    + *
  • 0 = no caching
  • + *
  • 1 = use class cache_lifetime value
  • + *
  • 2 = use cache_lifetime in cache file
  • + *
+ * @var integer + */ + var $caching = 0; + + /** + * The name of the directory for cache files. + * + * @var string + */ + var $cache_dir = 'cache'; + + /** + * This is the number of seconds cached content will persist. + *
    + *
  • 0 = always regenerate cache
  • + *
  • -1 = never expires
  • + *
+ * + * @var integer + */ + var $cache_lifetime = 3600; + + /** + * Only used when $caching is enabled. If true, then If-Modified-Since headers + * are respected with cached content, and appropriate HTTP headers are sent. + * This way repeated hits to a cached page do not send the entire page to the + * client every time. + * + * @var boolean + */ + var $cache_modified_check = false; + + /** + * This determines how Smarty handles "" tags in templates. + * possible values: + *
    + *
  • SMARTY_PHP_PASSTHRU -> print tags as plain text
  • + *
  • SMARTY_PHP_QUOTE -> escape tags as entities
  • + *
  • SMARTY_PHP_REMOVE -> remove php tags
  • + *
  • SMARTY_PHP_ALLOW -> execute php tags
  • + *
+ * + * @var integer + */ + var $php_handling = SMARTY_PHP_PASSTHRU; + + /** + * This enables template security. When enabled, many things are restricted + * in the templates that normally would go unchecked. This is useful when + * untrusted parties are editing templates and you want a reasonable level + * of security. (no direct execution of PHP in templates for example) + * + * @var boolean + */ + var $security = false; + + /** + * This is the list of template directories that are considered secure. This + * is used only if {@link $security} is enabled. One directory per array + * element. {@link $template_dir} is in this list implicitly. + * + * @var array + */ + var $secure_dir = array(); + + /** + * These are the security settings for Smarty. They are used only when + * {@link $security} is enabled. + * + * @var array + */ + var $security_settings = array( + 'PHP_HANDLING' => false, + 'IF_FUNCS' => array('array', 'list', + 'isset', 'empty', + 'count', 'sizeof', + 'in_array', 'is_array', + 'true', 'false', 'null'), + 'INCLUDE_ANY' => false, + 'PHP_TAGS' => false, + 'MODIFIER_FUNCS' => array('count'), + 'ALLOW_CONSTANTS' => false, + 'ALLOW_SUPER_GLOBALS' => true + ); + + /** + * This is an array of directories where trusted php scripts reside. + * {@link $security} is disabled during their inclusion/execution. + * + * @var array + */ + var $trusted_dir = array(); + + /** + * The left delimiter used for the template tags. + * + * @var string + */ + var $left_delimiter = '{'; + + /** + * The right delimiter used for the template tags. + * + * @var string + */ + var $right_delimiter = '}'; + + /** + * The order in which request variables are registered, similar to + * variables_order in php.ini E = Environment, G = GET, P = POST, + * C = Cookies, S = Server + * + * @var string + */ + var $request_vars_order = 'EGPCS'; + + /** + * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) + * are uses as request-vars or $_*[]-vars. note: if + * request_use_auto_globals is true, then $request_vars_order has + * no effect, but the php-ini-value "gpc_order" + * + * @var boolean + */ + var $request_use_auto_globals = true; + + /** + * Set this if you want different sets of compiled files for the same + * templates. This is useful for things like different languages. + * Instead of creating separate sets of templates per language, you + * set different compile_ids like 'en' and 'de'. + * + * @var string + */ + var $compile_id = null; + + /** + * This tells Smarty whether or not to use sub dirs in the cache/ and + * templates_c/ directories. sub directories better organized, but + * may not work well with PHP safe mode enabled. + * + * @var boolean + * + */ + var $use_sub_dirs = false; + + /** + * This is a list of the modifiers to apply to all template variables. + * Put each modifier in a separate array element in the order you want + * them applied. example: array('escape:"htmlall"'); + * + * @var array + */ + var $default_modifiers = array(); + + /** + * This is the resource type to be used when not specified + * at the beginning of the resource path. examples: + * $smarty->display('file:index.tpl'); + * $smarty->display('db:index.tpl'); + * $smarty->display('index.tpl'); // will use default resource type + * {include file="file:index.tpl"} + * {include file="db:index.tpl"} + * {include file="index.tpl"} {* will use default resource type *} + * + * @var array + */ + var $default_resource_type = 'file'; + + /** + * The function used for cache file handling. If not set, built-in caching is used. + * + * @var null|string function name + */ + var $cache_handler_func = null; + + /** + * This indicates which filters are automatically loaded into Smarty. + * + * @var array array of filter names + */ + var $autoload_filters = array(); + + /**#@+ + * @var boolean + */ + /** + * This tells if config file vars of the same name overwrite each other or not. + * if disabled, same name variables are accumulated in an array. + */ + var $config_overwrite = true; + + /** + * This tells whether or not to automatically booleanize config file variables. + * If enabled, then the strings "on", "true", and "yes" are treated as boolean + * true, and "off", "false" and "no" are treated as boolean false. + */ + var $config_booleanize = true; + + /** + * This tells whether hidden sections [.foobar] are readable from the + * tempalates or not. Normally you would never allow this since that is + * the point behind hidden sections: the application can access them, but + * the templates cannot. + */ + var $config_read_hidden = false; + + /** + * This tells whether or not automatically fix newlines in config files. + * It basically converts \r (mac) or \r\n (dos) to \n + */ + var $config_fix_newlines = true; + /**#@-*/ + + /** + * If a template cannot be found, this PHP function will be executed. + * Useful for creating templates on-the-fly or other special action. + * + * @var string function name + */ + var $default_template_handler_func = ''; + + /** + * The file that contains the compiler class. This can a full + * pathname, or relative to the php_include path. + * + * @var string + */ + var $compiler_file = 'Smarty_Compiler.class.php'; + + /** + * The class used for compiling templates. + * + * @var string + */ + var $compiler_class = 'Smarty_Compiler'; + + /** + * The class used to load config vars. + * + * @var string + */ + var $config_class = 'Config_File'; + +/**#@+ + * END Smarty Configuration Section + * There should be no need to touch anything below this line. + * @access private + */ + /** + * where assigned template vars are kept + * + * @var array + */ + var $_tpl_vars = array(); + + /** + * stores run-time $smarty.* vars + * + * @var null|array + */ + var $_smarty_vars = null; + + /** + * keeps track of sections + * + * @var array + */ + var $_sections = array(); + + /** + * keeps track of foreach blocks + * + * @var array + */ + var $_foreach = array(); + + /** + * keeps track of tag hierarchy + * + * @var array + */ + var $_tag_stack = array(); + + /** + * configuration object + * + * @var Config_file + */ + var $_conf_obj = null; + + /** + * loaded configuration settings + * + * @var array + */ + var $_config = array(array('vars' => array(), 'files' => array())); + + /** + * md5 checksum of the string 'Smarty' + * + * @var string + */ + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; + + /** + * Smarty version number + * + * @var string + */ + var $_version = '2.6.28'; + + /** + * current template inclusion depth + * + * @var integer + */ + var $_inclusion_depth = 0; + + /** + * for different compiled templates + * + * @var string + */ + var $_compile_id = null; + + /** + * text in URL to enable debug mode + * + * @var string + */ + var $_smarty_debug_id = 'SMARTY_DEBUG'; + + /** + * debugging information for debug console + * + * @var array + */ + var $_smarty_debug_info = array(); + + /** + * info that makes up a cache file + * + * @var array + */ + var $_cache_info = array(); + + /** + * default file permissions + * + * @var integer + */ + var $_file_perms = 0644; + + /** + * default dir permissions + * + * @var integer + */ + var $_dir_perms = 0771; + + /** + * registered objects + * + * @var array + */ + var $_reg_objects = array(); + + /** + * table keeping track of plugins + * + * @var array + */ + var $_plugins = array( + 'modifier' => array(), + 'function' => array(), + 'block' => array(), + 'compiler' => array(), + 'prefilter' => array(), + 'postfilter' => array(), + 'outputfilter' => array(), + 'resource' => array(), + 'insert' => array()); + + + /** + * cache serials + * + * @var array + */ + var $_cache_serials = array(); + + /** + * name of optional cache include file + * + * @var string + */ + var $_cache_include = null; + + /** + * indicate if the current code is used in a compiled + * include + * + * @var string + */ + var $_cache_including = false; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty() + { + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); + } + + /** + * assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign + */ + function assign($tpl_var, $value = null) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if ($key != '') { + $this->_tpl_vars[$key] = $val; + } + } + } else { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = $value; + } + } + + /** + * assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign + */ + function assign_by_ref($tpl_var, &$value) + { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = &$value; + } + + /** + * appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + */ + function append($tpl_var, $value=null, $merge=false) + { + if (is_array($tpl_var)) { + // $tpl_var is an array, ignore $value + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + if(!@is_array($this->_tpl_vars[$_key])) { + settype($this->_tpl_vars[$_key],'array'); + } + if($merge && is_array($_val)) { + foreach($_val as $_mkey => $_mval) { + $this->_tpl_vars[$_key][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$_key][] = $_val; + } + } + } + } else { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if($merge && is_array($value)) { + foreach($value as $_mkey => $_mval) { + $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } + } + + /** + * appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + */ + function append_by_ref($tpl_var, &$value, $merge=false) + { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_key => $_val) { + $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; + } + } else { + $this->_tpl_vars[$tpl_var][] = &$value; + } + } + } + + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + function clear_assign($tpl_var) + { + if (is_array($tpl_var)) + foreach ($tpl_var as $curr_var) + unset($this->_tpl_vars[$curr_var]); + else + unset($this->_tpl_vars[$tpl_var]); + } + + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + */ + function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['function'][$function] = + array($function_impl, null, null, false, $cacheable, $cache_attrs); + + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + function unregister_function($function) + { + unset($this->_plugins['function'][$function]); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object &$object_impl the referenced PHP object to register + * @param null|array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param null|array $block_functs list of methods that are block format + */ + function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->_reg_objects[$object] = + array(&$object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + function unregister_object($object) + { + unset($this->_reg_objects[$object]); + } + + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + */ + function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['block'][$block] = + array($block_impl, null, null, false, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + function unregister_block($block) + { + unset($this->_plugins['block'][$block]); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + */ + function register_compiler_function($function, $function_impl, $cacheable=true) + { + $this->_plugins['compiler'][$function] = + array($function_impl, null, null, false, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + function unregister_compiler_function($function) + { + unset($this->_plugins['compiler'][$function]); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + function register_modifier($modifier, $modifier_impl) + { + $this->_plugins['modifier'][$modifier] = + array($modifier_impl, null, null, false); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + function unregister_modifier($modifier) + { + unset($this->_plugins['modifier'][$modifier]); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + function register_resource($type, $functions) + { + if (count($functions)==4) { + $this->_plugins['resource'][$type] = + array($functions, false); + + } elseif (count($functions)==5) { + $this->_plugins['resource'][$type] = + array(array(array(&$functions[0], $functions[1]) + ,array(&$functions[0], $functions[2]) + ,array(&$functions[0], $functions[3]) + ,array(&$functions[0], $functions[4])) + ,false); + + } else { + $this->trigger_error("malformed function-list for '$type' in register_resource"); + + } + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + function unregister_resource($type) + { + unset($this->_plugins['resource'][$type]); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param callback $function + */ + function register_prefilter($function) + { + $this->_plugins['prefilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters a prefilter function + * + * @param callback $function + */ + function unregister_prefilter($function) + { + unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param callback $function + */ + function register_postfilter($function) + { + $this->_plugins['postfilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters a postfilter function + * + * @param callback $function + */ + function unregister_postfilter($function) + { + unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param callback $function + */ + function register_outputfilter($function) + { + $this->_plugins['outputfilter'][$this->_get_filter_name($function)] + = array($function, null, null, false); + } + + /** + * Unregisters an outputfilter function + * + * @param callback $function + */ + function unregister_outputfilter($function) + { + unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + function load_filter($type, $name) + { + switch ($type) { + case 'output': + $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + break; + + case 'pre': + case 'post': + if (!isset($this->_plugins[$type . 'filter'][$name])) + $this->_plugins[$type . 'filter'][$name] = false; + break; + } + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * @return boolean + */ + function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + if (!isset($tpl_file)) + $compile_id = null; + + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); + + if (!empty($this->cache_handler_func)) { + return call_user_func_array($this->cache_handler_func, + array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); + } else { + $_params = array('auto_base' => $this->cache_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $_auto_id, + 'exp_time' => $exp_time); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + } + + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_all_cache($exp_time = null) + { + return $this->clear_cache(null, null, null, $exp_time); + } + + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * @return string|false results of {@link _read_cache_file()} + */ + function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + if (!$this->caching) + return false; + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + $_params = array( + 'tpl_file' => $tpl_file, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + return smarty_core_read_cache_file($_params, $this); + } + + + /** + * clear all the assigned template variables. + * + */ + function clear_all_assign() + { + $this->_tpl_vars = array(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + $_params = array('auto_base' => $this->compile_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $compile_id, + 'exp_time' => $exp_time, + 'extensions' => array('.inc', '.php')); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * @return boolean + */ + function template_exists($tpl_file) + { + $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); + return $this->_fetch_resource_info($_params); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_template_vars($name=null) + { + if(!isset($name)) { + return $this->_tpl_vars; + } elseif(isset($this->_tpl_vars[$name])) { + return $this->_tpl_vars[$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * Returns an array containing config variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_config_vars($name=null) + { + if(!isset($name) && is_array($this->_config[0])) { + return $this->_config[0]['vars']; + } else if(isset($this->_config[0]['vars'][$name])) { + return $this->_config[0]['vars'][$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + $msg = htmlentities($error_msg); + trigger_error("Smarty error: $msg", $error_type); + } + + + /** + * executes & displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + */ + function display($resource_name, $cache_id = null, $compile_id = null) + { + $this->fetch($resource_name, $cache_id, $compile_id, true); + } + + /** + * executes & returns or displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + * @param boolean $display + */ + function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) + { + static $_cache_info = array(); + + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) + ? $this->error_reporting : error_reporting() & ~E_NOTICE); + + if (!$this->debugging && $this->debugging_ctrl == 'URL') { + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; + if (@strstr($_query_string, $this->_smarty_debug_id)) { + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { + // enable debugging for this browser session + @setcookie('SMARTY_DEBUG', true); + $this->debugging = true; + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { + // disable debugging for this browser session + @setcookie('SMARTY_DEBUG', false); + $this->debugging = false; + } else { + // enable debugging for this page + $this->debugging = true; + } + } else { + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + } + } + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $resource_name, + 'depth' => 0); + $_included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + + $this->_compile_id = $compile_id; + $this->_inclusion_depth = 0; + + if ($this->caching) { + // save old cache_info, initialize cache_info + array_push($_cache_info, $this->_cache_info); + $this->_cache_info = array(); + $_params = array( + 'tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => null + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + if (smarty_core_read_cache_file($_params, $this)) { + $_smarty_results = $_params['results']; + if (!empty($this->_cache_info['insert_tags'])) { + $_params = array('plugins' => $this->_cache_info['insert_tags']); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + } + if (!empty($this->_cache_info['cache_serials'])) { + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); + $_smarty_results = smarty_core_process_compiled_include($_params, $this); + } + + + if ($display) { + if ($this->debugging) + { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + $_smarty_results .= smarty_core_display_debug_console($_params, $this); + } + if ($this->cache_modified_check) { + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; + if (@count($this->_cache_info['insert_tags']) == 0 + && !$this->_cache_serials + && $_gmt_mtime == $_last_modified_date) { + if (php_sapi_name()=='cgi') + header('Status: 304 Not Modified'); + else + header('HTTP/1.1 304 Not Modified'); + + } else { + header('Last-Modified: '.$_gmt_mtime); + echo $_smarty_results; + } + } else { + echo $_smarty_results; + } + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return true; + } else { + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return $_smarty_results; + } + } else { + $this->_cache_info['template'][$resource_name] = true; + if ($this->cache_modified_check && $display) { + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + } + } + } + + // load filters that are marked as autoload + if (count($this->autoload_filters)) { + foreach ($this->autoload_filters as $_filter_type => $_filters) { + foreach ($_filters as $_filter) { + $this->load_filter($_filter_type, $_filter); + } + } + } + + $_smarty_compile_path = $this->_get_compile_path($resource_name); + + // if we just need to display the results, don't perform output + // buffering - for speed + $_cache_including = $this->_cache_including; + $this->_cache_including = false; + if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + } else { + ob_start(); + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + $_smarty_results = ob_get_contents(); + ob_end_clean(); + + foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { + $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); + } + } + + if ($this->caching) { + $_params = array('tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); + smarty_core_write_cache_file($_params, $this); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + + if ($this->_cache_serials) { + // strip nocache-tags from output + $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' + ,'' + ,$_smarty_results); + } + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + } + $this->_cache_including = $_cache_including; + + if ($display) { + if (isset($_smarty_results)) { echo $_smarty_results; } + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + echo smarty_core_display_debug_console($_params, $this); + } + error_reporting($_smarty_old_error_level); + return; + } else { + error_reporting($_smarty_old_error_level); + if (isset($_smarty_results)) { return $_smarty_results; } + } + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + function config_load($file, $section = null, $scope = 'global') + { + require_once($this->_get_plugin_filepath('function', 'config_load')); + smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); + } + + /** + * return a reference to a registered object + * + * @param string $name + * @return object + */ + function &get_registered_object($name) { + if (!isset($this->_reg_objects[$name])) + $this->_trigger_fatal_error("'$name' is not a registered object"); + + if (!is_object($this->_reg_objects[$name][0])) + $this->_trigger_fatal_error("registered '$name' is not an object"); + + return $this->_reg_objects[$name][0]; + } + + /** + * clear configuration values + * + * @param string $var + */ + function clear_config($var = null) + { + if(!isset($var)) { + // clear all values + $this->_config = array(array('vars' => array(), + 'files' => array())); + } else { + unset($this->_config[0]['vars'][$var]); + } + } + + /** + * get filepath of requested plugin + * + * @param string $type + * @param string $name + * @return string|false + */ + function _get_plugin_filepath($type, $name) + { + $_params = array('type' => $type, 'name' => $name); + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); + return smarty_core_assemble_plugin_filepath($_params, $this); + } + + /** + * test if resource needs compiling + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _is_compiled($resource_name, $compile_path) + { + if (!$this->force_compile && file_exists($compile_path)) { + if (!$this->compile_check) { + // no need to check compiled file + return true; + } else { + // get file source and timestamp + $_params = array('resource_name' => $resource_name, 'get_source'=>false); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + if ($_params['resource_timestamp'] <= filemtime($compile_path)) { + // template not expired, no recompile + return true; + } else { + // compile template + return false; + } + } + } else { + // compiled template does not exist, or forced compile + return false; + } + } + + /** + * compile the template + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _compile_resource($resource_name, $compile_path) + { + + $_params = array('resource_name' => $resource_name); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + + $_source_content = $_params['source_content']; + $_cache_include = substr($compile_path, 0, -4).'.inc'; + + if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { + // if a _cache_serial was set, we also have to write an include-file: + if ($this->_cache_include_info) { + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); + } + + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $this); + + return true; + } else { + return false; + } + + } + + /** + * compile the given source + * + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return boolean + */ + function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) + { + if (file_exists(SMARTY_DIR . $this->compiler_file)) { + require_once(SMARTY_DIR . $this->compiler_file); + } else { + // use include_path + require_once($this->compiler_file); + } + + + $smarty_compiler = new $this->compiler_class; + + $smarty_compiler->template_dir = $this->template_dir; + $smarty_compiler->compile_dir = $this->compile_dir; + $smarty_compiler->plugins_dir = $this->plugins_dir; + $smarty_compiler->config_dir = $this->config_dir; + $smarty_compiler->force_compile = $this->force_compile; + $smarty_compiler->caching = $this->caching; + $smarty_compiler->php_handling = $this->php_handling; + $smarty_compiler->left_delimiter = $this->left_delimiter; + $smarty_compiler->right_delimiter = $this->right_delimiter; + $smarty_compiler->_version = $this->_version; + $smarty_compiler->security = $this->security; + $smarty_compiler->secure_dir = $this->secure_dir; + $smarty_compiler->security_settings = $this->security_settings; + $smarty_compiler->trusted_dir = $this->trusted_dir; + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; + $smarty_compiler->_reg_objects = &$this->_reg_objects; + $smarty_compiler->_plugins = &$this->_plugins; + $smarty_compiler->_tpl_vars = &$this->_tpl_vars; + $smarty_compiler->default_modifiers = $this->default_modifiers; + $smarty_compiler->compile_id = $this->_compile_id; + $smarty_compiler->_config = $this->_config; + $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; + + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + } + $smarty_compiler->_cache_include = $cache_include_path; + + + $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); + + if ($smarty_compiler->_cache_serial) { + $this->_cache_include_info = array( + 'cache_serial'=>$smarty_compiler->_cache_serial + ,'plugins_code'=>$smarty_compiler->_plugins_code + ,'include_file_path' => $cache_include_path); + + } else { + $this->_cache_include_info = null; + + } + + return $_results; + } + + /** + * Get the compile path for this resource + * + * @param string $resource_name + * @return string results of {@link _get_auto_filename()} + */ + function _get_compile_path($resource_name) + { + return $this->_get_auto_filename($this->compile_dir, $resource_name, + $this->_compile_id) . '.php'; + } + + /** + * fetch the template info. Gets timestamp, and source + * if get_source is true + * + * sets $source_content to the source of the template, and + * $resource_timestamp to its time stamp + * @param string $resource_name + * @param string $source_content + * @param integer $resource_timestamp + * @param boolean $get_source + * @param boolean $quiet + * @return boolean + */ + + function _fetch_resource_info(&$params) + { + if(!isset($params['get_source'])) { $params['get_source'] = true; } + if(!isset($params['quiet'])) { $params['quiet'] = false; } + + $_return = false; + $_params = array('resource_name' => $params['resource_name']) ; + if (isset($params['resource_base_path'])) + $_params['resource_base_path'] = $params['resource_base_path']; + else + $_params['resource_base_path'] = $this->template_dir; + + if ($this->_parse_resource_name($_params)) { + $_resource_type = $_params['resource_type']; + $_resource_name = $_params['resource_name']; + switch ($_resource_type) { + case 'file': + if ($params['get_source']) { + $params['source_content'] = $this->_read_file($_resource_name); + } + $params['resource_timestamp'] = filemtime($_resource_name); + $_return = is_file($_resource_name) && is_readable($_resource_name); + break; + + default: + // call resource functions to fetch the template source and timestamp + if ($params['get_source']) { + $_source_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], + array($_resource_name, &$params['source_content'], &$this)); + } else { + $_source_return = true; + } + + $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], + array($_resource_name, &$params['resource_timestamp'], &$this)); + + $_return = $_source_return && $_timestamp_return; + break; + } + } + + if (!$_return) { + // see if we can get a template with the default template handler + if (!empty($this->default_template_handler_func)) { + if (!is_callable($this->default_template_handler_func)) { + $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); + } else { + $_return = call_user_func_array( + $this->default_template_handler_func, + array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); + } + } + } + + if (!$_return) { + if (!$params['quiet']) { + $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); + } + } else if ($_return && $this->security) { + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if (!smarty_core_is_secure($_params, $this)) { + if (!$params['quiet']) + $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); + $params['source_content'] = null; + $params['resource_timestamp'] = null; + return false; + } + } + return $_return; + } + + + /** + * parse out the type and name from the resource + * + * @param string $resource_base_path + * @param string $resource_name + * @param string $resource_type + * @param string $resource_name + * @return boolean + */ + + function _parse_resource_name(&$params) + { + + // split tpl_path by the first colon + $_resource_name_parts = explode(':', $params['resource_name'], 2); + + if (count($_resource_name_parts) == 1) { + // no resource type given + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $_resource_name_parts[0]; + } else { + if(strlen($_resource_name_parts[0]) == 1) { + // 1 char is not resource type, but part of filepath + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $params['resource_name']; + } else { + $params['resource_type'] = $_resource_name_parts[0]; + $params['resource_name'] = $_resource_name_parts[1]; + } + } + + if ($params['resource_type'] == 'file') { + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { + // relative pathname to $params['resource_base_path'] + // use the first directory where the file is found + foreach ((array)$params['resource_base_path'] as $_curr_path) { + $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; + if (file_exists($_fullpath) && is_file($_fullpath)) { + $params['resource_name'] = $_fullpath; + return true; + } + // didn't find the file, try include_path + $_params = array('file_path' => $_fullpath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $this)) { + $params['resource_name'] = $_params['new_file_path']; + return true; + } + } + return false; + } else { + /* absolute path */ + return file_exists($params['resource_name']); + } + } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { + $_params = array('type' => $params['resource_type']); + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); + smarty_core_load_resource_plugin($_params, $this); + } + + return true; + } + + + /** + * Handle modifiers + * + * @param string|null $modifier_name + * @param array|null $map_array + * @return string result of modifiers + */ + function _run_mod_handler() + { + $_args = func_get_args(); + list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); + list($_func_name, $_tpl_file, $_tpl_line) = + $this->_plugins['modifier'][$_modifier_name]; + + $_var = $_args[0]; + foreach ($_var as $_key => $_val) { + $_args[0] = $_val; + $_var[$_key] = call_user_func_array($_func_name, $_args); + } + return $_var; + } + + /** + * Remove starting and ending quotes from the string + * + * @param string $string + * @return string + */ + function _dequote($string) + { + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && + substr($string, -1) == substr($string, 0, 1)) + return substr($string, 1, -1); + else + return $string; + } + + + /** + * read in a file + * + * @param string $filename + * @return string + */ + function _read_file($filename) + { + if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) { + $contents = ''; + while (!feof($fd)) { + $contents .= fread($fd, 8192); + } + fclose($fd); + return $contents; + } else { + return false; + } + } + + /** + * get a concrete filename for automagically created content + * + * @param string $auto_base + * @param string $auto_source + * @param string $auto_id + * @return string + * @staticvar string|null + * @staticvar string|null + */ + function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) + { + $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; + $_return = $auto_base . DIRECTORY_SEPARATOR; + + if(isset($auto_id)) { + // make auto_id safe for directory names + $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); + // split into separate directories + $_return .= $auto_id . $_compile_dir_sep; + } + + if(isset($auto_source)) { + // make source name safe for filename + $_filename = urlencode(basename($auto_source)); + $_crc32 = sprintf('%08X', crc32($auto_source)); + // prepend %% to avoid name conflicts with + // with $params['auto_id'] names + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; + $_return .= '%%' . $_crc32 . '%%' . $_filename; + } + + return $_return; + } + + /** + * unlink a file, possibly using expiration time + * + * @param string $resource + * @param integer $exp_time + */ + function _unlink($resource, $exp_time = null) + { + if(isset($exp_time)) { + if(time() - @filemtime($resource) >= $exp_time) { + return @unlink($resource); + } + } else { + return @unlink($resource); + } + } + + /** + * returns an auto_id for auto-file-functions + * + * @param string $cache_id + * @param string $compile_id + * @return string|null + */ + function _get_auto_id($cache_id=null, $compile_id=null) { + if (isset($cache_id)) + return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; + elseif(isset($compile_id)) + return $compile_id; + else + return null; + } + + /** + * trigger Smarty plugin error + * + * @param string $error_msg + * @param string $tpl_file + * @param integer $tpl_line + * @param string $file + * @param integer $line + * @param integer $error_type + */ + function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, + $file = null, $line = null, $error_type = E_USER_ERROR) + { + if(isset($file) && isset($line)) { + $info = ' ('.basename($file).", line $line)"; + } else { + $info = ''; + } + if (isset($tpl_line) && isset($tpl_file)) { + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); + } else { + $this->trigger_error($error_msg . $info, $error_type); + } + } + + + /** + * callback function for preg_replace, to call a non-cacheable block + * @return string + */ + function _process_compiled_include_callback($match) { + $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; + ob_start(); + $_func($this); + $_ret = ob_get_contents(); + ob_end_clean(); + return $_ret; + } + + + /** + * called for included templates + * + * @param string $_smarty_include_tpl_file + * @param string $_smarty_include_vars + */ + + // $_smarty_include_tpl_file, $_smarty_include_vars + + function _smarty_include($params) + { + if ($this->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $params['smarty_include_tpl_file'], + 'depth' => ++$this->_inclusion_depth); + $included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); + + // config vars are treated as local, so push a copy of the + // current ones onto the front of the stack + array_unshift($this->_config, $this->_config[0]); + + $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); + + + if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) + || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + + // pop the local vars off the front of the stack + array_shift($this->_config); + + $this->_inclusion_depth--; + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; + } + + if ($this->caching) { + $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; + } + } + + + /** + * get or set an array of cached attributes for function that is + * not cacheable + * @return array + */ + function &_smarty_cache_attrs($cache_serial, $count) { + $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; + + if ($this->_cache_including) { + /* return next set of cache_attrs */ + $_return = current($_cache_attrs); + next($_cache_attrs); + return $_return; + + } else { + /* add a reference to a new set of cache_attrs */ + $_cache_attrs[] = array(); + return $_cache_attrs[count($_cache_attrs)-1]; + + } + + } + + + /** + * wrapper for include() retaining $this + * @return mixed + */ + function _include($filename, $once=false, $params=null) + { + if ($once) { + return include_once($filename); + } else { + return include($filename); + } + } + + + /** + * wrapper for eval() retaining $this + * @return mixed + */ + function _eval($code, $params=null) + { + return eval($code); + } + + /** + * Extracts the filter name from the given callback + * + * @param callback $function + * @return string + */ + function _get_filter_name($function) + { + if (is_array($function)) { + $_class_name = (is_object($function[0]) ? + get_class($function[0]) : $function[0]); + return $_class_name . '_' . $function[1]; + } + else { + return $function; + } + } + + /**#@-*/ + +} + +/* vim: set expandtab: */ + +?> diff --git a/code/web/public_php/admin/smarty/Smarty_Compiler.class.php b/code/web/public_php/admin/smarty/Smarty_Compiler.class.php index e714a6339..c1bc798d1 100644 --- a/code/web/public_php/admin/smarty/Smarty_Compiler.class.php +++ b/code/web/public_php/admin/smarty/Smarty_Compiler.class.php @@ -1,2304 +1,2365 @@ - - * @author Andrei Zmievski - * @version 2.6.9 - * @copyright 2001-2005 New Digital Group, Inc. - * @package Smarty - */ - -/* $Id: Smarty_Compiler.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ - -/** - * Template compiling class - * @package Smarty - */ -class Smarty_Compiler extends Smarty { - - // internal vars - /**#@+ - * @access private - */ - var $_folded_blocks = array(); // keeps folded template blocks - var $_current_file = null; // the current template being compiled - var $_current_line_no = 1; // line number for error messages - var $_capture_stack = array(); // keeps track of nested capture buffers - var $_plugin_info = array(); // keeps track of plugins to load - var $_init_smarty_vars = false; - var $_permitted_tokens = array('true','false','yes','no','on','off','null'); - var $_db_qstr_regexp = null; // regexps are setup in the constructor - var $_si_qstr_regexp = null; - var $_qstr_regexp = null; - var $_func_regexp = null; - var $_reg_obj_regexp = null; - var $_var_bracket_regexp = null; - var $_num_const_regexp = null; - var $_dvar_guts_regexp = null; - var $_dvar_regexp = null; - var $_cvar_regexp = null; - var $_svar_regexp = null; - var $_avar_regexp = null; - var $_mod_regexp = null; - var $_var_regexp = null; - var $_parenth_param_regexp = null; - var $_func_call_regexp = null; - var $_obj_ext_regexp = null; - var $_obj_start_regexp = null; - var $_obj_params_regexp = null; - var $_obj_call_regexp = null; - var $_cacheable_state = 0; - var $_cache_attrs_count = 0; - var $_nocache_count = 0; - var $_cache_serial = null; - var $_cache_include = null; - - var $_strip_depth = 0; - var $_additional_newline = "\n"; - - /**#@-*/ - /** - * The class constructor. - */ - function Smarty_Compiler() - { - // matches double quoted strings: - // "foobar" - // "foo\"bar" - $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; - - // matches single quoted strings: - // 'foobar' - // 'foo\'bar' - $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - // matches single or double quoted strings - $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; - - // matches bracket portion of vars - // [0] - // [foo] - // [$bar] - $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; - - // matches numerical constants - // 30 - // -12 - // 13.22 - $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; - - // matches $ vars (not objects): - // $foo - // $foo.bar - // $foo.bar.foobar - // $foo[0] - // $foo[$bar] - // $foo[5][blah] - // $foo[5].bar[$foobar][4] - $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; - $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; - $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp - . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; - $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; - - // matches config vars: - // #foo# - // #foobar123_foo# - $this->_cvar_regexp = '\#\w+\#'; - - // matches section vars: - // %foo.bar% - $this->_svar_regexp = '\%\w+\.\w+\%'; - - // matches all valid variables (no quotes, no modifiers) - $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' - . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; - - // matches valid variable syntax: - // $foo - // $foo - // #foo# - // #foo# - // "text" - // "text" - $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; - - // matches valid object call (one level of object nesting allowed in parameters): - // $foo->bar - // $foo->bar() - // $foo->bar("text") - // $foo->bar($foo, $bar, "text") - // $foo->bar($foo, "foo") - // $foo->bar->foo() - // $foo->bar->foo->bar() - // $foo->bar($foo->bar) - // $foo->bar($foo->bar()) - // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) - $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; - $this->_obj_restricted_param_regexp = '(?:' - . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' - . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; - $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' - . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; - $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp - . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; - $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; - $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; - - // matches valid modifier syntax: - // |foo - // |@foo - // |foo:"bar" - // |foo:$bar - // |foo:"bar":$foobar - // |foo|bar - // |foo:$foo->bar - $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' - . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; - - // matches valid function name: - // foo123 - // _foo_bar - $this->_func_regexp = '[a-zA-Z_]\w*'; - - // matches valid registered object: - // foo->bar - $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; - - // matches valid parameter values: - // true - // $foo - // $foo|bar - // #foo# - // #foo#|bar - // "text" - // "text"|bar - // $foo->bar - $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' - . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; - - // matches valid parenthesised function parameters: - // - // "text" - // $foo, $bar, "text" - // $foo|bar, "foo"|bar, $foo->bar($foo)|bar - $this->_parenth_param_regexp = '(?:\((?:\w+|' - . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' - . $this->_param_regexp . ')))*)?\))'; - - // matches valid function call: - // foo() - // foo_bar($foo) - // _foo_bar($foo,"bar") - // foo123($foo,$foo->bar(),"foo") - $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' - . $this->_parenth_param_regexp . '))'; - } - - /** - * compile a resource - * - * sets $compiled_content to the compiled source - * @param string $resource_name - * @param string $source_content - * @param string $compiled_content - * @return true - */ - function _compile_file($resource_name, $source_content, &$compiled_content) - { - - if ($this->security) { - // do not allow php syntax to be executed unless specified - if ($this->php_handling == SMARTY_PHP_ALLOW && - !$this->security_settings['PHP_HANDLING']) { - $this->php_handling = SMARTY_PHP_PASSTHRU; - } - } - - $this->_load_filters(); - - $this->_current_file = $resource_name; - $this->_current_line_no = 1; - $ldq = preg_quote($this->left_delimiter, '~'); - $rdq = preg_quote($this->right_delimiter, '~'); - - // run template source through prefilter functions - if (count($this->_plugins['prefilter']) > 0) { - foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { - if ($prefilter === false) continue; - if ($prefilter[3] || is_callable($prefilter[0])) { - $source_content = call_user_func_array($prefilter[0], - array($source_content, &$this)); - $this->_plugins['prefilter'][$filter_name][3] = true; - } else { - $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); - } - } - } - - /* fetch all special blocks */ - $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; - - preg_match_all($search, $source_content, $match, PREG_SET_ORDER); - $this->_folded_blocks = $match; - reset($this->_folded_blocks); - - /* replace special blocks by "{php}" */ - $source_content = preg_replace($search.'e', "'" - . $this->_quote_replace($this->left_delimiter) . 'php' - . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" - . $this->_quote_replace($this->right_delimiter) - . "'" - , $source_content); - - /* Gather all template tags. */ - preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); - $template_tags = $_match[1]; - /* Split content by template tags to obtain non-template content. */ - $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); - - /* loop through text blocks */ - for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { - /* match anything resembling php tags */ - if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { - /* replace tags with placeholders to prevent recursive replacements */ - $sp_match[1] = array_unique($sp_match[1]); - usort($sp_match[1], '_smarty_sort_length'); - for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { - $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); - } - /* process each one */ - for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { - if ($this->php_handling == SMARTY_PHP_PASSTHRU) { - /* echo php contents */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', ''."\n", $text_blocks[$curr_tb]); - } else if ($this->php_handling == SMARTY_PHP_QUOTE) { - /* quote php tags */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); - } else if ($this->php_handling == SMARTY_PHP_REMOVE) { - /* remove php tags */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); - } else { - /* SMARTY_PHP_ALLOW, but echo non php starting tags */ - $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', ''."\n", $sp_match[1][$curr_sp]); - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); - } - } - } - } - - /* Compile the template tags into PHP code. */ - $compiled_tags = array(); - for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { - $this->_current_line_no += substr_count($text_blocks[$i], "\n"); - $compiled_tags[] = $this->_compile_tag($template_tags[$i]); - $this->_current_line_no += substr_count($template_tags[$i], "\n"); - } - if (count($this->_tag_stack)>0) { - list($_open_tag, $_line_no) = end($this->_tag_stack); - $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); - return; - } - - /* Reformat $text_blocks between 'strip' and '/strip' tags, - removing spaces, tabs and newlines. */ - $strip = false; - for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { - if ($compiled_tags[$i] == '{strip}') { - $compiled_tags[$i] = ''; - $strip = true; - /* remove leading whitespaces */ - $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); - } - if ($strip) { - /* strip all $text_blocks before the next '/strip' */ - for ($j = $i + 1; $j < $for_max; $j++) { - /* remove leading and trailing whitespaces of each line */ - $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); - if ($compiled_tags[$j] == '{/strip}') { - /* remove trailing whitespaces from the last text_block */ - $text_blocks[$j] = rtrim($text_blocks[$j]); - } - $text_blocks[$j] = ""\'", "\\"=>"\\\\")) . "'; ?>"; - if ($compiled_tags[$j] == '{/strip}') { - $compiled_tags[$j] = "\n"; /* slurped by php, but necessary - if a newline is following the closing strip-tag */ - $strip = false; - $i = $j; - break; - } - } - } - } - $compiled_content = ''; - - /* Interleave the compiled contents and text blocks to get the final result. */ - for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { - if ($compiled_tags[$i] == '') { - // tag result empty, remove first newline from following text block - $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); - } - $compiled_content .= $text_blocks[$i].$compiled_tags[$i]; - } - $compiled_content .= $text_blocks[$i]; - - // remove \n from the end of the file, if any - if (($_len=strlen($compiled_content)) && ($compiled_content{$_len - 1} == "\n" )) { - $compiled_content = substr($compiled_content, 0, -1); - } - - if (!empty($this->_cache_serial)) { - $compiled_content = "_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; - } - - // remove unnecessary close/open tags - $compiled_content = preg_replace('~\?>\n?<\?php~', '', $compiled_content); - - // run compiled template through postfilter functions - if (count($this->_plugins['postfilter']) > 0) { - foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { - if ($postfilter === false) continue; - if ($postfilter[3] || is_callable($postfilter[0])) { - $compiled_content = call_user_func_array($postfilter[0], - array($compiled_content, &$this)); - $this->_plugins['postfilter'][$filter_name][3] = true; - } else { - $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); - } - } - } - - // put header at the top of the compiled template - $template_header = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; - $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; - - /* Emit code to load needed plugins. */ - $this->_plugins_code = ''; - if (count($this->_plugin_info)) { - $_plugins_params = "array('plugins' => array("; - foreach ($this->_plugin_info as $plugin_type => $plugins) { - foreach ($plugins as $plugin_name => $plugin_info) { - $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; - $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; - } - } - $_plugins_params .= '))'; - $plugins_code = "\n"; - $template_header .= $plugins_code; - $this->_plugin_info = array(); - $this->_plugins_code = $plugins_code; - } - - if ($this->_init_smarty_vars) { - $template_header .= "\n"; - $this->_init_smarty_vars = false; - } - - $compiled_content = $template_header . $compiled_content; - return true; - } - - /** - * Compile a template tag - * - * @param string $template_tag - * @return string - */ - function _compile_tag($template_tag) - { - /* Matched comment. */ - if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*') - return ''; - - /* Split tag into two three parts: command, command modifiers and the arguments. */ - if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp - . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) - (?:\s+(.*))?$ - ~xs', $template_tag, $match)) { - $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); - } - - $tag_command = $match[1]; - $tag_modifier = isset($match[2]) ? $match[2] : null; - $tag_args = isset($match[3]) ? $match[3] : null; - - if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { - /* tag name is a variable or object */ - $_return = $this->_parse_var_props($tag_command . $tag_modifier); - return "" . $this->_additional_newline; - } - - /* If the tag name is a registered object, we process it. */ - if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { - return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); - } - - switch ($tag_command) { - case 'include': - return $this->_compile_include_tag($tag_args); - - case 'include_php': - return $this->_compile_include_php_tag($tag_args); - - case 'if': - $this->_push_tag('if'); - return $this->_compile_if_tag($tag_args); - - case 'else': - list($_open_tag) = end($this->_tag_stack); - if ($_open_tag != 'if' && $_open_tag != 'elseif') - $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); - else - $this->_push_tag('else'); - return ''; - - case 'elseif': - list($_open_tag) = end($this->_tag_stack); - if ($_open_tag != 'if' && $_open_tag != 'elseif') - $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); - if ($_open_tag == 'if') - $this->_push_tag('elseif'); - return $this->_compile_if_tag($tag_args, true); - - case '/if': - $this->_pop_tag('if'); - return ''; - - case 'capture': - return $this->_compile_capture_tag(true, $tag_args); - - case '/capture': - return $this->_compile_capture_tag(false); - - case 'ldelim': - return $this->left_delimiter; - - case 'rdelim': - return $this->right_delimiter; - - case 'section': - $this->_push_tag('section'); - return $this->_compile_section_start($tag_args); - - case 'sectionelse': - $this->_push_tag('sectionelse'); - return ""; - break; - - case '/section': - $_open_tag = $this->_pop_tag('section'); - if ($_open_tag == 'sectionelse') - return ""; - else - return ""; - - case 'foreach': - $this->_push_tag('foreach'); - return $this->_compile_foreach_start($tag_args); - break; - - case 'foreachelse': - $this->_push_tag('foreachelse'); - return ""; - - case '/foreach': - $_open_tag = $this->_pop_tag('foreach'); - if ($_open_tag == 'foreachelse') - return ""; - else - return ""; - break; - - case 'strip': - case '/strip': - if ($tag_command{0}=='/') { - $this->_pop_tag('strip'); - if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ - $this->_additional_newline = "\n"; - return '{' . $tag_command . '}'; - } - } else { - $this->_push_tag('strip'); - if ($this->_strip_depth++==0) { /* outermost opening {strip} */ - $this->_additional_newline = ""; - return '{' . $tag_command . '}'; - } - } - return ''; - - case 'php': - /* handle folded tags replaced by {php} */ - list(, $block) = each($this->_folded_blocks); - $this->_current_line_no += substr_count($block[0], "\n"); - /* the number of matched elements in the regexp in _compile_file() - determins the type of folded tag that was found */ - switch (count($block)) { - case 2: /* comment */ - return ''; - - case 3: /* literal */ - return ""\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; - - case 4: /* php */ - if ($this->security && !$this->security_settings['PHP_TAGS']) { - $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); - return; - } - return ''; - } - break; - - case 'insert': - return $this->_compile_insert_tag($tag_args); - - default: - if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { - return $output; - } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; - } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; - } else { - $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); - } - - } - } - - - /** - * compile the custom compiler tag - * - * sets $output to the compiled custom compiler tag - * @param string $tag_command - * @param string $tag_args - * @param string $output - * @return boolean - */ - function _compile_compiler_tag($tag_command, $tag_args, &$output) - { - $found = false; - $have_function = true; - - /* - * First we check if the compiler function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['compiler'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['compiler'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "compiler function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_compiler_' . $tag_command; - if (!is_callable($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); - } - } - - /* - * True return value means that we either found a plugin or a - * dynamically registered function. False means that we didn't and the - * compiler should now emit code to load custom function plugin for this - * tag. - */ - if ($found) { - if ($have_function) { - $output = call_user_func_array($plugin_func, array($tag_args, &$this)); - if($output != '') { - $output = '_push_cacheable_state('compiler', $tag_command) - . $output - . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; - } - } else { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - } - return true; - } else { - return false; - } - } - - - /** - * compile block function tag - * - * sets $output to compiled block function tag - * @param string $tag_command - * @param string $tag_args - * @param string $tag_modifier - * @param string $output - * @return boolean - */ - function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) - { - if ($tag_command{0} == '/') { - $start_tag = false; - $tag_command = substr($tag_command, 1); - } else - $start_tag = true; - - $found = false; - $have_function = true; - - /* - * First we check if the block function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['block'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['block'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "block function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_block_' . $tag_command; - if (!function_exists($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); - - } - } - - if (!$found) { - return false; - } else if (!$have_function) { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - return true; - } - - /* - * Even though we've located the plugin function, compilation - * happens only once, so the plugin will still need to be loaded - * at runtime for future requests. - */ - $this->_add_plugin('block', $tag_command); - - if ($start_tag) - $this->_push_tag($tag_command); - else - $this->_pop_tag($tag_command); - - if ($start_tag) { - $output = '_push_cacheable_state('block', $tag_command); - $attrs = $this->_parse_attrs($tag_args); - $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs=''); - $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; - $output .= $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat=true);'; - $output .= 'while ($_block_repeat) { ob_start(); ?>'; - } else { - $output = '_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat=false)'; - if ($tag_modifier != '') { - $this->_parse_modifiers($_out_tag_text, $tag_modifier); - } - $output .= 'echo '.$_out_tag_text.'; } '; - $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; - } - - return true; - } - - - /** - * compile custom function tag - * - * @param string $tag_command - * @param string $tag_args - * @param string $tag_modifier - * @return string - */ - function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) - { - $found = false; - $have_function = true; - - /* - * First we check if the custom function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['function'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['function'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "custom function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_function_' . $tag_command; - if (!function_exists($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); - - } - } - - if (!$found) { - return false; - } else if (!$have_function) { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - return true; - } - - /* declare plugin to be loaded on display of the template that - we compile right now */ - $this->_add_plugin('function', $tag_command); - - $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); - $attrs = $this->_parse_attrs($tag_args); - $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs=''); - - $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; - if($tag_modifier != '') { - $this->_parse_modifiers($output, $tag_modifier); - } - - if($output != '') { - $output = '_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; - } - - return true; - } - - /** - * compile a registered object tag - * - * @param string $tag_command - * @param array $attrs - * @param string $tag_modifier - * @return string - */ - function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) - { - if ($tag_command{0} == '/') { - $start_tag = false; - $tag_command = substr($tag_command, 1); - } else { - $start_tag = true; - } - - list($object, $obj_comp) = explode('->', $tag_command); - - $arg_list = array(); - if(count($attrs)) { - $_assign_var = false; - foreach ($attrs as $arg_name => $arg_value) { - if($arg_name == 'assign') { - $_assign_var = $arg_value; - unset($attrs['assign']); - continue; - } - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - - if($this->_reg_objects[$object][2]) { - // smarty object argument format - $args = "array(".implode(',', (array)$arg_list)."), \$this"; - } else { - // traditional argument format - $args = implode(',', array_values($attrs)); - if (empty($args)) { - $args = 'null'; - } - } - - $prefix = ''; - $postfix = ''; - $newline = ''; - if(!is_object($this->_reg_objects[$object][0])) { - $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { - $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { - // method - if(in_array($obj_comp, $this->_reg_objects[$object][3])) { - // block method - if ($start_tag) { - $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; - $prefix .= "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat=true); "; - $prefix .= "while (\$_block_repeat) { ob_start();"; - $return = null; - $postfix = ''; - } else { - $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); "; - $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat=false)"; - $postfix = "} array_pop(\$this->_tag_stack);"; - } - } else { - // non-block method - $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; - } - } else { - // property - $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; - } - - if($return != null) { - if($tag_modifier != '') { - $this->_parse_modifiers($return, $tag_modifier); - } - - if(!empty($_assign_var)) { - $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; - } else { - $output = 'echo ' . $return . ';'; - $newline = $this->_additional_newline; - } - } else { - $output = ''; - } - - return '" . $newline; - } - - /** - * Compile {insert ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_insert_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $name = $this->_dequote($attrs['name']); - - if (empty($name)) { - $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); - } - - if (!empty($attrs['script'])) { - $delayed_loading = true; - } else { - $delayed_loading = false; - } - - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - $this->_add_plugin('insert', $name, $delayed_loading); - - $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; - - return "" . $this->_additional_newline; - } - - /** - * Compile {include ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_include_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); - } - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'file') { - $include_file = $arg_value; - continue; - } else if ($arg_name == 'assign') { - $assign_var = $arg_value; - continue; - } - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - $output = '_tpl_vars;\n"; - - - $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; - $output .= "\$this->_smarty_include($_params);\n" . - "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . - "unset(\$_smarty_tpl_vars);\n"; - - if (isset($assign_var)) { - $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; - } - - $output .= ' ?>'; - - return $output; - - } - - /** - * Compile {include ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_include_php_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); - } - - $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); - $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; - - $arg_list = array(); - foreach($attrs as $arg_name => $arg_value) { - if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { - if(is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - - $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; - - return "" . $this->_additional_newline; - } - - - /** - * Compile {section ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_section_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - $output = '_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); - } - - $output .= "unset(\$this->_sections[$section_name]);\n"; - $section_props = "\$this->_sections[$section_name]"; - - foreach ($attrs as $attr_name => $attr_value) { - switch ($attr_name) { - case 'loop': - $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; - break; - - case 'show': - if (is_bool($attr_value)) - $show_attr_value = $attr_value ? 'true' : 'false'; - else - $show_attr_value = "(bool)$attr_value"; - $output .= "{$section_props}['show'] = $show_attr_value;\n"; - break; - - case 'name': - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - - case 'max': - case 'start': - $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; - break; - - case 'step': - $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; - break; - - default: - $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); - break; - } - } - - if (!isset($attrs['show'])) - $output .= "{$section_props}['show'] = true;\n"; - - if (!isset($attrs['loop'])) - $output .= "{$section_props}['loop'] = 1;\n"; - - if (!isset($attrs['max'])) - $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; - else - $output .= "if ({$section_props}['max'] < 0)\n" . - " {$section_props}['max'] = {$section_props}['loop'];\n"; - - if (!isset($attrs['step'])) - $output .= "{$section_props}['step'] = 1;\n"; - - if (!isset($attrs['start'])) - $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; - else { - $output .= "if ({$section_props}['start'] < 0)\n" . - " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . - "else\n" . - " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; - } - - $output .= "if ({$section_props}['show']) {\n"; - if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { - $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; - } else { - $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; - } - $output .= " if ({$section_props}['total'] == 0)\n" . - " {$section_props}['show'] = false;\n" . - "} else\n" . - " {$section_props}['total'] = 0;\n"; - - $output .= "if ({$section_props}['show']):\n"; - $output .= " - for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; - {$section_props}['iteration'] <= {$section_props}['total']; - {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; - $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; - $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; - $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; - $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; - $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; - - $output .= "?>"; - - return $output; - } - - - /** - * Compile {foreach ...} tag. - * - * @param string $tag_args - * @return string - */ - function _compile_foreach_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - if (empty($attrs['from'])) { - return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); - } - $from = $attrs['from']; - - if (empty($attrs['item'])) { - return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); - } - $item = $this->_dequote($attrs['item']); - if (!preg_match('~^\w+$~', $item)) { - return $this->_syntax_error("'foreach: item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); - } - - if (isset($attrs['key'])) { - $key = $this->_dequote($attrs['key']); - if (!preg_match('~^\w+$~', $key)) { - return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); - } - $key_part = "\$this->_tpl_vars['$key'] => "; - } else { - $key = null; - $key_part = ''; - } - - if (isset($attrs['name'])) { - $name = $attrs['name']; - } else { - $name = null; - } - - $output = '_foreach[$name]"; - $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; - $output .= "if ({$foreach_props}['total'] > 0):\n"; - $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; - $output .= " {$foreach_props}['iteration']++;\n"; - } else { - $output .= "if (count(\$_from)):\n"; - $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; - } - $output .= '?>'; - - return $output; - } - - - /** - * Compile {capture} .. {/capture} tags - * - * @param boolean $start true if this is the {capture} tag - * @param string $tag_args - * @return string - */ - - function _compile_capture_tag($start, $tag_args = '') - { - $attrs = $this->_parse_attrs($tag_args); - - if ($start) { - if (isset($attrs['name'])) - $buffer = $attrs['name']; - else - $buffer = "'default'"; - - if (isset($attrs['assign'])) - $assign = $attrs['assign']; - else - $assign = null; - $output = ""; - $this->_capture_stack[] = array($buffer, $assign); - } else { - list($buffer, $assign) = array_pop($this->_capture_stack); - $output = "_smarty_vars['capture'][$buffer] = ob_get_contents(); "; - if (isset($assign)) { - $output .= " \$this->assign($assign, ob_get_contents());"; - } - $output .= "ob_end_clean(); ?>"; - } - - return $output; - } - - /** - * Compile {if ...} tag - * - * @param string $tag_args - * @param boolean $elseif if true, uses elseif instead of if - * @return string - */ - function _compile_if_tag($tag_args, $elseif = false) - { - - /* Tokenize args for 'if' tag. */ - preg_match_all('~(?> - ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call - ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string - \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token - \b\w+\b | # valid word token - \S+ # anything else - )~x', $tag_args, $match); - - $tokens = $match[0]; - - // make sure we have balanced parenthesis - $token_count = array_count_values($tokens); - if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { - $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); - } - - $is_arg_stack = array(); - - for ($i = 0; $i < count($tokens); $i++) { - - $token = &$tokens[$i]; - - switch (strtolower($token)) { - case '!': - case '%': - case '!==': - case '==': - case '===': - case '>': - case '<': - case '!=': - case '<>': - case '<<': - case '>>': - case '<=': - case '>=': - case '&&': - case '||': - case '|': - case '^': - case '&': - case '~': - case ')': - case ',': - case '+': - case '-': - case '*': - case '/': - case '@': - break; - - case 'eq': - $token = '=='; - break; - - case 'ne': - case 'neq': - $token = '!='; - break; - - case 'lt': - $token = '<'; - break; - - case 'le': - case 'lte': - $token = '<='; - break; - - case 'gt': - $token = '>'; - break; - - case 'ge': - case 'gte': - $token = '>='; - break; - - case 'and': - $token = '&&'; - break; - - case 'or': - $token = '||'; - break; - - case 'not': - $token = '!'; - break; - - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - /* If last token was a ')', we operate on the parenthesized - expression. The start of the expression is on the stack. - Otherwise, we operate on the last encountered token. */ - if ($tokens[$i-1] == ')') - $is_arg_start = array_pop($is_arg_stack); - else - $is_arg_start = $i-1; - /* Construct the argument for 'is' expression, so it knows - what to operate on. */ - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - /* Pass all tokens from next one until the end to the - 'is' expression parsing function. The function will - return modified tokens, where the first one is the result - of the 'is' expression and the rest are the tokens it - didn't touch. */ - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - /* Replace the old tokens with the new ones. */ - array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); - - /* Adjust argument start so that it won't change from the - current position for the next iteration. */ - $i = $is_arg_start; - break; - - default: - if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { - // function call - if($this->security && - !in_array($token, $this->security_settings['IF_FUNCS'])) { - $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); - } - } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { - // variable function call - $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); - } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { - // object or variable - $token = $this->_parse_var_props($token); - } elseif(is_numeric($token)) { - // number, skip it - } else { - $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); - } - break; - } - } - - if ($elseif) - return ''; - else - return ''; - } - - - function _compile_arg_list($type, $name, $attrs, &$cache_code) { - $arg_list = array(); - - if (isset($type) && isset($name) - && isset($this->_plugins[$type]) - && isset($this->_plugins[$type][$name]) - && empty($this->_plugins[$type][$name][4]) - && is_array($this->_plugins[$type][$name][5]) - ) { - /* we have a list of parameters that should be cached */ - $_cache_attrs = $this->_plugins[$type][$name][5]; - $_count = $this->_cache_attrs_count++; - $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; - - } else { - /* no parameters are cached */ - $_cache_attrs = null; - } - - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - if (is_null($arg_value)) - $arg_value = 'null'; - if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { - $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; - } else { - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - return $arg_list; - } - - /** - * Parse is expression - * - * @param string $is_arg - * @param array $tokens - * @return array - */ - function _parse_is_expr($is_arg, $tokens) - { - $expr_end = 0; - $negate_expr = false; - - if (($first_token = array_shift($tokens)) == 'not') { - $negate_expr = true; - $expr_type = array_shift($tokens); - } else - $expr_type = $first_token; - - switch ($expr_type) { - case 'even': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; - } else - $expr = "!(1 & $is_arg)"; - break; - - case 'odd': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; - } else - $expr = "(1 & $is_arg)"; - break; - - case 'div': - if (@$tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; - } else { - $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); - } - break; - - default: - $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); - break; - } - - if ($negate_expr) { - $expr = "!($expr)"; - } - - array_splice($tokens, 0, $expr_end, $expr); - - return $tokens; - } - - - /** - * Parse attribute string - * - * @param string $tag_args - * @return array - */ - function _parse_attrs($tag_args) - { - - /* Tokenize tag attributes. */ - preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) - )+ | - [=] - ~x', $tag_args, $match); - $tokens = $match[0]; - - $attrs = array(); - /* Parse state: - 0 - expecting attribute name - 1 - expecting '=' - 2 - expecting attribute value (not '=') */ - $state = 0; - - foreach ($tokens as $token) { - switch ($state) { - case 0: - /* If the token is a valid identifier, we set attribute name - and go to state 1. */ - if (preg_match('~^\w+$~', $token)) { - $attr_name = $token; - $state = 1; - } else - $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); - break; - - case 1: - /* If the token is '=', then we go to state 2. */ - if ($token == '=') { - $state = 2; - } else - $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); - break; - - case 2: - /* If token is not '=', we set the attribute value and go to - state 0. */ - if ($token != '=') { - /* We booleanize the token if it's a non-quoted possible - boolean value. */ - if (preg_match('~^(on|yes|true)$~', $token)) { - $token = 'true'; - } else if (preg_match('~^(off|no|false)$~', $token)) { - $token = 'false'; - } else if ($token == 'null') { - $token = 'null'; - } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { - /* treat integer literally */ - } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { - /* treat as a string, double-quote it escaping quotes */ - $token = '"'.addslashes($token).'"'; - } - - $attrs[$attr_name] = $token; - $state = 0; - } else - $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); - break; - } - $last_token = $token; - } - - if($state != 0) { - if($state == 1) { - $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); - } else { - $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); - } - } - - $this->_parse_vars_props($attrs); - - return $attrs; - } - - /** - * compile multiple variables and section properties tokens into - * PHP code - * - * @param array $tokens - */ - function _parse_vars_props(&$tokens) - { - foreach($tokens as $key => $val) { - $tokens[$key] = $this->_parse_var_props($val); - } - } - - /** - * compile single variable and section properties token into - * PHP code - * - * @param string $val - * @param string $tag_attrs - * @return string - */ - function _parse_var_props($val) - { - $val = trim($val); - - if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { - // $ variable or object - $return = $this->_parse_var($match[1]); - $modifiers = $match[2]; - if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { - $_default_mod_string = implode('|',(array)$this->default_modifiers); - $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; - } - $this->_parse_modifiers($return, $modifiers); - return $return; - } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // double quoted text - preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - $return = $this->_expand_quoted_text($match[1]); - if($match[2] != '') { - $this->_parse_modifiers($return, $match[2]); - } - return $return; - } - elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // numerical constant - preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - if($match[2] != '') { - $this->_parse_modifiers($match[1], $match[2]); - return $match[1]; - } - } - elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // single quoted text - preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - if($match[2] != '') { - $this->_parse_modifiers($match[1], $match[2]); - return $match[1]; - } - } - elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // config var - return $this->_parse_conf_var($val); - } - elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // section var - return $this->_parse_section_prop($val); - } - elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { - // literal string - return $this->_expand_quoted_text('"' . $val .'"'); - } - return $val; - } - - /** - * expand quoted text with embedded variables - * - * @param string $var_expr - * @return string - */ - function _expand_quoted_text($var_expr) - { - // if contains unescaped $, expand it - if(preg_match_all('~(?:\`(?_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?_parse_var(str_replace('`','',$_var)) . ')."', $var_expr); - } - $_return = preg_replace('~\.""|(?_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); - - if(count($_math_vars) > 1) { - $_first_var = ""; - $_complete_var = ""; - $_output = ""; - // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) - foreach($_math_vars as $_k => $_math_var) { - $_math_var = $_math_vars[$_k]; - - if(!empty($_math_var) || is_numeric($_math_var)) { - // hit a math operator, so process the stuff which came before it - if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { - $_has_math = true; - if(!empty($_complete_var) || is_numeric($_complete_var)) { - $_output .= $this->_parse_var($_complete_var); - } - - // just output the math operator to php - $_output .= $_math_var; - - if(empty($_first_var)) - $_first_var = $_complete_var; - - $_complete_var = ""; - } else { - $_complete_var .= $_math_var; - } - } - } - if($_has_math) { - if(!empty($_complete_var) || is_numeric($_complete_var)) - $_output .= $this->_parse_var($_complete_var); - - // get the modifiers working (only the last var from math + modifier is left) - $var_expr = $_complete_var; - } - } - - // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) - if(is_numeric($var_expr{0})) - $_var_ref = $var_expr; - else - $_var_ref = substr($var_expr, 1); - - if(!$_has_math) { - - // get [foo] and .foo and ->foo and (...) pieces - preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); - - $_indexes = $match[0]; - $_var_name = array_shift($_indexes); - - /* Handle $smarty.* variable references as a special case. */ - if ($_var_name == 'smarty') { - /* - * If the reference could be compiled, use the compiled output; - * otherwise, fall back on the $smarty variable generated at - * run-time. - */ - if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { - $_output = $smarty_ref; - } else { - $_var_name = substr(array_shift($_indexes), 1); - $_output = "\$this->_smarty_vars['$_var_name']"; - } - } elseif(is_numeric($_var_name) && is_numeric($var_expr{0})) { - // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers - if(count($_indexes) > 0) - { - $_var_name .= implode("", $_indexes); - $_indexes = array(); - } - $_output = $_var_name; - } else { - $_output = "\$this->_tpl_vars['$_var_name']"; - } - - foreach ($_indexes as $_index) { - if ($_index{0} == '[') { - $_index = substr($_index, 1, -1); - if (is_numeric($_index)) { - $_output .= "[$_index]"; - } elseif ($_index{0} == '$') { - if (strpos($_index, '.') !== false) { - $_output .= '[' . $this->_parse_var($_index) . ']'; - } else { - $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; - } - } else { - $_var_parts = explode('.', $_index); - $_var_section = $_var_parts[0]; - $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; - $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; - } - } else if ($_index{0} == '.') { - if ($_index{1} == '$') - $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; - else - $_output .= "['" . substr($_index, 1) . "']"; - } else if (substr($_index,0,2) == '->') { - if(substr($_index,2,2) == '__') { - $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } elseif($this->security && substr($_index, 2, 1) == '_') { - $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } elseif ($_index{2} == '$') { - if ($this->security) { - $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } else { - $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; - } - } else { - $_output .= $_index; - } - } elseif ($_index{0} == '(') { - $_index = $this->_parse_parenth_args($_index); - $_output .= $_index; - } else { - $_output .= $_index; - } - } - } - - return $_output; - } - - /** - * parse arguments in function call parenthesis - * - * @param string $parenth_args - * @return string - */ - function _parse_parenth_args($parenth_args) - { - preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); - $orig_vals = $match = $match[0]; - $this->_parse_vars_props($match); - $replace = array(); - for ($i = 0, $count = count($match); $i < $count; $i++) { - $replace[$orig_vals[$i]] = $match[$i]; - } - return strtr($parenth_args, $replace); - } - - /** - * parse configuration variable expression into PHP code - * - * @param string $conf_var_expr - */ - function _parse_conf_var($conf_var_expr) - { - $parts = explode('|', $conf_var_expr, 2); - $var_ref = $parts[0]; - $modifiers = isset($parts[1]) ? $parts[1] : ''; - - $var_name = substr($var_ref, 1, -1); - - $output = "\$this->_config[0]['vars']['$var_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - /** - * parse section property expression into PHP code - * - * @param string $section_prop_expr - * @return string - */ - function _parse_section_prop($section_prop_expr) - { - $parts = explode('|', $section_prop_expr, 2); - $var_ref = $parts[0]; - $modifiers = isset($parts[1]) ? $parts[1] : ''; - - preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); - $section_name = $match[1]; - $prop_name = $match[2]; - - $output = "\$this->_sections['$section_name']['$prop_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - - /** - * parse modifier chain into PHP code - * - * sets $output to parsed modified chain - * @param string $output - * @param string $modifier_string - */ - function _parse_modifiers(&$output, $modifier_string) - { - preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); - list(, $_modifiers, $modifier_arg_strings) = $_match; - - for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { - $_modifier_name = $_modifiers[$_i]; - - if($_modifier_name == 'smarty') { - // skip smarty modifier - continue; - } - - preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); - $_modifier_args = $_match[1]; - - if ($_modifier_name{0} == '@') { - $_map_array = false; - $_modifier_name = substr($_modifier_name, 1); - } else { - $_map_array = true; - } - - if (empty($this->_plugins['modifier'][$_modifier_name]) - && !$this->_get_plugin_filepath('modifier', $_modifier_name) - && function_exists($_modifier_name)) { - if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { - $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } else { - $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); - } - } - $this->_add_plugin('modifier', $_modifier_name); - - $this->_parse_vars_props($_modifier_args); - - if($_modifier_name == 'default') { - // supress notifications of default modifier vars and args - if($output{0} == '$') { - $output = '@' . $output; - } - if(isset($_modifier_args[0]) && $_modifier_args[0]{0} == '$') { - $_modifier_args[0] = '@' . $_modifier_args[0]; - } - } - if (count($_modifier_args) > 0) - $_modifier_args = ', '.implode(', ', $_modifier_args); - else - $_modifier_args = ''; - - if ($_map_array) { - $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; - - } else { - - $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; - - } - } - } - - - /** - * add plugin - * - * @param string $type - * @param string $name - * @param boolean? $delayed_loading - */ - function _add_plugin($type, $name, $delayed_loading = null) - { - if (!isset($this->_plugin_info[$type])) { - $this->_plugin_info[$type] = array(); - } - if (!isset($this->_plugin_info[$type][$name])) { - $this->_plugin_info[$type][$name] = array($this->_current_file, - $this->_current_line_no, - $delayed_loading); - } - } - - - /** - * Compiles references of type $smarty.foo - * - * @param string $indexes - * @return string - */ - function _compile_smarty_ref(&$indexes) - { - /* Extract the reference name. */ - $_ref = substr($indexes[0], 1); - foreach($indexes as $_index_no=>$_index) { - if ($_index{0} != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { - $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); - } - } - - switch ($_ref) { - case 'now': - $compiled_ref = 'time()'; - $_max_index = 1; - break; - - case 'foreach': - array_shift($indexes); - $_var = $this->_parse_var_props(substr($indexes[0], 1)); - $_propname = substr($indexes[1], 1); - $_max_index = 1; - switch ($_propname) { - case 'index': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; - break; - - case 'first': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; - break; - - case 'last': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; - break; - - case 'show': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; - break; - - default: - unset($_max_index); - $compiled_ref = "\$this->_foreach[$_var]"; - } - break; - - case 'section': - array_shift($indexes); - $_var = $this->_parse_var_props(substr($indexes[0], 1)); - $compiled_ref = "\$this->_sections[$_var]"; - break; - - case 'get': - $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']"; - break; - - case 'post': - $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']"; - break; - - case 'cookies': - $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']"; - break; - - case 'env': - $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']"; - break; - - case 'server': - $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']"; - break; - - case 'session': - $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']"; - break; - - /* - * These cases are handled either at run-time or elsewhere in the - * compiler. - */ - case 'request': - if ($this->request_use_auto_globals) { - $compiled_ref = '$_REQUEST'; - break; - } else { - $this->_init_smarty_vars = true; - } - return null; - - case 'capture': - return null; - - case 'template': - $compiled_ref = "'$this->_current_file'"; - $_max_index = 1; - break; - - case 'version': - $compiled_ref = "'$this->_version'"; - $_max_index = 1; - break; - - case 'const': - if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { - $this->_syntax_error("(secure mode) constants not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - array_shift($indexes); - if (preg_match('!^\.\w+$!', $indexes[0])) { - $compiled_ref = '@' . substr($indexes[0], 1); - } else { - $_val = $this->_parse_var_props(substr($indexes[0], 1)); - $compiled_ref = '@constant(' . $_val . ')'; - } - $_max_index = 1; - break; - - case 'config': - $compiled_ref = "\$this->_config[0]['vars']"; - $_max_index = 3; - break; - - case 'ldelim': - $compiled_ref = "'$this->left_delimiter'"; - break; - - case 'rdelim': - $compiled_ref = "'$this->right_delimiter'"; - break; - - default: - $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); - break; - } - - if (isset($_max_index) && count($indexes) > $_max_index) { - $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); - } - - array_shift($indexes); - return $compiled_ref; - } - - /** - * compiles call to plugin of type $type with name $name - * returns a string containing the function-name or method call - * without the paramter-list that would have follow to make the - * call valid php-syntax - * - * @param string $type - * @param string $name - * @return string - */ - function _compile_plugin_call($type, $name) { - if (isset($this->_plugins[$type][$name])) { - /* plugin loaded */ - if (is_array($this->_plugins[$type][$name][0])) { - return ((is_object($this->_plugins[$type][$name][0][0])) ? - "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ - : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ - ). $this->_plugins[$type][$name][0][1]; - - } else { - /* function callback */ - return $this->_plugins[$type][$name][0]; - - } - } else { - /* plugin not loaded -> auto-loadable-plugin */ - return 'smarty_'.$type.'_'.$name; - - } - } - - /** - * load pre- and post-filters - */ - function _load_filters() - { - if (count($this->_plugins['prefilter']) > 0) { - foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { - if ($prefilter === false) { - unset($this->_plugins['prefilter'][$filter_name]); - $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - } - } - } - if (count($this->_plugins['postfilter']) > 0) { - foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { - if ($postfilter === false) { - unset($this->_plugins['postfilter'][$filter_name]); - $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - } - } - } - } - - - /** - * Quote subpattern references - * - * @param string $string - * @return string - */ - function _quote_replace($string) - { - return strtr($string, array('\\' => '\\\\', '$' => '\\$')); - } - - /** - * display Smarty syntax error - * - * @param string $error_msg - * @param integer $error_type - * @param string $file - * @param integer $line - */ - function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) - { - $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); - } - - - /** - * check if the compilation changes from cacheable to - * non-cacheable state with the beginning of the current - * plugin. return php-code to reflect the transition. - * @return string - */ - function _push_cacheable_state($type, $name) { - $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; - if ($_cacheable - || 0<$this->_cacheable_state++) return ''; - if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); - $_ret = 'if ($this->caching && !$this->_cache_including) { echo \'{nocache:' - . $this->_cache_serial . '#' . $this->_nocache_count - . '}\';}'; - return $_ret; - } - - - /** - * check if the compilation changes from non-cacheable to - * cacheable state with the end of the current plugin return - * php-code to reflect the transition. - * @return string - */ - function _pop_cacheable_state($type, $name) { - $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; - if ($_cacheable - || --$this->_cacheable_state>0) return ''; - return 'if ($this->caching && !$this->_cache_including) { echo \'{/nocache:' - . $this->_cache_serial . '#' . ($this->_nocache_count++) - . '}\';}'; - } - - - /** - * push opening tag-name, file-name and line-number on the tag-stack - * @param string the opening tag's name - */ - function _push_tag($open_tag) - { - array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); - } - - /** - * pop closing tag-name - * raise an error if this stack-top doesn't match with the closing tag - * @param string the closing tag's name - * @return string the opening tag's name - */ - function _pop_tag($close_tag) - { - $message = ''; - if (count($this->_tag_stack)>0) { - list($_open_tag, $_line_no) = array_pop($this->_tag_stack); - if ($close_tag == $_open_tag) { - return $_open_tag; - } - if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { - return $this->_pop_tag($close_tag); - } - if ($close_tag == 'section' && $_open_tag == 'sectionelse') { - $this->_pop_tag($close_tag); - return $_open_tag; - } - if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { - $this->_pop_tag($close_tag); - return $_open_tag; - } - if ($_open_tag == 'else' || $_open_tag == 'elseif') { - $_open_tag = 'if'; - } elseif ($_open_tag == 'sectionelse') { - $_open_tag = 'section'; - } elseif ($_open_tag == 'foreachelse') { - $_open_tag = 'foreach'; - } - $message = " expected {/$_open_tag} (opened line $_line_no)."; - } - $this->_syntax_error("mismatched tag {/$close_tag}.$message", - E_USER_ERROR, __FILE__, __LINE__); - } - -} - -/** - * compare to values by their string length - * - * @access private - * @param string $a - * @param string $b - * @return 0|-1|1 - */ -function _smarty_sort_length($a, $b) -{ - if($a == $b) - return 0; - - if(strlen($a) == strlen($b)) - return ($a > $b) ? -1 : 1; - - return (strlen($a) > strlen($b)) ? -1 : 1; -} - - -/* vim: set et: */ - -?> + + * @author Andrei Zmievski + * @version 2.6.25-dev + * @copyright 2001-2005 New Digital Group, Inc. + * @package Smarty + */ + +/* $Id: Smarty_Compiler.class.php 4779 2013-09-30 19:14:32Z Uwe.Tews@googlemail.com $ */ + +/** + * Template compiling class + * @package Smarty + */ +class Smarty_Compiler extends Smarty { + + // internal vars + /**#@+ + * @access private + */ + var $_folded_blocks = array(); // keeps folded template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_capture_stack = array(); // keeps track of nested capture buffers + var $_plugin_info = array(); // keeps track of plugins to load + var $_init_smarty_vars = false; + var $_permitted_tokens = array('true','false','yes','no','on','off','null'); + var $_db_qstr_regexp = null; // regexps are setup in the constructor + var $_si_qstr_regexp = null; + var $_qstr_regexp = null; + var $_func_regexp = null; + var $_reg_obj_regexp = null; + var $_var_bracket_regexp = null; + var $_num_const_regexp = null; + var $_dvar_guts_regexp = null; + var $_dvar_regexp = null; + var $_cvar_regexp = null; + var $_svar_regexp = null; + var $_avar_regexp = null; + var $_mod_regexp = null; + var $_var_regexp = null; + var $_parenth_param_regexp = null; + var $_func_call_regexp = null; + var $_obj_ext_regexp = null; + var $_obj_start_regexp = null; + var $_obj_params_regexp = null; + var $_obj_call_regexp = null; + var $_cacheable_state = 0; + var $_cache_attrs_count = 0; + var $_nocache_count = 0; + var $_cache_serial = null; + var $_cache_include = null; + + var $_strip_depth = 0; + var $_additional_newline = "\n"; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty_Compiler() + { + // matches double quoted strings: + // "foobar" + // "foo\"bar" + $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; + + // matches single quoted strings: + // 'foobar' + // 'foo\'bar' + $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + // matches single or double quoted strings + $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; + + // matches bracket portion of vars + // [0] + // [foo] + // [$bar] + $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; + + // matches numerical constants + // 30 + // -12 + // 13.22 + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; + + // matches $ vars (not objects): + // $foo + // $foo.bar + // $foo.bar.foobar + // $foo[0] + // $foo[$bar] + // $foo[5][blah] + // $foo[5].bar[$foobar][4] + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; + $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; + $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; + $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; + + // matches config vars: + // #foo# + // #foobar123_foo# + $this->_cvar_regexp = '\#\w+\#'; + + // matches section vars: + // %foo.bar% + $this->_svar_regexp = '\%\w+\.\w+\%'; + + // matches all valid variables (no quotes, no modifiers) + $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' + . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; + + // matches valid variable syntax: + // $foo + // $foo + // #foo# + // #foo# + // "text" + // "text" + $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; + + // matches valid object call (one level of object nesting allowed in parameters): + // $foo->bar + // $foo->bar() + // $foo->bar("text") + // $foo->bar($foo, $bar, "text") + // $foo->bar($foo, "foo") + // $foo->bar->foo() + // $foo->bar->foo->bar() + // $foo->bar($foo->bar) + // $foo->bar($foo->bar()) + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) + $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; + $this->_obj_restricted_param_regexp = '(?:' + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; + $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; + + // matches valid modifier syntax: + // |foo + // |@foo + // |foo:"bar" + // |foo:$bar + // |foo:"bar":$foobar + // |foo|bar + // |foo:$foo->bar + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' + . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; + + // matches valid function name: + // foo123 + // _foo_bar + $this->_func_regexp = '[a-zA-Z_]\w*'; + + // matches valid registered object: + // foo->bar + $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; + + // matches valid parameter values: + // true + // $foo + // $foo|bar + // #foo# + // #foo#|bar + // "text" + // "text"|bar + // $foo->bar + $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; + + // matches valid parenthesised function parameters: + // + // "text" + // $foo, $bar, "text" + // $foo|bar, "foo"|bar, $foo->bar($foo)|bar + $this->_parenth_param_regexp = '(?:\((?:\w+|' + . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_param_regexp . ')))*)?\))'; + + // matches valid function call: + // foo() + // foo_bar($foo) + // _foo_bar($foo,"bar") + // foo123($foo,$foo->bar(),"foo") + $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' + . $this->_parenth_param_regexp . '))'; + } + + /** + * compile a resource + * + * sets $compiled_content to the compiled source + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return true + */ + function _compile_file($resource_name, $source_content, &$compiled_content) + { + + if ($this->security) { + // do not allow php syntax to be executed unless specified + if ($this->php_handling == SMARTY_PHP_ALLOW && + !$this->security_settings['PHP_HANDLING']) { + $this->php_handling = SMARTY_PHP_PASSTHRU; + } + } + + $this->_load_filters(); + + $this->_current_file = $resource_name; + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '~'); + $rdq = preg_quote($this->right_delimiter, '~'); + + // run template source through prefilter functions + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) continue; + if ($prefilter[3] || is_callable($prefilter[0])) { + $source_content = call_user_func_array($prefilter[0], + array($source_content, &$this)); + $this->_plugins['prefilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); + } + } + } + + /* fetch all special blocks */ + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; + + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); + $this->_folded_blocks = $match; + reset($this->_folded_blocks); + + /* replace special blocks by "{php}" */ + $source_content = preg_replace_callback($search, create_function ('$matches', "return '" + . $this->_quote_replace($this->left_delimiter) . 'php' + . "' . str_repeat(\"\n\", substr_count('\$matches[1]', \"\n\")) .'" + . $this->_quote_replace($this->right_delimiter) + . "';") + , $source_content); + + /* Gather all template tags. */ + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); + $template_tags = $_match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); + + /* loop through text blocks */ + for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { + /* match anything resembling php tags */ + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { + /* replace tags with placeholders to prevent recursive replacements */ + $sp_match[1] = array_unique($sp_match[1]); + usort($sp_match[1], '_smarty_sort_length'); + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); + } + /* process each one */ + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + if ($this->php_handling == SMARTY_PHP_PASSTHRU) { + /* echo php contents */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', ''."\n", $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_QUOTE) { + /* quote php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_REMOVE) { + /* remove php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); + } else { + /* SMARTY_PHP_ALLOW, but echo non php starting tags */ + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', ''."\n", $sp_match[1][$curr_sp]); + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); + } + } + } + } + + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = end($this->_tag_stack); + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); + return; + } + + /* Reformat $text_blocks between 'strip' and '/strip' tags, + removing spaces, tabs and newlines. */ + $strip = false; + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '{strip}') { + $compiled_tags[$i] = ''; + $strip = true; + /* remove leading whitespaces */ + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); + } + if ($strip) { + /* strip all $text_blocks before the next '/strip' */ + for ($j = $i + 1; $j < $for_max; $j++) { + /* remove leading and trailing whitespaces of each line */ + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); + if ($compiled_tags[$j] == '{/strip}') { + /* remove trailing whitespaces from the last text_block */ + $text_blocks[$j] = rtrim($text_blocks[$j]); + } + $text_blocks[$j] = ""\'", "\\"=>"\\\\")) . "'; ?>"; + if ($compiled_tags[$j] == '{/strip}') { + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary + if a newline is following the closing strip-tag */ + $strip = false; + $i = $j; + break; + } + } + } + } + $compiled_content = ''; + + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '') { + // tag result empty, remove first newline from following text block + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); + } + // replace legit PHP tags with placeholder + $text_blocks[$i] = str_replace('\n", $compiled_content); + $compiled_content = preg_replace("~(?\n", $compiled_content); + + // recover legit tags + $compiled_content = str_replace($tag_guard, '_cache_serial)) { + $compiled_content = "_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; + } + + // run compiled template through postfilter functions + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) continue; + if ($postfilter[3] || is_callable($postfilter[0])) { + $compiled_content = call_user_func_array($postfilter[0], + array($compiled_content, &$this)); + $this->_plugins['postfilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); + } + } + } + + // put header at the top of the compiled template + $template_header = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; + + /* Emit code to load needed plugins. */ + $this->_plugins_code = ''; + if (count($this->_plugin_info)) { + $_plugins_params = "array('plugins' => array("; + foreach ($this->_plugin_info as $plugin_type => $plugins) { + foreach ($plugins as $plugin_name => $plugin_info) { + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; + $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; + } + } + $_plugins_params .= '))'; + $plugins_code = "\n"; + $template_header .= $plugins_code; + $this->_plugin_info = array(); + $this->_plugins_code = $plugins_code; + } + + if ($this->_init_smarty_vars) { + $template_header .= "\n"; + $this->_init_smarty_vars = false; + } + + $compiled_content = $template_header . $compiled_content; + return true; + } + + /** + * Compile a template tag + * + * @param string $template_tag + * @return string + */ + function _compile_tag($template_tag) + { + /* Matched comment. */ + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') + return ''; + + /* Split tag into two three parts: command, command modifiers and the arguments. */ + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp + . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) + (?:\s+(.*))?$ + ~xs', $template_tag, $match)) { + $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $tag_command = $match[1]; + $tag_modifier = isset($match[2]) ? $match[2] : null; + $tag_args = isset($match[3]) ? $match[3] : null; + + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { + /* tag name is a variable or object */ + $_return = $this->_parse_var_props($tag_command . $tag_modifier); + return "" . $this->_additional_newline; + } + + /* If the tag name is a registered object, we process it. */ + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { + return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'include_php': + return $this->_compile_include_php_tag($tag_args); + + case 'if': + $this->_push_tag('if'); + return $this->_compile_if_tag($tag_args); + + case 'else': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); + else + $this->_push_tag('else'); + return ''; + + case 'elseif': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); + if ($_open_tag == 'if') + $this->_push_tag('elseif'); + return $this->_compile_if_tag($tag_args, true); + + case '/if': + $this->_pop_tag('if'); + return ''; + + case 'capture': + return $this->_compile_capture_tag(true, $tag_args); + + case '/capture': + return $this->_compile_capture_tag(false); + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + $this->_push_tag('section'); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_push_tag('sectionelse'); + return ""; + break; + + case '/section': + $_open_tag = $this->_pop_tag('section'); + if ($_open_tag == 'sectionelse') + return ""; + else + return ""; + + case 'foreach': + $this->_push_tag('foreach'); + return $this->_compile_foreach_start($tag_args); + break; + + case 'foreachelse': + $this->_push_tag('foreachelse'); + return ""; + + case '/foreach': + $_open_tag = $this->_pop_tag('foreach'); + if ($_open_tag == 'foreachelse') + return ""; + else + return ""; + break; + + case 'strip': + case '/strip': + if (substr($tag_command, 0, 1)=='/') { + $this->_pop_tag('strip'); + if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ + $this->_additional_newline = "\n"; + return '{' . $tag_command . '}'; + } + } else { + $this->_push_tag('strip'); + if ($this->_strip_depth++==0) { /* outermost opening {strip} */ + $this->_additional_newline = ""; + return '{' . $tag_command . '}'; + } + } + return ''; + + case 'php': + /* handle folded tags replaced by {php} */ + list(, $block) = each($this->_folded_blocks); + $this->_current_line_no += substr_count($block[0], "\n"); + /* the number of matched elements in the regexp in _compile_file() + determins the type of folded tag that was found */ + switch (count($block)) { + case 2: /* comment */ + return ''; + + case 3: /* literal */ + return ""\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; + + case 4: /* php */ + if ($this->security && !$this->security_settings['PHP_TAGS']) { + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); + return; + } + return ''; + } + break; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { + return $output; + } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else { + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); + } + + } + } + + + /** + * compile the custom compiler tag + * + * sets $output to the compiled custom compiler tag + * @param string $tag_command + * @param string $tag_args + * @param string $output + * @return boolean + */ + function _compile_compiler_tag($tag_command, $tag_args, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the compiler function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['compiler'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['compiler'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "compiler function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_compiler_' . $tag_command; + if (!is_callable($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); + } + } + + /* + * True return value means that we either found a plugin or a + * dynamically registered function. False means that we didn't and the + * compiler should now emit code to load custom function plugin for this + * tag. + */ + if ($found) { + if ($have_function) { + $output = call_user_func_array($plugin_func, array($tag_args, &$this)); + if($output != '') { + $output = '_push_cacheable_state('compiler', $tag_command) + . $output + . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; + } + } else { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + } + return true; + } else { + return false; + } + } + + + /** + * compile block function tag + * + * sets $output to compiled block function tag + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @param string $output + * @return boolean + */ + function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else + $start_tag = true; + + $found = false; + $have_function = true; + + /* + * First we check if the block function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['block'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['block'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "block function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_block_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* + * Even though we've located the plugin function, compilation + * happens only once, so the plugin will still need to be loaded + * at runtime for future requests. + */ + $this->_add_plugin('block', $tag_command); + + if ($start_tag) + $this->_push_tag($tag_command); + else + $this->_pop_tag($tag_command); + + if ($start_tag) { + $output = '_push_cacheable_state('block', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs=''; + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; + $output .= 'while ($_block_repeat) { ob_start(); ?>'; + } else { + $output = '_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; + if ($tag_modifier != '') { + $this->_parse_modifiers($_out_tag_text, $tag_modifier); + } + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; + $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; + } + + return true; + } + + + /** + * compile custom function tag + * + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @return string + */ + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the custom function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['function'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['function'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "custom function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_function_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* declare plugin to be loaded on display of the template that + we compile right now */ + $this->_add_plugin('function', $tag_command); + + $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs = ''; + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); + + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; + if($tag_modifier != '') { + $this->_parse_modifiers($output, $tag_modifier); + } + + if($output != '') { + $output = '_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; + } + + return true; + } + + /** + * compile a registered object tag + * + * @param string $tag_command + * @param array $attrs + * @param string $tag_modifier + * @return string + */ + function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else { + $start_tag = true; + } + + list($object, $obj_comp) = explode('->', $tag_command); + + $arg_list = array(); + if(count($attrs)) { + $_assign_var = false; + foreach ($attrs as $arg_name => $arg_value) { + if($arg_name == 'assign') { + $_assign_var = $arg_value; + unset($attrs['assign']); + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + if($this->_reg_objects[$object][2]) { + // smarty object argument format + $args = "array(".implode(',', (array)$arg_list)."), \$this"; + } else { + // traditional argument format + $args = implode(',', array_values($attrs)); + if (empty($args)) { + $args = ''; + } + } + + $prefix = ''; + $postfix = ''; + $newline = ''; + if(!is_object($this->_reg_objects[$object][0])) { + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { + // method + if(in_array($obj_comp, $this->_reg_objects[$object][3])) { + // block method + if ($start_tag) { + $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; + $prefix .= "while (\$_block_repeat) { ob_start();"; + $return = null; + $postfix = ''; + } else { + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; + $postfix = "} array_pop(\$this->_tag_stack);"; + } + } else { + // non-block method + $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; + } + } else { + // property + $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; + } + + if($return != null) { + if($tag_modifier != '') { + $this->_parse_modifiers($return, $tag_modifier); + } + + if(!empty($_assign_var)) { + $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; + } else { + $output = 'echo ' . $return . ';'; + $newline = $this->_additional_newline; + } + } else { + $output = ''; + } + + return '" . $newline; + } + + /** + * Compile {insert ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!preg_match('~^\w+$~', $name)) { + return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!empty($attrs['script'])) { + $delayed_loading = true; + } else { + $delayed_loading = false; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $this->_add_plugin('insert', $name, $delayed_loading); + + $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; + + return "" . $this->_additional_newline; + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); + } + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') { + $include_file = $arg_value; + continue; + } else if ($arg_name == 'assign') { + $assign_var = $arg_value; + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $output = '_tpl_vars;\n"; + + + $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; + $output .= "\$this->_smarty_include($_params);\n" . + "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . + "unset(\$_smarty_tpl_vars);\n"; + + if (isset($assign_var)) { + $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; + } + + $output .= ' ?>'; + + return $output; + + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_php_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); + $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; + + $arg_list = array(); + foreach($attrs as $arg_name => $arg_value) { + if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { + if(is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; + + return "" . $this->_additional_newline; + } + + + /** + * Compile {section ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + $output = '_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); + } + + $output .= "unset(\$this->_sections[$section_name]);\n"; + $section_props = "\$this->_sections[$section_name]"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $show_attr_value = $attr_value ? 'true' : 'false'; + else + $show_attr_value = "(bool)$attr_value"; + $output .= "{$section_props}['show'] = $show_attr_value;\n"; + break; + + case 'name': + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + case 'max': + case 'start': + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; + break; + + case 'step': + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; + break; + + default: + $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + } + + if (!isset($attrs['show'])) + $output .= "{$section_props}['show'] = true;\n"; + + if (!isset($attrs['loop'])) + $output .= "{$section_props}['loop'] = 1;\n"; + + if (!isset($attrs['max'])) + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; + else + $output .= "if ({$section_props}['max'] < 0)\n" . + " {$section_props}['max'] = {$section_props}['loop'];\n"; + + if (!isset($attrs['step'])) + $output .= "{$section_props}['step'] = 1;\n"; + + if (!isset($attrs['start'])) + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; + else { + $output .= "if ({$section_props}['start'] < 0)\n" . + " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . + "else\n" . + " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; + } + + $output .= "if ({$section_props}['show']) {\n"; + if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; + } else { + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; + } + $output .= " if ({$section_props}['total'] == 0)\n" . + " {$section_props}['show'] = false;\n" . + "} else\n" . + " {$section_props}['total'] = 0;\n"; + + $output .= "if ({$section_props}['show']):\n"; + $output .= " + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; + {$section_props}['iteration'] <= {$section_props}['total']; + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; + + $output .= "?>"; + + return $output; + } + + + /** + * Compile {foreach ...} tag. + * + * @param string $tag_args + * @return string + */ + function _compile_foreach_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['from'])) { + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $from = $attrs['from']; + + if (empty($attrs['item'])) { + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $item = $this->_dequote($attrs['item']); + if (!preg_match('~^\w+$~', $item)) { + return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($attrs['key'])) { + $key = $this->_dequote($attrs['key']); + if (!preg_match('~^\w+$~', $key)) { + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + $key_part = "\$this->_tpl_vars['$key'] => "; + } else { + $key = null; + $key_part = ''; + } + + if (isset($attrs['name'])) { + $name = $attrs['name']; + } else { + $name = null; + } + + $output = '_foreach[$name]"; + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; + $output .= "if ({$foreach_props}['total'] > 0):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + $output .= " {$foreach_props}['iteration']++;\n"; + } else { + $output .= "if (count(\$_from)):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + } + $output .= '?>'; + + return $output; + } + + + /** + * Compile {capture} .. {/capture} tags + * + * @param boolean $start true if this is the {capture} tag + * @param string $tag_args + * @return string + */ + + function _compile_capture_tag($start, $tag_args = '') + { + $attrs = $this->_parse_attrs($tag_args); + + if ($start) { + $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; + $assign = isset($attrs['assign']) ? $attrs['assign'] : null; + $append = isset($attrs['append']) ? $attrs['append'] : null; + + $output = ""; + $this->_capture_stack[] = array($buffer, $assign, $append); + } else { + list($buffer, $assign, $append) = array_pop($this->_capture_stack); + $output = "_smarty_vars['capture'][$buffer] = ob_get_contents(); "; + if (isset($assign)) { + $output .= " \$this->assign($assign, ob_get_contents());"; + } + if (isset($append)) { + $output .= " \$this->append($append, ob_get_contents());"; + } + $output .= "ob_end_clean(); ?>"; + } + + return $output; + } + + /** + * Compile {if ...} tag + * + * @param string $tag_args + * @param boolean $elseif if true, uses elseif instead of if + * @return string + */ + function _compile_if_tag($tag_args, $elseif = false) + { + + /* Tokenize args for 'if' tag. */ + preg_match_all('~(?> + ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call + ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string + \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token + \b\w+\b | # valid word token + \S+ # anything else + )~x', $tag_args, $match); + + $tokens = $match[0]; + + if(empty($tokens)) { + $_error_msg = $elseif ? "'elseif'" : "'if'"; + $_error_msg .= ' statement requires arguments'; + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); + } + + + // make sure we have balanced parenthesis + $token_count = array_count_values($tokens); + if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { + $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + + $token = &$tokens[$i]; + + switch (strtolower($token)) { + case '!': + case '%': + case '!==': + case '==': + case '===': + case '>': + case '<': + case '!=': + case '<>': + case '<<': + case '>>': + case '<=': + case '>=': + case '&&': + case '||': + case '|': + case '^': + case '&': + case '~': + case ')': + case ',': + case '+': + case '-': + case '*': + case '/': + case '@': + break; + + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') { + $is_arg_start = array_pop($is_arg_stack); + if ($is_arg_start != 0) { + if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { + $is_arg_start--; + } + } + } else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + + default: + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { + // function call + if($this->security && + !in_array($token, $this->security_settings['IF_FUNCS'])) { + $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { + // variable function call + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { + // object or variable + $token = $this->_parse_var_props($token); + } elseif(is_numeric($token)) { + // number, skip it + } else { + $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + } + } + + if ($elseif) + return ''; + else + return ''; + } + + + function _compile_arg_list($type, $name, $attrs, &$cache_code) { + $arg_list = array(); + + if (isset($type) && isset($name) + && isset($this->_plugins[$type]) + && isset($this->_plugins[$type][$name]) + && empty($this->_plugins[$type][$name][4]) + && is_array($this->_plugins[$type][$name][5]) + ) { + /* we have a list of parameters that should be cached */ + $_cache_attrs = $this->_plugins[$type][$name][5]; + $_count = $this->_cache_attrs_count++; + $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; + + } else { + /* no parameters are cached */ + $_cache_attrs = null; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + if (is_null($arg_value)) + $arg_value = 'null'; + if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { + $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; + } else { + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + return $arg_list; + } + + /** + * Parse is expression + * + * @param string $is_arg + * @param array $tokens + * @return array + */ + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + $negate_expr = false; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "!(1 & $is_arg)"; + break; + + case 'odd': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "(1 & $is_arg)"; + break; + + case 'div': + if (@$tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; + } else { + $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + + /** + * Parse attribute string + * + * @param string $tag_args + * @return array + */ + function _parse_attrs($tag_args) + { + + /* Tokenize tag attributes. */ + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) + )+ | + [=] + ~x', $tag_args, $match); + $tokens = $match[0]; + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('~^\w+$~', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('~^(on|yes|true)$~', $token)) { + $token = 'true'; + } else if (preg_match('~^(off|no|false)$~', $token)) { + $token = 'false'; + } else if ($token == 'null') { + $token = 'null'; + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { + /* treat integer literally */ + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { + /* treat as a string, double-quote it escaping quotes */ + $token = '"'.addslashes($token).'"'; + } + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); + break; + } + $last_token = $token; + } + + if($state != 0) { + if($state == 1) { + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + } else { + $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + /** + * compile multiple variables and section properties tokens into + * PHP code + * + * @param array $tokens + */ + function _parse_vars_props(&$tokens) + { + foreach($tokens as $key => $val) { + $tokens[$key] = $this->_parse_var_props($val); + } + } + + /** + * compile single variable and section properties token into + * PHP code + * + * @param string $val + * @param string $tag_attrs + * @return string + */ + function _parse_var_props($val) + { + $val = trim($val); + + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { + // $ variable or object + $return = $this->_parse_var($match[1]); + $modifiers = $match[2]; + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { + $_default_mod_string = implode('|',(array)$this->default_modifiers); + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; + } + $this->_parse_modifiers($return, $modifiers); + return $return; + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // double quoted text + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + $return = $this->_expand_quoted_text($match[1]); + if($match[2] != '') { + $this->_parse_modifiers($return, $match[2]); + } + return $return; + } + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // numerical constant + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // single quoted text + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // config var + return $this->_parse_conf_var($val); + } + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // section var + return $this->_parse_section_prop($val); + } + elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { + // literal string + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); + } + return $val; + } + + /** + * expand quoted text with embedded variables + * + * @param string $var_expr + * @return string + */ + function _expand_quoted_text($var_expr) + { + // if contains unescaped $, expand it + if(preg_match_all('~(?:\`(?_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?_parse_var(str_replace('`','',$_var)) . ')."'; + } + $var_expr = strtr($var_expr, $_replace); + $_return = preg_replace('~\.""|(?_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); + + if(count($_math_vars) > 1) { + $_first_var = ""; + $_complete_var = ""; + $_output = ""; + // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) + foreach($_math_vars as $_k => $_math_var) { + $_math_var = $_math_vars[$_k]; + + if(!empty($_math_var) || is_numeric($_math_var)) { + // hit a math operator, so process the stuff which came before it + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { + $_has_math = true; + if(!empty($_complete_var) || is_numeric($_complete_var)) { + $_output .= $this->_parse_var($_complete_var); + } + + // just output the math operator to php + $_output .= $_math_var; + + if(empty($_first_var)) + $_first_var = $_complete_var; + + $_complete_var = ""; + } else { + $_complete_var .= $_math_var; + } + } + } + if($_has_math) { + if(!empty($_complete_var) || is_numeric($_complete_var)) + $_output .= $this->_parse_var($_complete_var); + + // get the modifiers working (only the last var from math + modifier is left) + $var_expr = $_complete_var; + } + } + + // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) + if(is_numeric(substr($var_expr, 0, 1))) + $_var_ref = $var_expr; + else + $_var_ref = substr($var_expr, 1); + + if(!$_has_math) { + + // get [foo] and .foo and ->foo and (...) pieces + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); + + $_indexes = $match[0]; + $_var_name = array_shift($_indexes); + + /* Handle $smarty.* variable references as a special case. */ + if ($_var_name == 'smarty') { + /* + * If the reference could be compiled, use the compiled output; + * otherwise, fall back on the $smarty variable generated at + * run-time. + */ + if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { + $_output = $smarty_ref; + } else { + $_var_name = substr(array_shift($_indexes), 1); + $_output = "\$this->_smarty_vars['$_var_name']"; + } + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { + // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers + if(count($_indexes) > 0) + { + $_var_name .= implode("", $_indexes); + $_indexes = array(); + } + $_output = $_var_name; + } else { + $_output = "\$this->_tpl_vars['$_var_name']"; + } + + foreach ($_indexes as $_index) { + if (substr($_index, 0, 1) == '[') { + $_index = substr($_index, 1, -1); + if (is_numeric($_index)) { + $_output .= "[$_index]"; + } elseif (substr($_index, 0, 1) == '$') { + if (strpos($_index, '.') !== false) { + $_output .= '[' . $this->_parse_var($_index) . ']'; + } else { + $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; + } + } else { + $_var_parts = explode('.', $_index); + $_var_section = $_var_parts[0]; + $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; + $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; + } + } else if (substr($_index, 0, 1) == '.') { + if (substr($_index, 1, 1) == '$') + $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; + else + $_output .= "['" . substr($_index, 1) . "']"; + } else if (substr($_index,0,2) == '->') { + if(substr($_index,2,2) == '__') { + $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif($this->security && substr($_index, 2, 1) == '_') { + $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif (substr($_index, 2, 1) == '$') { + if ($this->security) { + $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } else { + $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; + } + } else { + $_output .= $_index; + } + } elseif (substr($_index, 0, 1) == '(') { + $_index = $this->_parse_parenth_args($_index); + $_output .= $_index; + } else { + $_output .= $_index; + } + } + } + + return $_output; + } + + /** + * parse arguments in function call parenthesis + * + * @param string $parenth_args + * @return string + */ + function _parse_parenth_args($parenth_args) + { + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); + $orig_vals = $match = $match[0]; + $this->_parse_vars_props($match); + $replace = array(); + for ($i = 0, $count = count($match); $i < $count; $i++) { + $replace[$orig_vals[$i]] = $match[$i]; + } + return strtr($parenth_args, $replace); + } + + /** + * parse configuration variable expression into PHP code + * + * @param string $conf_var_expr + */ + function _parse_conf_var($conf_var_expr) + { + $parts = explode('|', $conf_var_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + $var_name = substr($var_ref, 1, -1); + + $output = "\$this->_config[0]['vars']['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + /** + * parse section property expression into PHP code + * + * @param string $section_prop_expr + * @return string + */ + function _parse_section_prop($section_prop_expr) + { + $parts = explode('|', $section_prop_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$this->_sections['$section_name']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + + /** + * parse modifier chain into PHP code + * + * sets $output to parsed modified chain + * @param string $output + * @param string $modifier_string + */ + function _parse_modifiers(&$output, $modifier_string) + { + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); + list(, $_modifiers, $modifier_arg_strings) = $_match; + + for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { + $_modifier_name = $_modifiers[$_i]; + + if($_modifier_name == 'smarty') { + // skip smarty modifier + continue; + } + + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); + $_modifier_args = $_match[1]; + + if (substr($_modifier_name, 0, 1) == '@') { + $_map_array = false; + $_modifier_name = substr($_modifier_name, 1); + } else { + $_map_array = true; + } + + if (empty($this->_plugins['modifier'][$_modifier_name]) + && !$this->_get_plugin_filepath('modifier', $_modifier_name) + && function_exists($_modifier_name)) { + if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } else { + $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); + } + } + $this->_add_plugin('modifier', $_modifier_name); + + $this->_parse_vars_props($_modifier_args); + + if($_modifier_name == 'default') { + // supress notifications of default modifier vars and args + if(substr($output, 0, 1) == '$') { + $output = '@' . $output; + } + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { + $_modifier_args[0] = '@' . $_modifier_args[0]; + } + } + if (count($_modifier_args) > 0) + $_modifier_args = ', '.implode(', ', $_modifier_args); + else + $_modifier_args = ''; + + if ($_map_array) { + $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; + + } else { + + $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; + + } + } + } + + + /** + * add plugin + * + * @param string $type + * @param string $name + * @param boolean? $delayed_loading + */ + function _add_plugin($type, $name, $delayed_loading = null) + { + if (!isset($this->_plugin_info[$type])) { + $this->_plugin_info[$type] = array(); + } + if (!isset($this->_plugin_info[$type][$name])) { + $this->_plugin_info[$type][$name] = array($this->_current_file, + $this->_current_line_no, + $delayed_loading); + } + } + + + /** + * Compiles references of type $smarty.foo + * + * @param string $indexes + * @return string + */ + function _compile_smarty_ref(&$indexes) + { + /* Extract the reference name. */ + $_ref = substr($indexes[0], 1); + foreach($indexes as $_index_no=>$_index) { + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { + $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + } + + switch ($_ref) { + case 'now': + $compiled_ref = 'time()'; + $_max_index = 1; + break; + + case 'foreach': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $_propname = substr($indexes[1], 1); + $_max_index = 1; + switch ($_propname) { + case 'index': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; + break; + + case 'first': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; + break; + + case 'last': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; + break; + + case 'show': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; + break; + + default: + unset($_max_index); + $compiled_ref = "\$this->_foreach[$_var]"; + } + break; + + case 'section': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = "\$this->_sections[$_var]"; + break; + + case 'get': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_GET"; + break; + + case 'post': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_POST"; + break; + + case 'cookies': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_COOKIE"; + break; + + case 'env': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_ENV"; + break; + + case 'server': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_SERVER"; + break; + + case 'session': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + $compiled_ref = "\$_SESSION"; + break; + + /* + * These cases are handled either at run-time or elsewhere in the + * compiler. + */ + case 'request': + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { + $this->_syntax_error("(secure mode) super global access not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + if ($this->request_use_auto_globals) { + $compiled_ref = "\$_REQUEST"; + break; + } else { + $this->_init_smarty_vars = true; + } + return null; + + case 'capture': + return null; + + case 'template': + $compiled_ref = "'" . addslashes($this->_current_file) . "'"; + $_max_index = 1; + break; + + case 'version': + $compiled_ref = "'$this->_version'"; + $_max_index = 1; + break; + + case 'const': + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { + $this->_syntax_error("(secure mode) constants not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + array_shift($indexes); + if (preg_match('!^\.\w+$!', $indexes[0])) { + $compiled_ref = '@' . substr($indexes[0], 1); + } else { + $_val = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = '@constant(' . $_val . ')'; + } + $_max_index = 1; + break; + + case 'config': + $compiled_ref = "\$this->_config[0]['vars']"; + $_max_index = 3; + break; + + case 'ldelim': + $compiled_ref = "'$this->left_delimiter'"; + break; + + case 'rdelim': + $compiled_ref = "'$this->right_delimiter'"; + break; + + default: + $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if (isset($_max_index) && count($indexes) > $_max_index) { + $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + + array_shift($indexes); + return $compiled_ref; + } + + /** + * compiles call to plugin of type $type with name $name + * returns a string containing the function-name or method call + * without the paramter-list that would have follow to make the + * call valid php-syntax + * + * @param string $type + * @param string $name + * @return string + */ + function _compile_plugin_call($type, $name) { + if (isset($this->_plugins[$type][$name])) { + /* plugin loaded */ + if (is_array($this->_plugins[$type][$name][0])) { + return ((is_object($this->_plugins[$type][$name][0][0])) ? + "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ + : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ + ). $this->_plugins[$type][$name][0][1]; + + } else { + /* function callback */ + return $this->_plugins[$type][$name][0]; + + } + } else { + /* plugin not loaded -> auto-loadable-plugin */ + return 'smarty_'.$type.'_'.$name; + + } + } + + /** + * load pre- and post-filters + */ + function _load_filters() + { + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) { + unset($this->_plugins['prefilter'][$filter_name]); + $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) { + unset($this->_plugins['postfilter'][$filter_name]); + $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + } + + + /** + * Quote subpattern references + * + * @param string $string + * @return string + */ + function _quote_replace($string) + { + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); + } + + /** + * display Smarty syntax error + * + * @param string $error_msg + * @param integer $error_type + * @param string $file + * @param integer $line + */ + function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) + { + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); + } + + + /** + * check if the compilation changes from cacheable to + * non-cacheable state with the beginning of the current + * plugin. return php-code to reflect the transition. + * @return string + */ + function _push_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || 0<$this->_cacheable_state++) return ''; + if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); + $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' + . $this->_cache_serial . '#' . $this->_nocache_count + . '}\'; endif;'; + return $_ret; + } + + + /** + * check if the compilation changes from non-cacheable to + * cacheable state with the end of the current plugin return + * php-code to reflect the transition. + * @return string + */ + function _pop_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || --$this->_cacheable_state>0) return ''; + return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' + . $this->_cache_serial . '#' . ($this->_nocache_count++) + . '}\'; endif;'; + } + + + /** + * push opening tag-name, file-name and line-number on the tag-stack + * @param string the opening tag's name + */ + function _push_tag($open_tag) + { + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); + } + + /** + * pop closing tag-name + * raise an error if this stack-top doesn't match with the closing tag + * @param string the closing tag's name + * @return string the opening tag's name + */ + function _pop_tag($close_tag) + { + $message = ''; + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); + if ($close_tag == $_open_tag) { + return $_open_tag; + } + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { + return $this->_pop_tag($close_tag); + } + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($_open_tag == 'else' || $_open_tag == 'elseif') { + $_open_tag = 'if'; + } elseif ($_open_tag == 'sectionelse') { + $_open_tag = 'section'; + } elseif ($_open_tag == 'foreachelse') { + $_open_tag = 'foreach'; + } + $message = " expected {/$_open_tag} (opened line $_line_no)."; + } + $this->_syntax_error("mismatched tag {/$close_tag}.$message", + E_USER_ERROR, __FILE__, __LINE__); + } + +} + +/** + * compare to values by their string length + * + * @access private + * @param string $a + * @param string $b + * @return 0|-1|1 + */ +function _smarty_sort_length($a, $b) +{ + if($a == $b) + return 0; + + if(strlen($a) == strlen($b)) + return ($a > $b) ? -1 : 1; + + return (strlen($a) > strlen($b)) ? -1 : 1; +} + + +/* vim: set et: */ + +?> diff --git a/code/web/public_php/admin/smarty/debug.tpl b/code/web/public_php/admin/smarty/debug.tpl index 7f1c9d425..c05ef5d0b 100644 --- a/code/web/public_php/admin/smarty/debug.tpl +++ b/code/web/public_php/admin/smarty/debug.tpl @@ -1,64 +1,157 @@ {* Smarty *} +{* debug.tpl, last updated version 2.1.0 *} +{assign_debug_info} +{capture assign=debug_output} + + + + Smarty Debug Console +{literal} + +{/literal} + + + +

Smarty Debug Console

+ +

included templates & config files (load time in seconds)

+ +
+{section name=templates loop=$_debug_tpls} + {section name=indent loop=$_debug_tpls[templates].depth}   {/section} + + {$_debug_tpls[templates].filename|escape:html} + {if isset($_debug_tpls[templates].exec_time)} + + ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) + {if %templates.index% eq 0}(total){/if} + + {/if} +
+{sectionelse} +

no templates included

+{/section} +
+ +

assigned template variables

+ + + {section name=vars loop=$_debug_keys} + + + + {sectionelse} + + {/section} +
{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}{$_debug_vals[vars]|@debug_print_var}

no template variables assigned

+ +

assigned config file variables (outer template scope)

+ + {section name=config_vars loop=$_debug_config_keys} + + + + {sectionelse} + + {/section} +
{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}{$_debug_config_vals[config_vars]|@debug_print_var}

no config vars assigned

+ + +{/capture} {if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} - - - - {section name=templates loop=$_debug_tpls} - - {sectionelse} - - {/section} - - {section name=vars loop=$_debug_keys} - - {sectionelse} - - {/section} - - {section name=config_vars loop=$_debug_config_keys} - - {sectionelse} - - {/section} -
Smarty Debug Console
included templates & config files (load time in seconds):
{section name=indent loop=$_debug_tpls[templates].depth}   {/section}{$_debug_tpls[templates].filename|escape:html}{if isset($_debug_tpls[templates].exec_time)} ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}){if %templates.index% eq 0} (total){/if}{/if}
no templates included
assigned template variables:
{ldelim}${$_debug_keys[vars]}{rdelim}{$_debug_vals[vars]|@debug_print_var}
no template variables assigned
assigned config file variables (outer template scope):
{ldelim}#{$_debug_config_keys[config_vars]}#{rdelim}{$_debug_config_vals[config_vars]|@debug_print_var}
no config vars assigned
- + {$debug_output} {else} - -{/if} + +{/if} \ No newline at end of file diff --git a/code/web/public_php/admin/smarty/internals/core.create_dir_structure.php b/code/web/public_php/admin/smarty/internals/core.create_dir_structure.php index 999cf5930..3eecc4972 100644 --- a/code/web/public_php/admin/smarty/internals/core.create_dir_structure.php +++ b/code/web/public_php/admin/smarty/internals/core.create_dir_structure.php @@ -22,7 +22,7 @@ function smarty_core_create_dir_structure($params, &$smarty) /* unix-style paths */ $_dir = $params['dir']; $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY); - $_new_dir = ($_dir{0}=='/') ? '/' : getcwd().'/'; + $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/'; if($_use_open_basedir = !empty($_open_basedir_ini)) { $_open_basedirs = explode(':', $_open_basedir_ini); } diff --git a/code/web/public_php/admin/smarty/internals/core.display_debug_console.php b/code/web/public_php/admin/smarty/internals/core.display_debug_console.php index a5d72913c..1a80f3909 100644 --- a/code/web/public_php/admin/smarty/internals/core.display_debug_console.php +++ b/code/web/public_php/admin/smarty/internals/core.display_debug_console.php @@ -23,7 +23,7 @@ function smarty_core_display_debug_console($params, &$smarty) // set path to debug template from SMARTY_DIR $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; if($smarty->security && is_file($smarty->debug_tpl)) { - $smarty->secure_dir[] = dirname(realpath($smarty->debug_tpl)); + $smarty->secure_dir[] = realpath($smarty->debug_tpl); } $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; } diff --git a/code/web/public_php/admin/smarty/internals/core.is_secure.php b/code/web/public_php/admin/smarty/internals/core.is_secure.php index 342f3aff8..d54abd432 100644 --- a/code/web/public_php/admin/smarty/internals/core.is_secure.php +++ b/code/web/public_php/admin/smarty/internals/core.is_secure.php @@ -27,18 +27,21 @@ function smarty_core_is_secure($params, &$smarty) foreach ((array)$params['resource_base_path'] as $curr_dir) { if ( ($_cd = realpath($curr_dir)) !== false && strncmp($_rp, $_cd, strlen($_cd)) == 0 && - $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { return true; } } } if (!empty($smarty->secure_dir)) { foreach ((array)$smarty->secure_dir as $curr_dir) { - if ( ($_cd = realpath($curr_dir)) !== false && - strncmp($_rp, $_cd, strlen($_cd)) == 0 && - $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { - return true; - } + if ( ($_cd = realpath($curr_dir)) !== false) { + if($_cd == $_rp) { + return true; + } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { + return true; + } + } } } } else { diff --git a/code/web/public_php/admin/smarty/internals/core.is_trusted.php b/code/web/public_php/admin/smarty/internals/core.is_trusted.php index f0bd2fb8c..429973158 100644 --- a/code/web/public_php/admin/smarty/internals/core.is_trusted.php +++ b/code/web/public_php/admin/smarty/internals/core.is_trusted.php @@ -25,7 +25,7 @@ function smarty_core_is_trusted($params, &$smarty) if (!empty($curr_dir) && is_readable ($curr_dir)) { $_cd = realpath($curr_dir); if (strncmp($_rp, $_cd, strlen($_cd)) == 0 - && $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { + && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { $_smarty_trusted = true; break; } diff --git a/code/web/public_php/admin/smarty/internals/core.process_cached_inserts.php b/code/web/public_php/admin/smarty/internals/core.process_cached_inserts.php index 29cb007eb..1d78edd93 100644 --- a/code/web/public_php/admin/smarty/internals/core.process_cached_inserts.php +++ b/code/web/public_php/admin/smarty/internals/core.process_cached_inserts.php @@ -52,7 +52,7 @@ function smarty_core_process_cached_inserts($params, &$smarty) $replace = ''; } - $params['results'] = str_replace($cached_inserts[$i], $replace, $params['results']); + $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); if ($smarty->debugging) { $_params = array(); require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); diff --git a/code/web/public_php/admin/smarty/internals/core.process_compiled_include.php b/code/web/public_php/admin/smarty/internals/core.process_compiled_include.php index 3e1d4c15a..904d59745 100644 --- a/code/web/public_php/admin/smarty/internals/core.process_compiled_include.php +++ b/code/web/public_php/admin/smarty/internals/core.process_compiled_include.php @@ -20,7 +20,12 @@ function smarty_core_process_compiled_include($params, &$smarty) $smarty->_cache_including = true; $_return = $params['results']; - foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) { + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $smarty->_include($_include_file_path, true); + } + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', array(&$smarty, '_process_compiled_include_callback'), $_return); diff --git a/code/web/public_php/admin/smarty/internals/core.read_cache_file.php b/code/web/public_php/admin/smarty/internals/core.read_cache_file.php index ecb147089..c60e113a7 100644 --- a/code/web/public_php/admin/smarty/internals/core.read_cache_file.php +++ b/code/web/public_php/admin/smarty/internals/core.read_cache_file.php @@ -90,16 +90,6 @@ function smarty_core_read_cache_file(&$params, &$smarty) } } - foreach ($_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { - if (empty($smarty->_cache_serials[$_include_file_path])) { - $smarty->_include($_include_file_path, true); - } - - if ($smarty->_cache_serials[$_include_file_path] != $_cache_serial) { - /* regenerate */ - return false; - } - } $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); $smarty->_cache_info = $_cache_info; diff --git a/code/web/public_php/admin/smarty/internals/core.rmdir.php b/code/web/public_php/admin/smarty/internals/core.rmdir.php index 4fdbccc95..2166c44d2 100644 --- a/code/web/public_php/admin/smarty/internals/core.rmdir.php +++ b/code/web/public_php/admin/smarty/internals/core.rmdir.php @@ -32,7 +32,6 @@ function smarty_core_rmdir($params, &$smarty) 'level' => $params['level'] + 1, 'exp_time' => $params['exp_time'] ); - require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); smarty_core_rmdir($_params, $smarty); } else { diff --git a/code/web/public_php/admin/smarty/internals/core.write_cache_file.php b/code/web/public_php/admin/smarty/internals/core.write_cache_file.php index 72f785b74..fa3cdd746 100644 --- a/code/web/public_php/admin/smarty/internals/core.write_cache_file.php +++ b/code/web/public_php/admin/smarty/internals/core.write_cache_file.php @@ -68,7 +68,7 @@ function smarty_core_write_cache_file($params, &$smarty) if (!empty($smarty->cache_handler_func)) { // use cache_handler function call_user_func_array($smarty->cache_handler_func, - array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); + array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires'])); } else { // use local cache file diff --git a/code/web/public_php/admin/smarty/internals/core.write_compiled_include.php b/code/web/public_php/admin/smarty/internals/core.write_compiled_include.php index 5e0b2e0dd..c14adb5f4 100644 --- a/code/web/public_php/admin/smarty/internals/core.write_compiled_include.php +++ b/code/web/public_php/admin/smarty/internals/core.write_compiled_include.php @@ -15,12 +15,12 @@ function smarty_core_write_compiled_include($params, &$smarty) { - $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\) \{ echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\';\}'; - $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\';\}'; + $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; + $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', $params['compiled_content'], $_match_source, PREG_SET_ORDER); - + // no nocache-parts found: done if (count($_match_source)==0) return; diff --git a/code/web/public_php/admin/smarty/internals/core.write_file.php b/code/web/public_php/admin/smarty/internals/core.write_file.php index 09e169840..8a3a3b398 100644 --- a/code/web/public_php/admin/smarty/internals/core.write_file.php +++ b/code/web/public_php/admin/smarty/internals/core.write_file.php @@ -23,8 +23,7 @@ function smarty_core_write_file($params, &$smarty) smarty_core_create_dir_structure($_params, $smarty); } - // write to tmp file, then rename it to avoid - // file locking race condition + // write to tmp file, then rename it to avoid file locking race condition $_tmp_file = tempnam($_dirname, 'wrt'); if (!($fd = @fopen($_tmp_file, 'wb'))) { @@ -38,12 +37,13 @@ function smarty_core_write_file($params, &$smarty) fwrite($fd, $params['contents']); fclose($fd); - // Delete the file if it allready exists (this is needed on Win, - // because it cannot overwrite files with rename() - if (file_exists($params['filename'])) { + if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { + // On platforms and filesystems that cannot overwrite with rename() + // delete the file before renaming it -- because windows always suffers + // this, it is short-circuited to avoid the initial rename() attempt @unlink($params['filename']); + @rename($_tmp_file, $params['filename']); } - @rename($_tmp_file, $params['filename']); @chmod($params['filename'], $smarty->_file_perms); return true; @@ -51,4 +51,4 @@ function smarty_core_write_file($params, &$smarty) /* vim: set expandtab: */ -?> +?> \ No newline at end of file diff --git a/code/web/public_php/admin/smarty/plugins/block.textformat.php b/code/web/public_php/admin/smarty/plugins/block.textformat.php index aaebab2f5..8cd010acb 100644 --- a/code/web/public_php/admin/smarty/plugins/block.textformat.php +++ b/code/web/public_php/admin/smarty/plugins/block.textformat.php @@ -23,6 +23,7 @@ * indent_char: string (" ") * wrap_boundary: boolean (true) * + * @author Monte Ohrt * @param string contents of the block * @param Smarty clever simulation of a method * @return string string $content re-formatted diff --git a/code/web/public_php/admin/smarty/plugins/compiler.assign.php b/code/web/public_php/admin/smarty/plugins/compiler.assign.php index 2e0201779..abef377f8 100644 --- a/code/web/public_php/admin/smarty/plugins/compiler.assign.php +++ b/code/web/public_php/admin/smarty/plugins/compiler.assign.php @@ -13,6 +13,8 @@ * Purpose: assign a value to a template variable * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} * (Smarty online manual) + * @author Monte Ohrt (initial author) + * @author messju mohr (conversion to compiler function) * @param string containing var-attribute and value-attribute * @param Smarty_Compiler */ diff --git a/code/web/public_php/admin/smarty/plugins/function.assign_debug_info.php b/code/web/public_php/admin/smarty/plugins/function.assign_debug_info.php index 8015624b1..654049876 100644 --- a/code/web/public_php/admin/smarty/plugins/function.assign_debug_info.php +++ b/code/web/public_php/admin/smarty/plugins/function.assign_debug_info.php @@ -11,6 +11,7 @@ * Type: function
* Name: assign_debug_info
* Purpose: assign debug info to the template
+ * @author Monte Ohrt * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} * @param Smarty diff --git a/code/web/public_php/admin/smarty/plugins/function.config_load.php b/code/web/public_php/admin/smarty/plugins/function.config_load.php index db7f8f6b9..db89f638c 100644 --- a/code/web/public_php/admin/smarty/plugins/function.config_load.php +++ b/code/web/public_php/admin/smarty/plugins/function.config_load.php @@ -13,6 +13,8 @@ * Purpose: load config file vars * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} * (Smarty online manual) + * @author Monte Ohrt + * @author messju mohr (added use of resources) * @param array Format: *
  * array('file' => required config file name,
diff --git a/code/web/public_php/admin/smarty/plugins/function.counter.php b/code/web/public_php/admin/smarty/plugins/function.counter.php
index cfe5dd886..1f26db5fb 100644
--- a/code/web/public_php/admin/smarty/plugins/function.counter.php
+++ b/code/web/public_php/admin/smarty/plugins/function.counter.php
@@ -12,6 +12,7 @@
  * Type:     function
* Name: counter
* Purpose: print out a counter value + * @author Monte Ohrt * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} * (Smarty online manual) * @param array parameters diff --git a/code/web/public_php/admin/smarty/plugins/function.cycle.php b/code/web/public_php/admin/smarty/plugins/function.cycle.php index fe78bb87d..80378b7f9 100644 --- a/code/web/public_php/admin/smarty/plugins/function.cycle.php +++ b/code/web/public_php/admin/smarty/plugins/function.cycle.php @@ -63,7 +63,11 @@ function smarty_function_cycle($params, &$smarty) $cycle_vars[$name]['values'] = $params['values']; } - $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; + if (isset($params['delimiter'])) { + $cycle_vars[$name]['delimiter'] = $params['delimiter']; + } elseif (!isset($cycle_vars[$name]['delimiter'])) { + $cycle_vars[$name]['delimiter'] = ','; + } if(is_array($cycle_vars[$name]['values'])) { $cycle_array = $cycle_vars[$name]['values']; diff --git a/code/web/public_php/admin/smarty/plugins/function.eval.php b/code/web/public_php/admin/smarty/plugins/function.eval.php index 3a4b8b2b8..ff0472de2 100644 --- a/code/web/public_php/admin/smarty/plugins/function.eval.php +++ b/code/web/public_php/admin/smarty/plugins/function.eval.php @@ -14,6 +14,7 @@ * Purpose: evaluate a template variable as a template
* @link http://smarty.php.net/manual/en/language.function.eval.php {eval} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty */ diff --git a/code/web/public_php/admin/smarty/plugins/function.fetch.php b/code/web/public_php/admin/smarty/plugins/function.fetch.php index f5a6987a9..d72c7b1f9 100644 --- a/code/web/public_php/admin/smarty/plugins/function.fetch.php +++ b/code/web/public_php/admin/smarty/plugins/function.fetch.php @@ -14,6 +14,7 @@ * Purpose: fetch file, web or ftp data and display results * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string|null if the assign parameter is passed, Smarty assigns the @@ -180,12 +181,12 @@ function smarty_function_fetch($params, &$smarty) $content .= fgets($fp,4096); } fclose($fp); - $csplit = split("\r\n\r\n",$content,2); + $csplit = preg_split("!\r\n\r\n!",$content,2); $content = $csplit[1]; if(!empty($params['assign_headers'])) { - $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); + $smarty->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0])); } } } else { diff --git a/code/web/public_php/admin/smarty/plugins/function.html_image.php b/code/web/public_php/admin/smarty/plugins/function.html_image.php index c62b0fea6..9abae72ef 100644 --- a/code/web/public_php/admin/smarty/plugins/function.html_image.php +++ b/code/web/public_php/admin/smarty/plugins/function.html_image.php @@ -19,9 +19,10 @@ * - width = image width (optional, default actual width) * - basedir = base directory for absolute paths, default * is environment variable DOCUMENT_ROOT + * - path_prefix = prefix for path output (optional, default empty) * - * Examples: {html_image file="images/masthead.gif"} - * Output: + * Examples: {html_image file="/images/masthead.gif"} + * Output: * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} * (Smarty online manual) * @author Monte Ohrt @@ -44,6 +45,7 @@ function smarty_function_html_image($params, &$smarty) $extra = ''; $prefix = ''; $suffix = ''; + $path_prefix = ''; $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; foreach($params as $_key => $_val) { @@ -52,6 +54,7 @@ function smarty_function_html_image($params, &$smarty) case 'height': case 'width': case 'dpi': + case 'path_prefix': case 'basedir': $$_key = $_val; break; @@ -90,15 +93,9 @@ function smarty_function_html_image($params, &$smarty) } else { $_image_path = $file; } - + if(!isset($params['width']) || !isset($params['height'])) { - if ($smarty->security && - ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && - (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && - (!smarty_core_is_secure($_params, $smarty)) ) { - $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); - - } elseif (!$_image_data = @getimagesize($_image_path)) { + if(!$_image_data = @getimagesize($_image_path)) { if(!file_exists($_image_path)) { $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); return; @@ -110,7 +107,13 @@ function smarty_function_html_image($params, &$smarty) return; } } - + if ($smarty->security && + ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && + (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && + (!smarty_core_is_secure($_params, $smarty)) ) { + $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); + } + if(!isset($params['width'])) { $width = $_image_data[0]; } @@ -131,7 +134,7 @@ function smarty_function_html_image($params, &$smarty) $height = round($height * $_resize); } - return $prefix . ''.$alt.'' . $suffix; + return $prefix . ''.$alt.'' . $suffix; } /* vim: set expandtab: */ diff --git a/code/web/public_php/admin/smarty/plugins/function.html_options.php b/code/web/public_php/admin/smarty/plugins/function.html_options.php index 761edf6ab..cebadde47 100644 --- a/code/web/public_php/admin/smarty/plugins/function.html_options.php +++ b/code/web/public_php/admin/smarty/plugins/function.html_options.php @@ -17,11 +17,11 @@ * - options (required if no values supplied) - associative array * - selected (optional) - string default not set * - output (required if not options supplied) - array - * - disabled (optional) - string default not set (added by Yogin) * Purpose: Prints the list of
!is", $source, $match); $_pre_blocks = $match[0]; - $source = preg_replace("!
.*?
!is", + $source = preg_replace("!]*?>.*?!is", '@@@SMARTY:TRIM:PRE@@@', $source); - + // Pull out the textarea blocks - preg_match_all("!]+>.*?!is", $source, $match); + preg_match_all("!]*?>.*?!is", $source, $match); $_textarea_blocks = $match[0]; - $source = preg_replace("!]+>.*?!is", + $source = preg_replace("!]*?>.*?!is", '@@@SMARTY:TRIM:TEXTAREA@@@', $source); // remove all leading spaces, tabs and carriage returns NOT // preceeded by a php close tag. $source = trim(preg_replace('/((?)\n)[\s]+/m', '\1', $source)); - // replace script blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); + // replace textarea blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); // replace pre blocks smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); - // replace textarea blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); + // replace script blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); return $source; } diff --git a/code/web/public_php/admin/smarty/plugins/shared.escape_special_chars.php b/code/web/public_php/admin/smarty/plugins/shared.escape_special_chars.php index 515763abe..c07ce31be 100644 --- a/code/web/public_php/admin/smarty/plugins/shared.escape_special_chars.php +++ b/code/web/public_php/admin/smarty/plugins/shared.escape_special_chars.php @@ -12,6 +12,7 @@ * Function: smarty_function_escape_special_chars
* Purpose: used by other smarty functions to escape * special chars except for already escaped ones + * @author Monte Ohrt * @param string * @return string */ diff --git a/code/web/public_php/admin/smarty/plugins/shared.make_timestamp.php b/code/web/public_php/admin/smarty/plugins/shared.make_timestamp.php index acdd77735..b42eb11d8 100644 --- a/code/web/public_php/admin/smarty/plugins/shared.make_timestamp.php +++ b/code/web/public_php/admin/smarty/plugins/shared.make_timestamp.php @@ -10,32 +10,35 @@ * Function: smarty_make_timestamp
* Purpose: used by other smarty functions to make a timestamp * from a string. + * @author Monte Ohrt * @param string * @return string */ function smarty_make_timestamp($string) { if(empty($string)) { - $string = "now"; - } - $time = strtotime($string); - if (is_numeric($time) && $time != -1) - return $time; - - // is mysql timestamp format of YYYYMMDDHHMMSS? - if (preg_match('/^\d{14}$/', $string)) { - $time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2), - substr($string,4,2),substr($string,6,2),substr($string,0,4)); + // use "now": + $time = time(); - return $time; + } elseif (preg_match('/^\d{14}$/', $string)) { + // it is mysql timestamp format of YYYYMMDDHHMMSS? + $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), + substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4)); + + } elseif (is_numeric($string)) { + // it is a numeric string, we handle it as timestamp + $time = (int)$string; + + } else { + // strtotime should handle it + $time = strtotime($string); + if ($time == -1 || $time === false) { + // strtotime() was not able to parse $string, use "now": + $time = time(); + } } + return $time; - // couldn't recognize it, try to return a time - $time = (int) $string; - if ($time > 0) - return $time; - else - return time(); } /* vim: set expandtab: */ From 4cf4440a97c49545df464f2caffdc02a5d7e012f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 22:26:11 +0200 Subject: [PATCH 101/240] Connection slots are now managed by their own object, and linking is now done to their positions. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_link.cpp | 2 +- .../plugins/gui_editor/expression_node.cpp | 152 ++++++++++++------ .../src/plugins/gui_editor/expression_node.h | 11 +- 3 files changed, 118 insertions(+), 47 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 1e7f7cf5f..5050a9339 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -53,7 +53,7 @@ void ExpressionLink::unlink() void ExpressionLink::nodeMoved() { - setLine( QLineF( m_from->pos(), m_to->pos() ) ); + setLine( QLineF( m_from->slotPos( 0 ), m_to->slotPos( 0 ) ) ); } void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index fae024096..06616c1db 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -22,19 +22,92 @@ #include #include + + +class NodeSlot +{ +public: + NodeSlot( const QPoint &tl, const QPoint &ttl, const QString &text ) + { + m_tl = tl; + m_ttl = ttl; + m_text = text; + + m_tw = 25.0; + m_th = 12.0; + m_wh = 10.0; + } + + ~NodeSlot() + { + } + + QPointF pos() const{ + QPointF p; + p.setX( m_tl.x() + m_wh / 2.0 ); + p.setY( m_tl.y() + m_wh / 2.0 ); + + return p; + } + + void paint( QPainter *painter ) + { + QBrush boxBrush; + QPen p; + + boxBrush.setColor( Qt::black ); + boxBrush.setStyle( Qt::SolidPattern ); + p.setColor( Qt::black ); + painter->setPen( p ); + + QRectF box; + QRectF tbox; + + box.setTopLeft( m_tl ); + box.setHeight( m_wh ); + box.setWidth( m_wh ); + + painter->fillRect( box, boxBrush ); + + tbox.setTopLeft( m_ttl ); + tbox.setHeight( m_th ); + tbox.setWidth( m_tw ); + + painter->drawText( tbox, Qt::AlignRight, m_text ); + } + +private: + QPoint m_tl; + QPoint m_ttl; + QString m_text; + + qreal m_th; + qreal m_tw; + qreal m_wh; +}; + + + ExpressionNode::ExpressionNode( QGraphicsItem *parent ) : QGraphicsItem( parent ) { m_link = NULL; + + m_w = 100; + m_h = 100; + + createSlots(); } ExpressionNode::~ExpressionNode() { + qDeleteAll( m_slots ); + m_slots.clear(); } QRectF ExpressionNode::boundingRect() const { - return QRectF( 0, 0, 100, 100 ); + return QRectF( 0, 0, m_w, m_h ); } void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) @@ -74,10 +147,20 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o painter->drawRect( rect ); painter->drawRect( header ); - paintConnections( painter ); + paintSlots( painter ); } +QPointF ExpressionNode::slotPos( int slot ) const +{ + const NodeSlot *s = m_slots[ slot ]; + QPointF sp = s->pos(); + QPointF mp = pos(); + + mp += sp; + return mp; +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { if( m_link != NULL ) @@ -86,54 +169,33 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) QGraphicsItem::mouseMoveEvent( e ); } -void ExpressionNode::paintConnections( QPainter *painter ) +void ExpressionNode::createSlots() { - QRectF rect = boundingRect(); - QBrush boxBrush; - QPen p; - - boxBrush.setColor( Qt::black ); - boxBrush.setStyle( Qt::SolidPattern ); - p.setColor( Qt::black ); - - QRectF box = rect; - QRectF tbox = rect; - qreal wh = 10.0; - qreal tw = 25.0; - qreal th = 12.0; - - box.setTopLeft( QPoint( 0, rect.height() * 0.5 ) ); - box.setHeight( wh ); - box.setWidth( wh ); - - painter->fillRect( box, boxBrush ); - - tbox.setTopLeft( QPoint( 15, rect.height() * 0.50 ) ); - tbox.setHeight( th ); - tbox.setWidth( tw ); - painter->setPen( p ); - painter->drawText( tbox, Qt::AlignCenter, "Out" ); - - + // First create the "Out" slot + qreal x = 0.0; + qreal y = m_h * 0.5; + qreal tx = 10; + qreal ty = m_h * 0.5 - 2; + m_slots.push_back( new NodeSlot( QPoint( x, y ), QPoint( tx, ty ), "Out" ) ); + + // Then the rest of them for( int i = 0; i < 3; i++ ) { - qreal x = rect.width() - wh; - qreal y = 30 + i * 20; - qreal tx = x - 5 - tw; - qreal ty = y - 2; - - box.setTopLeft( QPoint( x, y ) ); - box.setHeight( wh ); - box.setWidth( wh ); + x = m_w - 10; + y = 30 + i * 20.0; + tx = x - 5 - 25.0; + ty = y - 2; - painter->fillRect( box, boxBrush ); - - tbox.setTopLeft( QPoint( tx, ty ) ); - tbox.setHeight( th ); - tbox.setWidth( tw ); + m_slots.push_back( new NodeSlot( QPoint( x, y ), QPoint( tx, ty ), QString( 'A' + i ) ) ); + } +} - QString text = 'A' + i; - painter->drawText( tbox, Qt::AlignRight, text ); +void ExpressionNode::paintSlots( QPainter *painter ) +{ + for( int i = 0; i < 4; i++ ) + { + NodeSlot *slot = m_slots[ i ]; + slot->paint( painter ); } } diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 6eebcb8a4..c189bd0fc 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -21,8 +21,10 @@ #define EXPRESSION_NODE #include +#include class ExpressionLink; +class NodeSlot; class ExpressionNode : public QGraphicsItem { @@ -36,14 +38,21 @@ public: void setLink( ExpressionLink *link ){ m_link = link; } ExpressionLink* link() const{ return m_link; } + QPointF slotPos( int slot ) const; + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); private: - void paintConnections( QPainter *painter ); + void createSlots(); + void paintSlots( QPainter *painter ); ExpressionLink *m_link; + qreal m_w; + qreal m_h; + + QList< NodeSlot* > m_slots; }; #endif From c63f22fe92e31146305fb4fe52623926b29292a2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 22:31:48 +0200 Subject: [PATCH 102/240] Refactoring --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_node.cpp | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 06616c1db..e59db6a3c 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -22,16 +22,21 @@ #include #include - +struct NodeSlotInfo +{ + QPoint tl; + QPoint ttl; + QString text; +}; class NodeSlot { public: - NodeSlot( const QPoint &tl, const QPoint &ttl, const QString &text ) + NodeSlot( const NodeSlotInfo &info ) { - m_tl = tl; - m_ttl = ttl; - m_text = text; + m_tl = info.tl; + m_ttl = info.ttl; + m_text = info.text; m_tw = 25.0; m_th = 12.0; @@ -176,7 +181,13 @@ void ExpressionNode::createSlots() qreal y = m_h * 0.5; qreal tx = 10; qreal ty = m_h * 0.5 - 2; - m_slots.push_back( new NodeSlot( QPoint( x, y ), QPoint( tx, ty ), "Out" ) ); + + NodeSlotInfo info; + info.tl = QPoint( x, y ); + info.ttl = QPoint( tx, ty ); + info.text = "Out"; + + m_slots.push_back( new NodeSlot( info ) ); // Then the rest of them for( int i = 0; i < 3; i++ ) @@ -186,7 +197,11 @@ void ExpressionNode::createSlots() tx = x - 5 - 25.0; ty = y - 2; - m_slots.push_back( new NodeSlot( QPoint( x, y ), QPoint( tx, ty ), QString( 'A' + i ) ) ); + info.tl = QPoint( x, y ); + info.ttl = QPoint( tx, ty ); + info.text = QString( 'A' + i ); + + m_slots.push_back( new NodeSlot( info ) ); } } From 5fc392623b050132db6d843cc6a37a30f11046f4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 22:39:00 +0200 Subject: [PATCH 103/240] More refactoring. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_node.cpp | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index e59db6a3c..72f77f4dd 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -24,9 +24,23 @@ struct NodeSlotInfo { + // top-left QPoint tl; + + // text top-left QPoint ttl; + + // The text displayed QString text; + + // text width + qreal tw; + + // text height + qreal th; + + // width-height of the box + qreal wh; }; class NodeSlot @@ -38,9 +52,9 @@ public: m_ttl = info.ttl; m_text = info.text; - m_tw = 25.0; - m_th = 12.0; - m_wh = 10.0; + m_tw = info.tw; + m_th = info.th; + m_wh = info.wh; } ~NodeSlot() @@ -177,12 +191,17 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) void ExpressionNode::createSlots() { // First create the "Out" slot + + NodeSlotInfo info; + info.tw = 25.0; + info.th = 12.0; + info.wh = 10.0; + qreal x = 0.0; qreal y = m_h * 0.5; - qreal tx = 10; + qreal tx = info.wh; qreal ty = m_h * 0.5 - 2; - NodeSlotInfo info; info.tl = QPoint( x, y ); info.ttl = QPoint( tx, ty ); info.text = "Out"; @@ -192,9 +211,9 @@ void ExpressionNode::createSlots() // Then the rest of them for( int i = 0; i < 3; i++ ) { - x = m_w - 10; + x = m_w - info.wh; y = 30 + i * 20.0; - tx = x - 5 - 25.0; + tx = x - 5 - info.tw; ty = y - 2; info.tl = QPoint( x, y ); From 275095107b9b0251ded00e1826281de475176fb1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 22:54:50 +0200 Subject: [PATCH 104/240] More refactoring. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_node.cpp | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 72f77f4dd..95c2830f1 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -48,13 +48,7 @@ class NodeSlot public: NodeSlot( const NodeSlotInfo &info ) { - m_tl = info.tl; - m_ttl = info.ttl; - m_text = info.text; - - m_tw = info.tw; - m_th = info.th; - m_wh = info.wh; + m_info = info; } ~NodeSlot() @@ -63,8 +57,8 @@ public: QPointF pos() const{ QPointF p; - p.setX( m_tl.x() + m_wh / 2.0 ); - p.setY( m_tl.y() + m_wh / 2.0 ); + p.setX( m_info.tl.x() + m_info.wh / 2.0 ); + p.setY( m_info.tl.y() + m_info.wh / 2.0 ); return p; } @@ -82,27 +76,21 @@ public: QRectF box; QRectF tbox; - box.setTopLeft( m_tl ); - box.setHeight( m_wh ); - box.setWidth( m_wh ); + box.setTopLeft( m_info.tl ); + box.setHeight( m_info.wh ); + box.setWidth( m_info.wh ); painter->fillRect( box, boxBrush ); - tbox.setTopLeft( m_ttl ); - tbox.setHeight( m_th ); - tbox.setWidth( m_tw ); + tbox.setTopLeft( m_info.ttl ); + tbox.setHeight( m_info.th ); + tbox.setWidth( m_info.tw ); - painter->drawText( tbox, Qt::AlignRight, m_text ); + painter->drawText( tbox, Qt::AlignRight, m_info.text ); } private: - QPoint m_tl; - QPoint m_ttl; - QString m_text; - - qreal m_th; - qreal m_tw; - qreal m_wh; + NodeSlotInfo m_info; }; From 2e6a5bb1d6f706610bd9da172b4891f9d708fa29 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 13 Sep 2014 23:54:25 +0200 Subject: [PATCH 105/240] There are more than 1 slots available now. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 20 +++++++++------ .../plugins/gui_editor/expression_link.cpp | 13 ++++++---- .../src/plugins/gui_editor/expression_link.h | 4 ++- .../plugins/gui_editor/expression_node.cpp | 25 ++++++++++++++++--- .../src/plugins/gui_editor/expression_node.h | 9 ++++--- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 313af23b5..cca3b29ae 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -87,12 +87,18 @@ void ExpressionEditor::onDeleteSelection() ExpressionNode *node = dynamic_cast< ExpressionNode* >( item ); if( node != NULL ) { - ExpressionLink *link = node->link(); - if( link != NULL ) + ExpressionLink *link = NULL; + + int c = node->slotCount(); + for( int i = 0; i < c; i++ ) { - link->unlink(); - m_scene->removeItem( link ); - delete link; + link = node->link( i ); + if( link != NULL ) + { + link->unlink(); + m_scene->removeItem( link ); + delete link; + } } } @@ -113,7 +119,7 @@ void ExpressionEditor::onLinkItems() ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] ); ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] ); - if( ( from->link() != NULL ) || ( to->link() != NULL ) ) + if( ( from->link( 0 ) != NULL ) || ( to->link( 0 ) != NULL ) ) { QMessageBox::information( this, tr( "Failed to link nodes" ), @@ -122,7 +128,7 @@ void ExpressionEditor::onLinkItems() } ExpressionLink *link = new ExpressionLink(); - link->link( from, to ); + link->link( from, to, 0, 0 ); m_scene->addItem( link ); } diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 5050a9339..8e461960e 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -35,20 +35,23 @@ ExpressionLink::~ExpressionLink() unlink(); } -void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to ) +void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot ) { m_from = from; m_to = to; - m_from->setLink( this ); - m_to->setLink( this ); + m_from->setLink( this, fromSlot ); + m_to->setLink( this, toSlot ); + + m_fromSlot = fromSlot; + m_toSlot = toSlot; nodeMoved(); } void ExpressionLink::unlink() { - m_from->setLink( NULL ); - m_to->setLink( NULL ); + m_from->setLink( NULL, m_fromSlot ); + m_to->setLink( NULL, m_toSlot ); } void ExpressionLink::nodeMoved() diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h index 59644980a..a5235737c 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.h +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -29,7 +29,7 @@ public: ExpressionLink( QGraphicsItem *parent = NULL ); ~ExpressionLink(); - void link( ExpressionNode *from, ExpressionNode *to ); + void link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot ); void unlink(); void nodeMoved(); @@ -40,6 +40,8 @@ private: ExpressionNode *m_from; ExpressionNode *m_to; + int m_fromSlot; + int m_toSlot; }; #endif diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 95c2830f1..bcde92423 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -98,12 +98,13 @@ private: ExpressionNode::ExpressionNode( QGraphicsItem *parent ) : QGraphicsItem( parent ) { - m_link = NULL; - m_w = 100; m_h = 100; createSlots(); + + for( int i = 0; i < 4; i++ ) + m_links.push_back( NULL ); } ExpressionNode::~ExpressionNode() @@ -168,10 +169,26 @@ QPointF ExpressionNode::slotPos( int slot ) const return mp; } +void ExpressionNode::setLink( ExpressionLink *link, int slot ) +{ + m_links[ slot ] = link; +} + +ExpressionLink* ExpressionNode::link( int slot ) const +{ + return m_links[ slot ]; +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { - if( m_link != NULL ) - m_link->nodeMoved(); + for( int i = 0; i < 4; i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + link->nodeMoved(); + } QGraphicsItem::mouseMoveEvent( e ); } diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index c189bd0fc..991057731 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -35,11 +35,13 @@ public: QRectF boundingRect() const; void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); - void setLink( ExpressionLink *link ){ m_link = link; } - ExpressionLink* link() const{ return m_link; } + void setLink( ExpressionLink *link, int slot ); + ExpressionLink* link( int slot ) const; QPointF slotPos( int slot ) const; + int slotCount() const{ return m_slots.count(); } + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); @@ -47,12 +49,11 @@ private: void createSlots(); void paintSlots( QPainter *painter ); - ExpressionLink *m_link; - qreal m_w; qreal m_h; QList< NodeSlot* > m_slots; + QList< ExpressionLink* > m_links; }; #endif From b5a95d725b020fcc656a2e626768c78c280ef155 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 14 Sep 2014 15:02:44 +0200 Subject: [PATCH 106/240] Add pz process --HG-- branch : develop --- .hgignore | 1 + code/nel/tools/build_gamedata/0_setup.py | 1 + .../build_gamedata/configuration/tools.py | 1 + .../build_gamedata/processes/pz/0_setup.py | 97 +++++++++++++++++++ .../build_gamedata/processes/pz/1_export.py | 49 ++++++++++ .../build_gamedata/processes/pz/2_build.py | 62 ++++++++++++ .../build_gamedata/processes/pz/3_install.py | 57 +++++++++++ 7 files changed, 268 insertions(+) create mode 100644 code/nel/tools/build_gamedata/processes/pz/0_setup.py create mode 100644 code/nel/tools/build_gamedata/processes/pz/1_export.py create mode 100644 code/nel/tools/build_gamedata/processes/pz/2_build.py create mode 100644 code/nel/tools/build_gamedata/processes/pz/3_install.py diff --git a/.hgignore b/.hgignore index 16e7f1eef..22ab5938d 100644 --- a/.hgignore +++ b/.hgignore @@ -260,3 +260,4 @@ code/web/public_php/role_support code/web/public_php/role_domain code/web/public_php/db_version_ring code/web/public_php/config_user.php +code/nel/tools/build_gamedata/processes/pz/build_world_packed_col.cfg diff --git a/code/nel/tools/build_gamedata/0_setup.py b/code/nel/tools/build_gamedata/0_setup.py index aeac30eaf..f3edfc9ba 100755 --- a/code/nel/tools/build_gamedata/0_setup.py +++ b/code/nel/tools/build_gamedata/0_setup.py @@ -432,6 +432,7 @@ if not args.noverify: findTool(log, ToolDirectories, TgaCutTool, ToolSuffix) findTool(log, ToolDirectories, PatchGenTool, ToolSuffix) findTool(log, ToolDirectories, TranslationToolsTool, ToolSuffix) + findTool(log, ToolDirectories, BuildWorldPackedColTool, ToolSuffix) log.close() if os.path.isfile("0_setup.log"): diff --git a/code/nel/tools/build_gamedata/configuration/tools.py b/code/nel/tools/build_gamedata/configuration/tools.py index 1a31d2986..ce2dcff9c 100755 --- a/code/nel/tools/build_gamedata/configuration/tools.py +++ b/code/nel/tools/build_gamedata/configuration/tools.py @@ -91,3 +91,4 @@ AiBuildWmapTool = "ai_build_wmap" TgaCutTool = "tga_cut" PatchGenTool = "patch_gen" TranslationToolsTool = "translation_tools" +BuildWorldPackedColTool = "build_world_packed_col" diff --git a/code/nel/tools/build_gamedata/processes/pz/0_setup.py b/code/nel/tools/build_gamedata/processes/pz/0_setup.py new file mode 100644 index 000000000..e9f22be11 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pz/0_setup.py @@ -0,0 +1,97 @@ +#!/usr/bin/python +# +# \file 0_setup.py +# \brief setup pz +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Setup pz +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Setup pz") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Setup build directories +printLog(log, ">>> Setup build directories <<<") +mkPath(log, ExportBuildDirectory + "/" + PackedZoneCacheBuildDirectory) +mkPath(log, ExportBuildDirectory + "/" + PackedZoneCWMapCacheBuildDirectory) +mkPath(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory) + +# Setup lookup directories +printLog(log, ">>> Setup lookup directories <<<") +mkPath(log, ExportBuildDirectory + "/" + AiWmapBuildDirectory) +mkPath(log, ExportBuildDirectory + "/" + ZoneLightBuildDirectory) +mkPath(log, LeveldesignDataCommonDirectory) + +# Setup client directories +printLog(log, ">>> Setup install directories <<<") +mkPath(log, InstallDirectory + "/" + PackedZoneInstallDirectory) + +# Setup client directories +printLog(log, ">>> Setup configuration <<<") +mkPath(log, ActiveProjectDirectory + "/generated") +cfg = open(ActiveProjectDirectory + "/generated/build_world_packed_col.cfg", "w") +cfg.write("\n") +cfg.write("// BUILD WORLD PACKED COL CONFIGURATION\n") +cfg.write("\n") +cfg.write("SearchPaths = {\n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + AiWmapBuildDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + ZoneLightBuildDirectory + "\", \n") +cfg.write("\t\"" + LeveldesignDataCommonDirectory + "\", \n") +cfg.write("};\n") +cfg.write("\n") +cfg.write("CachePath = \"" + ExportBuildDirectory + "/" + PackedZoneCacheBuildDirectory + "\";\n") +cfg.write("CWMapCachePath = \"" + ExportBuildDirectory + "/" + PackedZoneCWMapCacheBuildDirectory + "\";\n") +cfg.write("OutputPath = \"" + ExportBuildDirectory + "/" + PackedZoneBuildDirectory + "\";\n") +cfg.write("\n") +cfg.write("EntryPointsFile = \"r2_islands.xml\";\n") +cfg.write("\n") +cfg.write("CWMapList = {\n") +cfg.write("\t\"" + PackedZoneCWMap + "\", \n") +cfg.write("};\n") +cfg.write("\n") +cfg.write("Fly = 0;\n") +cfg.write("\n") +cfg.write("HeightMapsAsTga = 1;\n") +cfg.write("PixelPerMeter = 1;\n") +cfg.write("\n") +cfg.write("RefineThreshold = 32;\n") +cfg.write("\n") +cfg.close() + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pz/1_export.py b/code/nel/tools/build_gamedata/processes/pz/1_export.py new file mode 100644 index 000000000..ff8daf747 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pz/1_export.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +# +# \file 1_export.py +# \brief Export pz +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Export pz +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Export pz") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pz/2_build.py b/code/nel/tools/build_gamedata/processes/pz/2_build.py new file mode 100644 index 000000000..b632412b0 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pz/2_build.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# +# \file 2_build.py +# \brief Build pz +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Build pz +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Build pz") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Find tools +BuildWorldPackedCol = findTool(log, ToolDirectories, BuildWorldPackedColTool, ToolSuffix) + +if BuildWorldPackedCol == "": + toolLogFail(log, BuildWorldPackedColTool, ToolSuffix) +else: + printLog(log, ">>> Copy ai_build_wmap.cfg <<<") + cfgPath = ActiveProjectDirectory + "/generated/build_world_packed_col.cfg" + shutil.copy(cfgPath, "build_world_packed_col.cfg") + printLog(log, ">>> Build pz <<<") + subprocess.call([ BuildWorldPackedCol, "build_world_packed_col.cfg" ]) +printLog(log, "") + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pz/3_install.py b/code/nel/tools/build_gamedata/processes/pz/3_install.py new file mode 100644 index 000000000..91f9f0a32 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/pz/3_install.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# +# \file 3_install.py +# \brief Install pz +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Install pz +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Install pz") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +installPath = InstallDirectory + "/" + PackedZoneInstallDirectory +mkPath(log, installPath) + +printLog(log, ">>> Install pz <<<") +mkPath(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory) +copyFilesNoTreeIfNeeded(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory, installPath) + +printLog(log, "") +log.close() + + +# end of file From 875cad3f72e81a0d3b05afb46d2b49c149abad50 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 15:15:20 +0200 Subject: [PATCH 107/240] Improved linking --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/CMakeLists.txt | 2 + .../src/plugins/gui_editor/expr_link_dlg.cpp | 122 ++++++++++++++++++ .../src/plugins/gui_editor/expr_link_dlg.h | 49 +++++++ .../src/plugins/gui_editor/expr_link_dlg.ui | 58 +++++++++ .../src/plugins/gui_editor/expr_slot_info.h | 32 +++++ .../plugins/gui_editor/expression_editor.cpp | 23 +++- .../plugins/gui_editor/expression_link.cpp | 8 +- .../plugins/gui_editor/expression_node.cpp | 39 ++++++ .../src/plugins/gui_editor/expression_node.h | 6 + 9 files changed, 335 insertions(+), 4 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/expr_link_dlg.cpp create mode 100644 code/studio/src/plugins/gui_editor/expr_link_dlg.h create mode 100644 code/studio/src/plugins/gui_editor/expr_link_dlg.ui create mode 100644 code/studio/src/plugins/gui_editor/expr_slot_info.h diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 77ca5a335..2b46e2cdc 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -35,6 +35,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR action_property_manager.h texture_property_manager.h expression_editor.h + expr_link_dlg.h ) SET(OVQT_PLUGIN_GUI_EDITOR_UIS @@ -53,6 +54,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS action_list.ui texture_chooser.ui expression_editor.ui + expr_link_dlg.ui ) SET(QT_USE_QTGUI TRUE) diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp new file mode 100644 index 000000000..44cf29d74 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp @@ -0,0 +1,122 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expr_link_dlg.h" +#include + +ExprLinkDlg::ExprLinkDlg( QWidget *parent ) : +QDialog( parent ) +{ + m_ui.setupUi( this ); + + connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); + connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); +} + +ExprLinkDlg::~ExprLinkDlg() +{ +} + +void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b ) +{ + QListIterator< SlotInfo > itra( a ); + QListIterator< SlotInfo > itrb( b ); + + while( itra.hasNext() ) + { + const SlotInfo &info = itra.next(); + + QListWidgetItem *item = new QListWidgetItem(); + item->setText( info.name ); + item->setData( Qt::UserRole, info.slot ); + + m_ui.list1->addItem( item ); + } + + while( itrb.hasNext() ) + { + const SlotInfo &info = itrb.next(); + + QListWidgetItem *item = new QListWidgetItem(); + item->setText( info.name ); + item->setData( Qt::UserRole, info.slot ); + + m_ui.list2->addItem( item ); + } + +} + +int ExprLinkDlg::getSlotA() const +{ + QListWidgetItem *item = m_ui.list1->currentItem(); + if( item == NULL ) + return -1; + + int slot = item->data( Qt::UserRole ).toInt(); + return slot; +} + +int ExprLinkDlg::getSlotB() const +{ + QListWidgetItem *item = m_ui.list2->currentItem(); + if( item == NULL ) + return -1; + + int slot = item->data( Qt::UserRole ).toInt(); + return slot; +} + +void ExprLinkDlg::onOKClicked() +{ + int slotA = getSlotA(); + int slotB = getSlotB(); + + if( ( slotA == -1 ) || ( slotB == -1 ) ) + { + QMessageBox::information( this, + tr( "No slots selected" ), + tr( "You need to select a slot on both sides." ) ); + return; + } + + if( ( slotA == 0 ) && ( slotB == 0 ) ) + { + QMessageBox::information( this, + tr( "Wrong slots selected" ), + tr( "You can only select the 'Out' slot on one of the sides." ) ); + return; + } + + if( ( slotA != 0 ) && ( slotB != 0 ) ) + { + QMessageBox::information( this, + tr( "Wrong slots selected" ), + tr( "One of the slots selected must be the 'Out' slot!" ) ); + return; + } + + accept(); +} + +void ExprLinkDlg::onCancelClicked() +{ + reject(); +} + + diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.h b/code/studio/src/plugins/gui_editor/expr_link_dlg.h new file mode 100644 index 000000000..d53d528c5 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.h @@ -0,0 +1,49 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPR_LINK_DLG +#define EXPR_LINK_DLG + +#include +#include +#include "ui_expr_link_dlg.h" +#include "expr_slot_info.h" + +class ExprLinkDlg : public QDialog +{ + Q_OBJECT +public: + ExprLinkDlg( QWidget *parent = NULL ); + ~ExprLinkDlg(); + + void load( const QList< SlotInfo > &a, const QList< SlotInfo > &b ); + + int getSlotA() const; + int getSlotB() const; + +private Q_SLOTS: + void onOKClicked(); + void onCancelClicked(); + +private: + Ui::ExprLinkDialog m_ui; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.ui b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui new file mode 100644 index 000000000..32e610352 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui @@ -0,0 +1,58 @@ + + + ExprLinkDialog + + + + 0 + 0 + 581 + 388 + + + + Linking nodes + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 398 + 20 + + + + + + + + Ok + + + + + + + Cancel + + + + + + + + diff --git a/code/studio/src/plugins/gui_editor/expr_slot_info.h b/code/studio/src/plugins/gui_editor/expr_slot_info.h new file mode 100644 index 000000000..9614cd96a --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_slot_info.h @@ -0,0 +1,32 @@ +// Ryzom Core Studio - Georges Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPR_SLOT_INFO +#define EXPR_SLOT_INFO + +#include + +struct SlotInfo +{ + QString name; + int slot; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index cca3b29ae..c4d5c1948 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -25,6 +25,7 @@ #include "expression_node.h" #include "expression_link.h" +#include "expr_link_dlg.h" #include @@ -119,16 +120,32 @@ void ExpressionEditor::onLinkItems() ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] ); ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] ); - if( ( from->link( 0 ) != NULL ) || ( to->link( 0 ) != NULL ) ) + QList< SlotInfo > froml; + QList< SlotInfo > tol; + + from->getSlots( froml ); + to->getSlots( tol ); + + // If there are no free slots, or both "Out" slots are taken we can't link + if( froml.isEmpty() || tol.isEmpty() || ( !from->slotEmpty( 0 ) && !to->slotEmpty( 0 ) ) ) { QMessageBox::information( this, tr( "Failed to link nodes" ), - tr( "Unfortunately those nodes are already linked." ) ); + tr( "Unfortunately those nodes are full." ) ); return; } + ExprLinkDlg d; + d.load( froml, tol ); + int result = d.exec(); + if( result == QDialog::Rejected ) + return; + + int slotA = d.getSlotA(); + int slotB = d.getSlotB(); + ExpressionLink *link = new ExpressionLink(); - link->link( from, to, 0, 0 ); + link->link( from, to, slotA, slotB ); m_scene->addItem( link ); } diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 8e461960e..66ddffd7f 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -50,13 +50,19 @@ void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to, int fromSlo void ExpressionLink::unlink() { + if( m_from == NULL ) + return; + m_from->setLink( NULL, m_fromSlot ); m_to->setLink( NULL, m_toSlot ); + + m_from = NULL; + m_to = NULL; } void ExpressionLink::nodeMoved() { - setLine( QLineF( m_from->slotPos( 0 ), m_to->slotPos( 0 ) ) ); + setLine( QLineF( m_from->slotPos( m_fromSlot ), m_to->slotPos( m_toSlot ) ) ); } void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index bcde92423..90d132d91 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -89,6 +89,8 @@ public: painter->drawText( tbox, Qt::AlignRight, m_info.text ); } + QString text() const{ return m_info.text; } + private: NodeSlotInfo m_info; }; @@ -109,6 +111,8 @@ QGraphicsItem( parent ) ExpressionNode::~ExpressionNode() { + clearLinks(); + qDeleteAll( m_slots ); m_slots.clear(); } @@ -169,6 +173,29 @@ QPointF ExpressionNode::slotPos( int slot ) const return mp; } +bool ExpressionNode::slotEmpty( int slot ) const +{ + if( m_links[ 0 ] == NULL ) + return true; + else + return false; +} + +void ExpressionNode::getSlots( QList< SlotInfo > &l ) +{ + SlotInfo info; + + for( int i = 0; i < m_slots.count(); i++ ) + { + if( m_links[ i ] != NULL ) + continue; + + info.name = m_slots[ i ]->text(); + info.slot = i; + l.push_back( info ); + } +} + void ExpressionNode::setLink( ExpressionLink *link, int slot ) { m_links[ slot ] = link; @@ -239,3 +266,15 @@ void ExpressionNode::paintSlots( QPainter *painter ) } +void ExpressionNode::clearLinks() +{ + for( int i = 0; i < m_links.count(); i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + link->unlink(); + } +} + diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 991057731..704804b55 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -22,6 +22,7 @@ #include #include +#include "expr_slot_info.h" class ExpressionLink; class NodeSlot; @@ -42,12 +43,17 @@ public: int slotCount() const{ return m_slots.count(); } + bool slotEmpty( int slot ) const; + + void getSlots( QList< SlotInfo > &l ); + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); private: void createSlots(); void paintSlots( QPainter *painter ); + void clearLinks(); qreal m_w; qreal m_h; From aa6701138194d03b1197d0e0df80aade145ac8b6 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 15:36:41 +0200 Subject: [PATCH 108/240] Added unlinking support. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 17 +++++++++++++++++ .../src/plugins/gui_editor/expression_editor.h | 1 + .../src/plugins/gui_editor/expression_link.cpp | 2 ++ .../src/plugins/gui_editor/expression_node.h | 3 ++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index c4d5c1948..1c4a1ecda 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -65,6 +65,9 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Link" ); connect( a, SIGNAL( triggered() ), this, SLOT( onLinkItems() ) ); } + + a = menu.addAction( "Unlink" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onUnLinkItems() ) ); } menu.exec( e->globalPos() ); @@ -150,4 +153,18 @@ void ExpressionEditor::onLinkItems() m_scene->addItem( link ); } +void ExpressionEditor::onUnLinkItems() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + + for( int i = 0; i < l.count(); i++ ) + { + ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ i ] ); + if( node == NULL ) + continue; + + node->clearLinks(); + } +} + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 70d2ad572..00d347993 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -39,6 +39,7 @@ private Q_SLOTS: void onDeleteSelection(); void onSelectionChanged(); void onLinkItems(); + void onUnLinkItems(); private: diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 66ddffd7f..537d4891f 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -58,6 +58,8 @@ void ExpressionLink::unlink() m_from = NULL; m_to = NULL; + + delete this; } void ExpressionLink::nodeMoved() diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 704804b55..4fb92cbf4 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -47,13 +47,14 @@ public: void getSlots( QList< SlotInfo > &l ); + void clearLinks(); + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); private: void createSlots(); void paintSlots( QPainter *painter ); - void clearLinks(); qreal m_w; qreal m_h; From 42cd76c768dc7b1b2711b90bdc6244ca54ecb96c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 16:37:17 +0200 Subject: [PATCH 109/240] Support for adding nodes with different slot count. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 39 ++++++++++++++----- .../plugins/gui_editor/expression_editor.h | 4 +- .../plugins/gui_editor/expression_node.cpp | 19 +++++---- .../src/plugins/gui_editor/expression_node.h | 2 +- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 1c4a1ecda..14bf69600 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -52,8 +52,15 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) QMenu menu; QAction *a = NULL; - a = menu.addAction( "Add rect" ); - connect( a, SIGNAL( triggered() ), this, SLOT( onAddRect() ) ); + QMenu *mm = menu.addMenu( "Add node" ); + a = mm->addAction( "1 slot" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode1() ) ); + + a = mm->addAction( "2 slots" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode2() ) ); + + a = mm->addAction( "3 slots" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode3() ) ); if( m_selectionCount > 0 ) { @@ -73,13 +80,6 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) menu.exec( e->globalPos() ); } -void ExpressionEditor::onAddRect() -{ - QGraphicsItem *item = new ExpressionNode(); - item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); - m_scene->addItem( item ); -} - void ExpressionEditor::onDeleteSelection() { QList< QGraphicsItem* > l = m_scene->selectedItems(); @@ -168,3 +168,24 @@ void ExpressionEditor::onUnLinkItems() } +void ExpressionEditor::onAddNode1() +{ + QGraphicsItem *item = new ExpressionNode( 1 ); + item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + m_scene->addItem( item ); +} + +void ExpressionEditor::onAddNode2() +{ + QGraphicsItem *item = new ExpressionNode( 2 ); + item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + m_scene->addItem( item ); +} + +void ExpressionEditor::onAddNode3() +{ + QGraphicsItem *item = new ExpressionNode( 3 ); + item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + m_scene->addItem( item ); +} + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 00d347993..2346f42cf 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -35,11 +35,13 @@ protected: void contextMenuEvent( QContextMenuEvent *e ); private Q_SLOTS: - void onAddRect(); void onDeleteSelection(); void onSelectionChanged(); void onLinkItems(); void onUnLinkItems(); + void onAddNode1(); + void onAddNode2(); + void onAddNode3(); private: diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 90d132d91..049acfbb9 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -97,16 +97,19 @@ private: -ExpressionNode::ExpressionNode( QGraphicsItem *parent ) : +ExpressionNode::ExpressionNode( int nodes, QGraphicsItem *parent ) : QGraphicsItem( parent ) { m_w = 100; m_h = 100; - createSlots(); + // Out nodes + m_links.push_back( NULL ); - for( int i = 0; i < 4; i++ ) + for( int i = 0; i < nodes; i++ ) m_links.push_back( NULL ); + + createSlots(); } ExpressionNode::~ExpressionNode() @@ -208,7 +211,7 @@ ExpressionLink* ExpressionNode::link( int slot ) const void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { - for( int i = 0; i < 4; i++ ) + for( int i = 0; i < m_links.count(); i++ ) { ExpressionLink *link = m_links[ i ]; if( link == NULL ) @@ -222,8 +225,9 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) void ExpressionNode::createSlots() { - // First create the "Out" slot + int nodes = m_links.count(); + // First create the "Out" slot NodeSlotInfo info; info.tw = 25.0; info.th = 12.0; @@ -239,9 +243,10 @@ void ExpressionNode::createSlots() info.text = "Out"; m_slots.push_back( new NodeSlot( info ) ); + nodes--; // Then the rest of them - for( int i = 0; i < 3; i++ ) + for( int i = 0; i < nodes; i++ ) { x = m_w - info.wh; y = 30 + i * 20.0; @@ -258,7 +263,7 @@ void ExpressionNode::createSlots() void ExpressionNode::paintSlots( QPainter *painter ) { - for( int i = 0; i < 4; i++ ) + for( int i = 0; i < m_slots.count(); i++ ) { NodeSlot *slot = m_slots[ i ]; slot->paint( painter ); diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 4fb92cbf4..efecea818 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -30,7 +30,7 @@ class NodeSlot; class ExpressionNode : public QGraphicsItem { public: - ExpressionNode( QGraphicsItem *parent = NULL ); + ExpressionNode( int nodes = 3, QGraphicsItem *parent = NULL ); ~ExpressionNode(); QRectF boundingRect() const; From adb717052ac953447df9df5fe9ca8776f006a154 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 14 Sep 2014 16:37:24 +0200 Subject: [PATCH 110/240] Add cartographer --HG-- branch : develop --- .hgignore | 1 + code/nel/tools/build_gamedata/0_setup.py | 1 + .../build_gamedata/configuration/tools.py | 1 + .../processes/cartographer/0_setup.py | 114 ++++++++++++++++++ .../processes/cartographer/1_export.py | 49 ++++++++ .../processes/cartographer/2_build.py | 62 ++++++++++ .../processes/cartographer/3_install.py | 57 +++++++++ .../build_gamedata/processes/pz/3_install.py | 3 +- 8 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 code/nel/tools/build_gamedata/processes/cartographer/0_setup.py create mode 100644 code/nel/tools/build_gamedata/processes/cartographer/1_export.py create mode 100644 code/nel/tools/build_gamedata/processes/cartographer/2_build.py create mode 100644 code/nel/tools/build_gamedata/processes/cartographer/3_install.py diff --git a/.hgignore b/.hgignore index 22ab5938d..7892f93af 100644 --- a/.hgignore +++ b/.hgignore @@ -261,3 +261,4 @@ code/web/public_php/role_domain code/web/public_php/db_version_ring code/web/public_php/config_user.php code/nel/tools/build_gamedata/processes/pz/build_world_packed_col.cfg +code/nel/tools/build_gamedata/processes/cartographer/island_screenshots.cfg diff --git a/code/nel/tools/build_gamedata/0_setup.py b/code/nel/tools/build_gamedata/0_setup.py index f3edfc9ba..8eff34131 100755 --- a/code/nel/tools/build_gamedata/0_setup.py +++ b/code/nel/tools/build_gamedata/0_setup.py @@ -433,6 +433,7 @@ if not args.noverify: findTool(log, ToolDirectories, PatchGenTool, ToolSuffix) findTool(log, ToolDirectories, TranslationToolsTool, ToolSuffix) findTool(log, ToolDirectories, BuildWorldPackedColTool, ToolSuffix) + findTool(log, ToolDirectories, R2IslandsTexturesTool, ToolSuffix) log.close() if os.path.isfile("0_setup.log"): diff --git a/code/nel/tools/build_gamedata/configuration/tools.py b/code/nel/tools/build_gamedata/configuration/tools.py index ce2dcff9c..c0c962360 100755 --- a/code/nel/tools/build_gamedata/configuration/tools.py +++ b/code/nel/tools/build_gamedata/configuration/tools.py @@ -92,3 +92,4 @@ TgaCutTool = "tga_cut" PatchGenTool = "patch_gen" TranslationToolsTool = "translation_tools" BuildWorldPackedColTool = "build_world_packed_col" +R2IslandsTexturesTool = "r2_islands_textures" diff --git a/code/nel/tools/build_gamedata/processes/cartographer/0_setup.py b/code/nel/tools/build_gamedata/processes/cartographer/0_setup.py new file mode 100644 index 000000000..6f8b9a754 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/cartographer/0_setup.py @@ -0,0 +1,114 @@ +#!/usr/bin/python +# +# \file 0_setup.py +# \brief setup cartographer +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Setup cartographer +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Setup cartographer") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Setup build directories +printLog(log, ">>> Setup build directories <<<") +mkPath(log, ExportBuildDirectory + "/" + CartographerBuildDirectory) + +# Setup lookup directories +printLog(log, ">>> Setup lookup directories <<<") +mkPath(log, ExportBuildDirectory + "/" + AiWmapBuildDirectory) # IN +mkPath(log, ExportBuildDirectory + "/" + ZoneLightBuildDirectory) # IN (.zonel) +mkPath(log, ExportBuildDirectory + "/" + ZoneLightIgLandBuildDirectory) # IN (.ig) +mkPath(log, ExportBuildDirectory + "/" + SmallbankExportDirectory) # IN +mkPath(log, ExportBuildDirectory + "/" + FarbankBuildDirectory) # IN +mkPath(log, ExportBuildDirectory + "/" + DisplaceExportDirectory) # IN +mkPath(log, ExportBuildDirectory + "/" + TilesExportDirectory) # IN +mkPath(log, LeveldesignDataCommonDirectory) # IN +mkPath(log, LeveldesignDfnDirectory) # IN +mkPath(log, LeveldesignDirectory) # IN +for dir in PropertiesExportBuildSearchPaths: + mkPath(log, ExportBuildDirectory + "/" + dir) + +# Setup client directories +printLog(log, ">>> Setup install directories <<<") +mkPath(log, InstallDirectory + "/" + CartographerInstallDirectory) + +# Setup client directories +printLog(log, ">>> Setup configuration <<<") +mkPath(log, ActiveProjectDirectory + "/generated") +cfg = open(ActiveProjectDirectory + "/generated/island_screenshots.cfg", "w") +cfg.write("\n") +cfg.write("// BUILD CARTOGRAPHER CONFIGURATION\n") +cfg.write("\n") +cfg.write("SearchPaths = {\n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + AiWmapBuildDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + ZoneLightBuildDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + ZoneLightIgLandBuildDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + SmallbankExportDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + FarbankBuildDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + DisplaceExportDirectory + "\", \n") +cfg.write("\t\"" + ExportBuildDirectory + "/" + TilesExportDirectory + "\", \n") +cfg.write("\t\"" + LeveldesignDataCommonDirectory + "\", \n") +cfg.write("\t\"" + LeveldesignDfnDirectory + "\", \n") +cfg.write("\t\"" + LeveldesignDirectory + "\", \n") +for dir in PropertiesExportBuildSearchPaths: + cfg.write("\t\"" + ExportBuildDirectory + "/" + dir + "\", \n") +cfg.write("};\n") +cfg.write("\n") +cfg.write("OutDir = \"" + ExportBuildDirectory + "/" + CartographerBuildDirectory + "\";\n") +cfg.write("\n") +cfg.write("Continents = {\n") +cfg.write("\t\"" + CartographerContinent + "\", \n") +cfg.write("};\n") +cfg.write("\n") +cfg.write("SeasonSuffixes = {\n") +for suffix in MultipleTilesPostfix: + cfg.write("\t\"" + suffix + "\", \n") +cfg.write("};\n") +cfg.write("\n") +cfg.write("InverseZTest = true;\n") +cfg.write("Vegetation = true;\n") +cfg.write("MeterPixelSize = 2;\n") +cfg.write("\n") +cfg.write("CompleteIslandsFile = \"r2_islands.xml\";\n") +cfg.write("EntryPointsFile = \"r2_entry_points.txt\";\n") +cfg.write("\n") +cfg.close() + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/cartographer/1_export.py b/code/nel/tools/build_gamedata/processes/cartographer/1_export.py new file mode 100644 index 000000000..319316728 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/cartographer/1_export.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +# +# \file 1_export.py +# \brief Export cartographer +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Export cartographer +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Export cartographer") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/cartographer/2_build.py b/code/nel/tools/build_gamedata/processes/cartographer/2_build.py new file mode 100644 index 000000000..c3c14e9aa --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/cartographer/2_build.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# +# \file 2_build.py +# \brief Build cartographer +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Build cartographer +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Build cartographer") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +# Find tools +R2IslandsTextures = findTool(log, ToolDirectories, R2IslandsTexturesTool, ToolSuffix) + +if R2IslandsTextures == "": + toolLogFail(log, R2IslandsTexturesTool, ToolSuffix) +else: + printLog(log, ">>> Copy island_screenshots.cfg <<<") + cfgPath = ActiveProjectDirectory + "/generated/island_screenshots.cfg" + shutil.copy(cfgPath, "island_screenshots.cfg") + printLog(log, ">>> Build cartographer <<<") + subprocess.call([ R2IslandsTextures ]) +printLog(log, "") + +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/cartographer/3_install.py b/code/nel/tools/build_gamedata/processes/cartographer/3_install.py new file mode 100644 index 000000000..f241318c4 --- /dev/null +++ b/code/nel/tools/build_gamedata/processes/cartographer/3_install.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# +# \file 3_install.py +# \brief Install cartographer +# \date 2014-09-13 13:32GMT +# \author Jan Boon (Kaetemi) +# Python port of game data build pipeline. +# Install cartographer +# +# NeL - MMORPG Framework +# Copyright (C) 2014 Jan BOON +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +import time, sys, os, shutil, subprocess, distutils.dir_util +sys.path.append("../../configuration") + +if os.path.isfile("log.log"): + os.remove("log.log") +log = open("log.log", "w") +from scripts import * +from buildsite import * +from process import * +from tools import * +from directories import * + +printLog(log, "") +printLog(log, "-------") +printLog(log, "--- Install cartographer") +printLog(log, "-------") +printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) +printLog(log, "") + +installPath = InstallDirectory + "/" + CartographerInstallDirectory +mkPath(log, installPath) + +printLog(log, ">>> Install cartographer <<<") +mkPath(log, ExportBuildDirectory + "/" + CartographerBuildDirectory) +copyFilesNoTreeIfNeeded(log, ExportBuildDirectory + "/" + CartographerBuildDirectory, installPath) + +printLog(log, "") +log.close() + + +# end of file diff --git a/code/nel/tools/build_gamedata/processes/pz/3_install.py b/code/nel/tools/build_gamedata/processes/pz/3_install.py index 91f9f0a32..c4feedef1 100644 --- a/code/nel/tools/build_gamedata/processes/pz/3_install.py +++ b/code/nel/tools/build_gamedata/processes/pz/3_install.py @@ -48,7 +48,8 @@ mkPath(log, installPath) printLog(log, ">>> Install pz <<<") mkPath(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory) -copyFilesNoTreeIfNeeded(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory, installPath) +copyFilesExtNoTreeIfNeeded(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory, installPath, ".island_hm") +copyFilesExtNoTreeIfNeeded(log, ExportBuildDirectory + "/" + PackedZoneBuildDirectory, installPath, ".packed_island") printLog(log, "") log.close() From 40b4bce729d7dfb8e8ac224e18c9dc129a999cbd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 16:43:45 +0200 Subject: [PATCH 111/240] A little refactoring. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 18 ++++++++-------- .../plugins/gui_editor/expression_editor.h | 1 + .../plugins/gui_editor/expression_node.cpp | 21 ++++++++----------- .../src/plugins/gui_editor/expression_node.h | 4 ++-- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 14bf69600..c821ceb6d 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -167,25 +167,25 @@ void ExpressionEditor::onUnLinkItems() } } - -void ExpressionEditor::onAddNode1() +void ExpressionEditor::addNode( int slotCount ) { - QGraphicsItem *item = new ExpressionNode( 1 ); + QGraphicsItem *item = new ExpressionNode( slotCount ); item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); m_scene->addItem( item ); } +void ExpressionEditor::onAddNode1() +{ + addNode( 1 ); +} + void ExpressionEditor::onAddNode2() { - QGraphicsItem *item = new ExpressionNode( 2 ); - item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); - m_scene->addItem( item ); + addNode( 2 ); } void ExpressionEditor::onAddNode3() { - QGraphicsItem *item = new ExpressionNode( 3 ); - item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); - m_scene->addItem( item ); + addNode( 3 ); } diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 2346f42cf..91bb5d851 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -39,6 +39,7 @@ private Q_SLOTS: void onSelectionChanged(); void onLinkItems(); void onUnLinkItems(); + void addNode( int slotCount ); void onAddNode1(); void onAddNode2(); void onAddNode3(); diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 049acfbb9..86469314a 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -97,19 +97,13 @@ private: -ExpressionNode::ExpressionNode( int nodes, QGraphicsItem *parent ) : +ExpressionNode::ExpressionNode( int slotCount, QGraphicsItem *parent ) : QGraphicsItem( parent ) { m_w = 100; m_h = 100; - // Out nodes - m_links.push_back( NULL ); - - for( int i = 0; i < nodes; i++ ) - m_links.push_back( NULL ); - - createSlots(); + createSlots( slotCount ); } ExpressionNode::~ExpressionNode() @@ -223,10 +217,14 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) QGraphicsItem::mouseMoveEvent( e ); } -void ExpressionNode::createSlots() +void ExpressionNode::createSlots( int count) { - int nodes = m_links.count(); + // Out nodes + m_links.push_back( NULL ); + for( int i = 0; i < count; i++ ) + m_links.push_back( NULL ); + // First create the "Out" slot NodeSlotInfo info; info.tw = 25.0; @@ -243,10 +241,9 @@ void ExpressionNode::createSlots() info.text = "Out"; m_slots.push_back( new NodeSlot( info ) ); - nodes--; // Then the rest of them - for( int i = 0; i < nodes; i++ ) + for( int i = 0; i < count; i++ ) { x = m_w - info.wh; y = 30 + i * 20.0; diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index efecea818..654329dd5 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -30,7 +30,7 @@ class NodeSlot; class ExpressionNode : public QGraphicsItem { public: - ExpressionNode( int nodes = 3, QGraphicsItem *parent = NULL ); + ExpressionNode( int slotCount = 3, QGraphicsItem *parent = NULL ); ~ExpressionNode(); QRectF boundingRect() const; @@ -53,7 +53,7 @@ protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); private: - void createSlots(); + void createSlots( int count = 3 ); void paintSlots( QPainter *painter ); qreal m_w; From 99ebe16c03acda5e703cdea9823274ffc9172f37 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 16:57:56 +0200 Subject: [PATCH 112/240] Allow painting of arbitrary number of connection slots. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_node.cpp | 6 +++++- code/studio/src/plugins/gui_editor/expression_node.h | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 86469314a..c12ca3ea5 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -102,6 +102,10 @@ QGraphicsItem( parent ) { m_w = 100; m_h = 100; + m_hh = 20.0; + + if( slotCount > 3 ) + m_h = m_h + 20.0 * ( slotCount - 3 ); createSlots( slotCount ); } @@ -128,7 +132,7 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o QRectF rect = boundingRect(); QRectF header = rect; - header.setHeight( header.height() * 0.2 ); + header.setHeight( m_hh ); // Draw filled rectangle, header c.setRed( 44 ); diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 654329dd5..6df38d583 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -56,8 +56,9 @@ private: void createSlots( int count = 3 ); void paintSlots( QPainter *painter ); - qreal m_w; - qreal m_h; + qreal m_w; // node width + qreal m_h; // node height + qreal m_hh; // header height QList< NodeSlot* > m_slots; QList< ExpressionLink* > m_links; From eb0693cd2775948c01baba0b9f6c5540fb123c2e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 17:04:42 +0200 Subject: [PATCH 113/240] Add serial number to nodes. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_editor.cpp | 9 ++++++++- code/studio/src/plugins/gui_editor/expression_editor.h | 1 + code/studio/src/plugins/gui_editor/expression_node.cpp | 6 ++++-- code/studio/src/plugins/gui_editor/expression_node.h | 4 +++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index c821ceb6d..dc164d361 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -40,6 +40,8 @@ QWidget( parent ) m_ui.view->setScene( m_scene ); connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); + + m_nodeCount = 0; } ExpressionEditor::~ExpressionEditor() @@ -169,7 +171,12 @@ void ExpressionEditor::onUnLinkItems() void ExpressionEditor::addNode( int slotCount ) { - QGraphicsItem *item = new ExpressionNode( slotCount ); + QString name; + name = "node #"; + name += QString::number( m_nodeCount ); + m_nodeCount++; + + QGraphicsItem *item = new ExpressionNode( name, slotCount ); item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); m_scene->addItem( item ); } diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 91bb5d851..553f8efd3 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -50,6 +50,7 @@ private: QGraphicsScene *m_scene; int m_selectionCount; + int m_nodeCount; }; #endif diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index c12ca3ea5..3098c6290 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -97,13 +97,15 @@ private: -ExpressionNode::ExpressionNode( int slotCount, QGraphicsItem *parent ) : +ExpressionNode::ExpressionNode( const QString &name, int slotCount, QGraphicsItem *parent ) : QGraphicsItem( parent ) { m_w = 100; m_h = 100; m_hh = 20.0; + m_name = name; + if( slotCount > 3 ) m_h = m_h + 20.0 * ( slotCount - 3 ); @@ -147,7 +149,7 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o // Draw header text p.setColor( Qt::black ); painter->setPen( p ); - painter->drawText( header, Qt::AlignCenter, "Something" ); + painter->drawText( header, Qt::AlignCenter, m_name ); if( option->state & QStyle::State_Selected ) { diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 6df38d583..0b7242f5d 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -30,7 +30,7 @@ class NodeSlot; class ExpressionNode : public QGraphicsItem { public: - ExpressionNode( int slotCount = 3, QGraphicsItem *parent = NULL ); + ExpressionNode( const QString &name, int slotCount = 3, QGraphicsItem *parent = NULL ); ~ExpressionNode(); QRectF boundingRect() const; @@ -62,6 +62,8 @@ private: QList< NodeSlot* > m_slots; QList< ExpressionLink* > m_links; + + QString m_name; }; #endif From 65382b45b7e98189f3e09c390b2817c129e63517 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 17:19:11 +0200 Subject: [PATCH 114/240] Show the node names as title, in the link dialog. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expr_link_dlg.cpp | 4 ++- .../src/plugins/gui_editor/expr_link_dlg.h | 2 +- .../src/plugins/gui_editor/expr_link_dlg.ui | 28 +++++++++++++++---- .../plugins/gui_editor/expression_editor.cpp | 2 +- .../src/plugins/gui_editor/expression_node.h | 2 ++ 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp index 44cf29d74..9a91e5f21 100644 --- a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp @@ -33,7 +33,7 @@ ExprLinkDlg::~ExprLinkDlg() { } -void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b ) +void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname ) { QListIterator< SlotInfo > itra( a ); QListIterator< SlotInfo > itrb( b ); @@ -60,6 +60,8 @@ void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b ) m_ui.list2->addItem( item ); } + m_ui.groupBox1->setTitle( aname ); + m_ui.groupBox2->setTitle( bname ); } int ExprLinkDlg::getSlotA() const diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.h b/code/studio/src/plugins/gui_editor/expr_link_dlg.h index d53d528c5..267787cf3 100644 --- a/code/studio/src/plugins/gui_editor/expr_link_dlg.h +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.h @@ -32,7 +32,7 @@ public: ExprLinkDlg( QWidget *parent = NULL ); ~ExprLinkDlg(); - void load( const QList< SlotInfo > &a, const QList< SlotInfo > &b ); + void load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname ); int getSlotA() const; int getSlotB() const; diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.ui b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui index 32e610352..d6fdf9d7d 100644 --- a/code/studio/src/plugins/gui_editor/expr_link_dlg.ui +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui @@ -6,21 +6,39 @@ 0 0 - 581 - 388 + 641 + 334
Linking nodes - + - + + + GroupBox + + + + + + + - + + + GroupBox + + + + + + + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index dc164d361..62e034255 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -141,7 +141,7 @@ void ExpressionEditor::onLinkItems() } ExprLinkDlg d; - d.load( froml, tol ); + d.load( froml, tol, from->name(), to->name() ); int result = d.exec(); if( result == QDialog::Rejected ) return; diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 0b7242f5d..7d236475a 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -49,6 +49,8 @@ public: void clearLinks(); + QString name() const{ return m_name; } + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); From 38810a8c0f351d0450a6e703f36897fc575034ef Mon Sep 17 00:00:00 2001 From: botanic Date: Sun, 14 Sep 2014 09:46:12 -0700 Subject: [PATCH 115/240] Update domain settings --HG-- branch : develop --- .../Domain_Management/Domain_Management.php | 107 ++++++++++-------- .../Domain_Management/templates/index.tpl | 16 +-- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php index 888112c65..bd2bb28e8 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php +++ b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php @@ -3,15 +3,15 @@ /** * Global and Local Hooks for the Domain_Management plugin * Global Hooks are defined with the prefix(name of the plugin) - * Local Hooks are defined with normal function name - * + * Local Hooks are defined with normal function name + * * All the Global Hooks are called during the page load * and Local Hooks are called according to conditions - * - * Here, we request to the Domain_Management url using REST + * + * Here, we request to the Domain_Management url using REST * to get the contents and will display with this plugin. - * - * @author shubham meena mentored by Matthew Lagoe + * + * @author shubham meena mentored by Matthew Lagoe */ @@ -31,78 +31,91 @@ function domain_management_hook_display() global $domain_management_return_set; // to display plugin name in menu bar $domain_management_return_set['admin_menu_display'] = 'Domain Management'; - $domain_management_return_set['icon'] = 'icon-edit'; - } + $domain_management_return_set['icon'] = 'icon-edit'; + } /** * Global Hook to interact with the REST api - * Pass the variables in the REST object to - * make request - * + * Pass the variables in the REST object to + * make request + * * variables REST object expects * url --> on which request is to be made * appkey --> app key for authentication * host --> host from which request have been sent - * + * * @return $domain_management_return_set global array returns the template data */ function domain_management_hook_call_rest() { global $domain_management_return_set; - global $WEBPATH; - - $domain_management_return_set['path'] = $WEBPATH; + global $WEBPATH; + + $domain_management_return_set['path'] = $WEBPATH; - } + } /** * Global Hook to return global variables which contains - * the content to use in the smarty templates extracted from + * the content to use in the smarty templates extracted from * the database - * + * * @return $domain_management_return_set global array returns the template data */ function domain_management_hook_get_db() { global $domain_management_return_set; - + + if ( isset( $_GET['ModifyDomain'] ) && $_GET['ModifyDomain'] = '1' && isset($_POST['domain_name'])) { + try { + + $dbs = new DBLayer( 'shard' ); + $dbs->update("domain", Array( 'domain_name' => $_POST['domain_name'], 'patch_version' => $_POST['patch_version'],'backup_patch_url' => $_POST['backup_patch_url'],'patch_urls' => $_POST['patch_urls'],'login_address' => $_POST['login_address'],'session_manager_address' => $_POST['session_manager_address'],'ring_db_name' => $_POST['ring_db_name'],'web_host' => $_POST['web_host'],'web_host_php' => $_POST['web_host_php'],'description' => $_POST['description'],),'`domain_id` = '.$_GET['edit_domain']); + + } + catch ( Exception $e ) { + return null; + } + } + try { - + $db = new DBLayer( 'shard' ); - - //get all domains - $statement = $db->executeWithoutParams("SELECT * FROM domain"); - $rows = $statement->fetchAll(); - $domain_management_return_set['domains'] = $rows; - - if (isset($_GET['edit_domain'])){ - //get permissions - $statement = $db->executeWithoutParams("SELECT * FROM `domain` WHERE `domain_id` = '".$_GET['edit_domain']."'"); - $rows = $statement->fetchAll(); - $domain_management_return_set['domains'] = $rows; - - $statement = $db->executeWithoutParams("SELECT * FROM `permission` WHERE `DomainId` = '".$_GET['edit_domain']."'"); - $rows = $statement->fetchAll(); - $domain_management_return_set['permissions'] = $rows; - - //get all users - $pagination = new Pagination(WebUsers::getAllUsersQuery(),"web",10,"WebUsers"); - $domain_management_return_set['userlist'] = Gui_Elements::make_table($pagination->getElements() , Array("getUId","getUsername","getEmail"), Array("id","username","email")); - - } - + + // get all domains + $statement = $db -> executeWithoutParams( "SELECT * FROM domain" ); + $rows = $statement -> fetchAll(); + $domain_management_return_set['domains'] = $rows; + + if ( isset( $_GET['edit_domain'] ) ) { + // get permissions + $statement = $db -> executeWithoutParams( "SELECT * FROM `domain` WHERE `domain_id` = '" . $_GET['edit_domain'] . "'" ); + $rows = $statement -> fetchAll(); + $domain_management_return_set['domains'] = $rows; + + $statement = $db -> executeWithoutParams( "SELECT * FROM `permission` WHERE `DomainId` = '" . $_GET['edit_domain'] . "'" ); + $rows = $statement -> fetchAll(); + $domain_management_return_set['permissions'] = $rows; + + // get all users + $pagination = new Pagination( WebUsers :: getAllUsersQuery(), "web", 10, "WebUsers" ); + $domain_management_return_set['userlist'] = Gui_Elements :: make_table( $pagination -> getElements() , Array( "getUId", "getUsername", "getEmail" ), Array( "id", "username", "email" ) ); + + } + return $rows; - - } catch (Exception $e) { + + } + catch ( Exception $e ) { return null; - } - } + } + } /** * Global Hook to return global variables which contains * the content to use in the smarty templates - * + * * @return $domain_management_return_set global array returns the template data */ function domain_management_hook_return_global() diff --git a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl index 2e818591c..6f0e55599 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl +++ b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl @@ -60,7 +60,7 @@
-
+ Domain Settings of '{$hook_info['Domain_Management']['domains']['0']['domain_name']}' @@ -85,12 +85,14 @@
- +
+ +
From 9ceeed138e52da7b02f5d841bddda4526de5ff91 Mon Sep 17 00:00:00 2001 From: botanic Date: Sun, 14 Sep 2014 10:13:30 -0700 Subject: [PATCH 116/240] change to 256 characters --HG-- branch : develop --- code/web/private_php/setup/sql/nel_ams_lib_00006.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/private_php/setup/sql/nel_ams_lib_00006.sql b/code/web/private_php/setup/sql/nel_ams_lib_00006.sql index 8a344379c..f4c632bad 100644 --- a/code/web/private_php/setup/sql/nel_ams_lib_00006.sql +++ b/code/web/private_php/setup/sql/nel_ams_lib_00006.sql @@ -1,7 +1,7 @@ CREATE TABLE IF NOT EXISTS `settings` ( `idSettings` int(11) NOT NULL, `Setting` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `Value` varchar(32) COLLATE utf8_unicode_ci NOT NULL + `Value` varchar(256) COLLATE utf8_unicode_ci NOT NULL ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT INTO `settings` (`idSettings`, `Setting`, `Value`) VALUES From 7f2091d6c98917bb8596a9719c093e5ba097e321 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sun, 14 Sep 2014 21:00:40 +0200 Subject: [PATCH 117/240] Expression Editor is now a QMainWindow subclass. Also added an expression tree, with some sample nodes. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 28 +++-- .../plugins/gui_editor/expression_editor.h | 5 +- .../plugins/gui_editor/expression_editor.ui | 107 +++++++++++++++--- 3 files changed, 110 insertions(+), 30 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 62e034255..54f878afa 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -30,16 +30,17 @@ #include ExpressionEditor::ExpressionEditor( QWidget *parent ) : -QWidget( parent ) +QMainWindow( parent ) { m_ui.setupUi( this ); - + m_selectionCount = 0; m_scene = new QGraphicsScene( this ); m_ui.view->setScene( m_scene ); connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); + connect( m_ui.tree, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); m_nodeCount = 0; } @@ -169,30 +170,37 @@ void ExpressionEditor::onUnLinkItems() } } -void ExpressionEditor::addNode( int slotCount ) +void ExpressionEditor::addNode( const QString &name, int slotCount ) { - QString name; - name = "node #"; - name += QString::number( m_nodeCount ); + QString n = name; + n += " #"; + n += QString::number( m_nodeCount ); m_nodeCount++; - QGraphicsItem *item = new ExpressionNode( name, slotCount ); + QGraphicsItem *item = new ExpressionNode( n, slotCount ); item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); m_scene->addItem( item ); } void ExpressionEditor::onAddNode1() { - addNode( 1 ); + addNode( "node", 1 ); } void ExpressionEditor::onAddNode2() { - addNode( 2 ); + addNode( "node", 2 ); } void ExpressionEditor::onAddNode3() { - addNode( 3 ); + addNode( "node", 3 ); } +void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) +{ + QString name = item->text( 0 ); + addNode( name, 3 ); +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 553f8efd3..5b17d091d 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -24,7 +24,7 @@ class QGraphicsScene; -class ExpressionEditor : public QWidget +class ExpressionEditor : public QMainWindow { Q_OBJECT public: @@ -39,10 +39,11 @@ private Q_SLOTS: void onSelectionChanged(); void onLinkItems(); void onUnLinkItems(); - void addNode( int slotCount ); + void addNode( const QString &name, int slotCount ); void onAddNode1(); void onAddNode2(); void onAddNode3(); + void onItemDblClicked( QTreeWidgetItem *item ); private: diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui index 80480ad39..db71014bf 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.ui +++ b/code/studio/src/plugins/gui_editor/expression_editor.ui @@ -1,33 +1,104 @@ ExpressionEditor - - - Qt::ApplicationModal - + 0 0 - 724 - 522 + 800 + 600 Expression Editor - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOn - - - - + + + + + + + + + + + 0 + 0 + 800 + 21 + + + + + + + 1 + + + + + + + + Expressions + + + + + Logical + + + + and + + + + + or + + + + + + Mathematical + + + + add + + + + + sub + + + + + + Value + + + + integer + + + + + string + + + + + boolean + + + + + + + + From ba3f48a9e26d3ae0c6b65819535de7172ff31f6a Mon Sep 17 00:00:00 2001 From: botanic Date: Sun, 14 Sep 2014 13:09:00 -0700 Subject: [PATCH 118/240] FIX #205 --HG-- branch : develop --- code/web/private_php/ams/autoload/helpers.php | 2 + .../Domain_Management/Domain_Management.php | 14 +++- .../Domain_Management/templates/index.tpl | 75 ++++++++++++++++--- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/code/web/private_php/ams/autoload/helpers.php b/code/web/private_php/ams/autoload/helpers.php index 94b45706d..b8118db37 100644 --- a/code/web/private_php/ams/autoload/helpers.php +++ b/code/web/private_php/ams/autoload/helpers.php @@ -18,6 +18,8 @@ class Helpers { */ public static function loadTemplate( $template, $vars = array (), $returnHTML = false ) { + error_log(print_r($_GET,true)); + error_log(print_r($_POST,true)); global $AMS_LIB; global $SITEBASE; global $AMS_TRANS; diff --git a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php index bd2bb28e8..cd748167d 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php +++ b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php @@ -71,7 +71,7 @@ function domain_management_hook_get_db() try { $dbs = new DBLayer( 'shard' ); - $dbs->update("domain", Array( 'domain_name' => $_POST['domain_name'], 'patch_version' => $_POST['patch_version'],'backup_patch_url' => $_POST['backup_patch_url'],'patch_urls' => $_POST['patch_urls'],'login_address' => $_POST['login_address'],'session_manager_address' => $_POST['session_manager_address'],'ring_db_name' => $_POST['ring_db_name'],'web_host' => $_POST['web_host'],'web_host_php' => $_POST['web_host_php'],'description' => $_POST['description'],),'`domain_id` = '.$_GET['edit_domain']); + $dbs->update("domain", Array( 'domain_name' => $_POST['domain_name'], 'status' => $_POST['status'], 'patch_version' => $_POST['patch_version'],'backup_patch_url' => $_POST['backup_patch_url'],'patch_urls' => $_POST['patch_urls'],'login_address' => $_POST['login_address'],'session_manager_address' => $_POST['session_manager_address'],'ring_db_name' => $_POST['ring_db_name'],'web_host' => $_POST['web_host'],'web_host_php' => $_POST['web_host_php'],'description' => $_POST['description'],),'`domain_id` = '.$_GET['edit_domain']); } catch ( Exception $e ) { @@ -123,3 +123,15 @@ function domain_management_hook_return_global() global $domain_management_return_set; return $domain_management_return_set; } + + +function api_key_management_hook_activate() + { + $dbl = new DBLayer( "lib" ); + $sql = "INSERT INTO `settings` (Setting) + SELECT 'Domain_Auto_Add' FROM DUAL + WHERE NOT EXISTS + (SELECT Setting FROM settings WHERE Setting='Domain_Auto_Add');"; + + $dbl -> executeWithoutParams( $sql ); + } \ No newline at end of file diff --git a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl index 6f0e55599..6c6a55b45 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl +++ b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl @@ -52,13 +52,13 @@
-
+
-
+
Modify Domain Settings
-
-
+
+
@@ -80,21 +80,19 @@
-
+
- -
-
-
-
-
+
@@ -196,6 +194,61 @@
+
+
+ +
+
+
+ Permission Settings +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + + {if isset($RESULT_OF_MODIFYING) and $RESULT_OF_MODIFYING eq "SUCCESS"} +
+ {$modify_mail_of_group_success} +
+ {/if} + + +
+
+
+
{else} From 89604dbba48d927e8b0a147f6ee6b44b77ecd9da Mon Sep 17 00:00:00 2001 From: botanic Date: Sun, 14 Sep 2014 15:52:40 -0700 Subject: [PATCH 119/240] Fix #194 --HG-- branch : develop --- code/web/private_php/ams/autoload/helpers.php | 4 +- code/web/private_php/ams/autoload/users.php | 30 ++++++-- .../Domain_Management/Domain_Management.php | 31 +++++++++ .../Domain_Management/templates/index.tpl | 69 ++++++++++++------- 4 files changed, 104 insertions(+), 30 deletions(-) diff --git a/code/web/private_php/ams/autoload/helpers.php b/code/web/private_php/ams/autoload/helpers.php index b8118db37..28e4ce036 100644 --- a/code/web/private_php/ams/autoload/helpers.php +++ b/code/web/private_php/ams/autoload/helpers.php @@ -18,8 +18,8 @@ class Helpers { */ public static function loadTemplate( $template, $vars = array (), $returnHTML = false ) { - error_log(print_r($_GET,true)); - error_log(print_r($_POST,true)); + //error_log(print_r($_GET,true)); + //error_log(print_r($_POST,true)); global $AMS_LIB; global $SITEBASE; global $AMS_TRANS; diff --git a/code/web/private_php/ams/autoload/users.php b/code/web/private_php/ams/autoload/users.php index cde30cf63..ffc04ace2 100644 --- a/code/web/private_php/ams/autoload/users.php +++ b/code/web/private_php/ams/autoload/users.php @@ -336,12 +336,32 @@ class Users{ $dbs = new DBLayer("shard"); $sth = $dbs->selectWithParameter("UId", "user", $values, "Login= :username"); $result = $sth->fetchAll(); - /*foreach ($result as $UId) { - $ins_values = array('UId' => $UId['UId'], 'clientApplication' => 'r2', 'AccessPrivilege' => 'OPEN'); - $dbs->insert("permission", $ins_values); - $ins_values['clientApplication'] = 'ryzom_open'; + $dbl = new DBLayer("lib"); + + $UId = $result['0']['UId']; + + $statement = $dbl->execute("SELECT * FROM `settings` WHERE `Setting` = :setting", Array('setting' => 'Domain_Auto_Add')); + $json = $statement->fetch(); + $json = json_decode($json['Value'],true); + + $db = new DBLayer( 'shard' ); + + // get all domains + $statement = $db -> executeWithoutParams( "SELECT * FROM domain" ); + $rows = $statement -> fetchAll(); + + //error_log(print_r($rows,true)); + //error_log(print_r($result,true)); + //error_log(print_r($json,true)); + foreach ($json as $key => $value) { + //error_log(print_r($key,true)); + //error_log(print_r($value,true)); + + $ins_values = array('UId' => $UId, 'DomainId' => $key, 'AccessPrivilege' => $value['1']); + error_log(print_r($ins_values,true)); + $dbs = new DBLayer("shard"); $dbs->insert("permission", $ins_values); - }*/ // FIXME: GARBAGE + } } catch (PDOException $e) { //oh noooz, the shard is offline! Put it in query queue at ams_lib db! diff --git a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php index cd748167d..a99ac5551 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php +++ b/code/web/private_php/ams/plugins/Domain_Management/Domain_Management.php @@ -73,6 +73,29 @@ function domain_management_hook_get_db() $dbs = new DBLayer( 'shard' ); $dbs->update("domain", Array( 'domain_name' => $_POST['domain_name'], 'status' => $_POST['status'], 'patch_version' => $_POST['patch_version'],'backup_patch_url' => $_POST['backup_patch_url'],'patch_urls' => $_POST['patch_urls'],'login_address' => $_POST['login_address'],'session_manager_address' => $_POST['session_manager_address'],'ring_db_name' => $_POST['ring_db_name'],'web_host' => $_POST['web_host'],'web_host_php' => $_POST['web_host_php'],'description' => $_POST['description'],),'`domain_id` = '.$_GET['edit_domain']); + } + catch ( Exception $e ) { + return null; + } + } + + if ( isset( $_GET['ModifyPermission'] ) && $_GET['ModifyPermission'] = '1' && isset($_POST['user'])) { + try { + + $dbl = new DBLayer("lib"); + + $statement = $dbl->execute("SELECT * FROM `settings` WHERE `Setting` = :setting", Array('setting' => 'Domain_Auto_Add')); + $json = $statement->fetch(); + $json = json_decode($json['Value'],true); + + $json[$_GET['edit_domain']]['1'] = $_POST['user']; + $json[$_GET['edit_domain']]['2'] = $_POST['moderator']; + $json[$_GET['edit_domain']]['3'] = $_POST['admin']; + + $update = json_encode($json); + + $dbl->update("settings", Array( 'Value' => $update),"`Setting` = 'Domain_Auto_Add'"); + } catch ( Exception $e ) { return null; @@ -102,6 +125,14 @@ function domain_management_hook_get_db() $pagination = new Pagination( WebUsers :: getAllUsersQuery(), "web", 10, "WebUsers" ); $domain_management_return_set['userlist'] = Gui_Elements :: make_table( $pagination -> getElements() , Array( "getUId", "getUsername", "getEmail" ), Array( "id", "username", "email" ) ); + $dbl = new DBLayer("lib"); + + $statement = $dbl->execute("SELECT * FROM `settings` WHERE `Setting` = :setting", Array('setting' => 'Domain_Auto_Add')); + $json = $statement->fetch(); + $json = json_decode($json['Value'],true); + + $domain_management_return_set['Domain_Auto_Add'] = $json[$_GET['edit_domain']]; + } return $rows; diff --git a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl index 6c6a55b45..803d1133e 100644 --- a/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl +++ b/code/web/private_php/ams/plugins/Domain_Management/templates/index.tpl @@ -205,35 +205,58 @@
-
-
- -
- + + + + + +
- -
- -
- + + + + +
+
- -
-
- +
+
+
+
+
+ +
+
+
+
+
+ +
+
From 5e5fb49f122ef42b3dccfe46fda711aa7c348c11 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 15 Sep 2014 01:25:01 +0200 Subject: [PATCH 120/240] Slot count can now be changed. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 25 ++++++++++++++++++ .../plugins/gui_editor/expression_editor.h | 1 + .../plugins/gui_editor/expression_node.cpp | 26 ++++++++++++++++--- .../src/plugins/gui_editor/expression_node.h | 2 ++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 54f878afa..45cd9c2d6 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -28,6 +28,7 @@ #include "expr_link_dlg.h" #include +#include ExpressionEditor::ExpressionEditor( QWidget *parent ) : QMainWindow( parent ) @@ -70,6 +71,12 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Remove" ); connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) ); + if( m_selectionCount == 1 ) + { + a = menu.addAction( "Change slot count" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); + } + else if( m_selectionCount == 2 ) { a = menu.addAction( "Link" ); @@ -203,4 +210,22 @@ void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) addNode( name, 3 ); } +void ExpressionEditor::onChangeSlotCount() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + int oldc = node->slotCount(); + + int c = QInputDialog::getInt( this, + tr( "Change slot count" ), + tr( "Enter new slot count" ), + oldc, + 1, + 26 ); + + if( oldc == c ) + return; + + node->changeSlotCount( c ); +} diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 5b17d091d..26493b8a0 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -44,6 +44,7 @@ private Q_SLOTS: void onAddNode2(); void onAddNode3(); void onItemDblClicked( QTreeWidgetItem *item ); + void onChangeSlotCount(); private: diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 3098c6290..026857ee3 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -115,9 +115,7 @@ QGraphicsItem( parent ) ExpressionNode::~ExpressionNode() { clearLinks(); - - qDeleteAll( m_slots ); - m_slots.clear(); + clearSlots(); } QRectF ExpressionNode::boundingRect() const @@ -176,6 +174,28 @@ QPointF ExpressionNode::slotPos( int slot ) const return mp; } +void ExpressionNode::changeSlotCount( int count ) +{ + clearSlots(); + clearLinks(); + m_links.clear(); + + if( count <= 3 ) + m_h = 100.0; + else + m_h = 100.0 + 20.0 * ( count - 3 ); + + createSlots( count ); + + update(); +} + +void ExpressionNode::clearSlots() +{ + qDeleteAll( m_slots ); + m_slots.clear(); +} + bool ExpressionNode::slotEmpty( int slot ) const { if( m_links[ 0 ] == NULL ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 7d236475a..cf49c212f 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -42,6 +42,8 @@ public: QPointF slotPos( int slot ) const; int slotCount() const{ return m_slots.count(); } + void changeSlotCount( int count ); + void clearSlots(); bool slotEmpty( int slot ) const; From 07caf402c26327f2cd4cceb317fcd690ad71f450 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 15 Sep 2014 12:49:13 +0200 Subject: [PATCH 121/240] Fix bad type passed to sscanf --HG-- branch : develop --- code/ryzom/server/src/ai_service/sheets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/server/src/ai_service/sheets.cpp b/code/ryzom/server/src/ai_service/sheets.cpp index bc7ece4fa..8369023e0 100644 --- a/code/ryzom/server/src/ai_service/sheets.cpp +++ b/code/ryzom/server/src/ai_service/sheets.cpp @@ -581,7 +581,7 @@ void AISHEETS::CCreature::readGeorges(NLMISC::CSmartPtr const& } if (item.getValueByName(s, "Basics.FameForGuardAttack") && !s.empty()) { - double tmp; + float tmp; sscanf(s.c_str(), "%f", &tmp); _FameForGuardAttack = (sint32)tmp; } From 84046c8db478f8105b0e2e8eea1fe718d40550d7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 15 Sep 2014 14:33:07 +0200 Subject: [PATCH 122/240] Fix r2ed --HG-- branch : develop --- code/ryzom/client/src/far_tp.cpp | 2 +- code/ryzom/client/src/r2/dmc/com_lua_module.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/far_tp.cpp b/code/ryzom/client/src/far_tp.cpp index 5ecd90c9c..2fb3f0c37 100644 --- a/code/ryzom/client/src/far_tp.cpp +++ b/code/ryzom/client/src/far_tp.cpp @@ -1132,7 +1132,7 @@ void CFarTP::disconnectFromPreviousShard() */ NetMngr.reinit(); - if( !isReselectingChar() ) + if (isIngame()) { nlinfo("FarTP: calling EntitiesMngr.reinit()"); EntitiesMngr.reinit(); diff --git a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp index b91aca95c..c9b6a6df2 100644 --- a/code/ryzom/client/src/r2/dmc/com_lua_module.cpp +++ b/code/ryzom/client/src/r2/dmc/com_lua_module.cpp @@ -238,7 +238,15 @@ void CComLuaModule::initLuaLib() }; int initialStackSize = lua_gettop(_LuaState); #if LUA_VERSION_NUM >= 502 - luaL_newlib(_LuaState, methods); + // luaL_newlib(_LuaState, methods); + // lua_setglobal(_LuaState, R2_LUA_PATH); + lua_getglobal(_LuaState, R2_LUA_PATH); + if (lua_isnil(_LuaState, -1)) + { + lua_pop(_LuaState, 1); + lua_newtable(_LuaState); + } + luaL_setfuncs(_LuaState, methods, 0); lua_setglobal(_LuaState, R2_LUA_PATH); #else luaL_openlib(_LuaState, R2_LUA_PATH, methods, 0); From 9283a74a22af1e426d2739aa9ffb66ba674c9c38 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 15 Sep 2014 16:59:12 +0200 Subject: [PATCH 123/240] Fix r2ed --HG-- branch : develop --- code/ryzom/client/src/far_tp.cpp | 2 +- .../client/src/interface_v3/lua_ihm_ryzom.cpp | 1 + .../r2/r2_core_user_component_manager.lua | 2 +- code/ryzom/common/data_common/r2/r2_debug.lua | 3 +- code/ryzom/common/data_common/r2/r2_logic.lua | 2 +- code/ryzom/common/data_common/r2/r2_misc.lua | 14 ++- .../common/data_common/r2/r2_ui_forms.lua | 2 +- .../data_common/r2/r2_ui_property_sheet.lua | 92 +++++++++---------- .../data_common/r2/unit_test/r2_unit_test.lua | 12 +-- 9 files changed, 71 insertions(+), 59 deletions(-) diff --git a/code/ryzom/client/src/far_tp.cpp b/code/ryzom/client/src/far_tp.cpp index 2fb3f0c37..4f48d2ff5 100644 --- a/code/ryzom/client/src/far_tp.cpp +++ b/code/ryzom/client/src/far_tp.cpp @@ -1132,7 +1132,7 @@ void CFarTP::disconnectFromPreviousShard() */ NetMngr.reinit(); - if (isIngame()) + if (isIngame() && !isReselectingChar()) { nlinfo("FarTP: calling EntitiesMngr.reinit()"); EntitiesMngr.reinit(); diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp index fe4c6a716..996bd698a 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp @@ -1931,6 +1931,7 @@ void CLuaIHMRyzom::rawDebugInfo(const std::string &dbg) #endif pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(dbg)); } + nldebug("LUA: '%s'", dbg.c_str()); } diff --git a/code/ryzom/common/data_common/r2/r2_core_user_component_manager.lua b/code/ryzom/common/data_common/r2/r2_core_user_component_manager.lua index 6769d503b..4aa445484 100644 --- a/code/ryzom/common/data_common/r2/r2_core_user_component_manager.lua +++ b/code/ryzom/common/data_common/r2/r2_core_user_component_manager.lua @@ -1116,7 +1116,7 @@ function userComponentManager:export(list, refX, refY, refZ) messageBox(i18n.get("uiR2EDInvalidName")) return end - if string.find(form.ComponentFileName, '\.lua', -4) == nil then + if string.find(form.ComponentFileName, '.lua', -4) == nil then form.ComponentFileName = form.ComponentFileName .. ".lua" end local refPosition = form.RefPosition diff --git a/code/ryzom/common/data_common/r2/r2_debug.lua b/code/ryzom/common/data_common/r2/r2_debug.lua index 6a63b5472..78501dcab 100644 --- a/code/ryzom/common/data_common/r2/r2_debug.lua +++ b/code/ryzom/common/data_common/r2/r2_debug.lua @@ -140,7 +140,8 @@ end function assert(cond) if not cond then - rawDebugInfo(colorTag(255, 0, 255) .. "ASSERTION FAILED !! ") + -- rawDebugInfo(colorTag(255, 0, 255) .. "ASSERTION FAILED !! ") + rawDebugInfo("@{FOFF}ASSERTION FAILED !! ") dumpCallStack(2); error("") end diff --git a/code/ryzom/common/data_common/r2/r2_logic.lua b/code/ryzom/common/data_common/r2/r2_logic.lua index 1ee35d562..d50a15faf 100644 --- a/code/ryzom/common/data_common/r2/r2_logic.lua +++ b/code/ryzom/common/data_common/r2/r2_logic.lua @@ -1679,7 +1679,7 @@ Logic.translateChatSequences = function (context, hlComponent, behavior, rtNpcGr event.Name = "activity_sequence_changed" table.insert(context.RtAct.Events, event) - local rtInitChatStep = r2.Translator.createAction("code", "oldChatStepVar = -1;\n" .. Logic.chatStepVar .." = 0;\n()setTimer(1, " ..Logic.chatTimerId .. ")\;\n") + local rtInitChatStep = r2.Translator.createAction("code", "oldChatStepVar = -1;\n" .. Logic.chatStepVar .." = 0;\n()setTimer(1, " ..Logic.chatTimerId .. ");\n") rtInitChatStep.Name = "init_chat_step" table.insert(context.RtAct.Actions, rtInitChatStep) table.insert(event.ActionsId, rtInitChatStep.Id) diff --git a/code/ryzom/common/data_common/r2/r2_misc.lua b/code/ryzom/common/data_common/r2/r2_misc.lua index ee9e2885e..f3c9fa865 100644 --- a/code/ryzom/common/data_common/r2/r2_misc.lua +++ b/code/ryzom/common/data_common/r2/r2_misc.lua @@ -32,9 +32,8 @@ end -- extension to table library : remove all content of a table without deleting the table object function table.clear(tbl) while next(tbl) do - tbl[next(tbl)] = nil + table.remove(tbl, next(tbl)) end - table.setn(tbl, 0) end ------------------------------------------------------------------------------------------------------------ @@ -174,6 +173,17 @@ end function strify(str) return [["]] .. tostring(str) .. [["]] end + +------------------------------------------------------------------------------------------------- +-- enclose a string by double quotes +function strifyXml(str) + strxml = string.gsub(str, ">", ">") + strxml = string.gsub(strxml, "<", "<") + strxml = string.gsub(strxml, "&", "&") + strxml = string.gsub(strxml, "'", "'") + strxml = string.gsub(strxml, '"', """) + return [["]] .. tostring(strxml) .. [["]] +end ------------------------------------------------------------------------------------------------------------ -- snap a position to ground, returning the z snapped coordinate diff --git a/code/ryzom/common/data_common/r2/r2_ui_forms.lua b/code/ryzom/common/data_common/r2/r2_ui_forms.lua index ae1b4d656..587581f26 100644 --- a/code/ryzom/common/data_common/r2/r2_ui_forms.lua +++ b/code/ryzom/common/data_common/r2/r2_ui_forms.lua @@ -328,7 +328,7 @@ end local function saveScenarioOnChange(formInstance) r2.print(formInstance.Name) - local name = string.gsub(formInstance.Name, "[\\\/\:\*\?\"\<\>\|]", "_") + local name = string.gsub(formInstance.Name, "[\\/:*?\"<>|]", "_") if name ~= formInstance.Name then fromInstance.Name = name formInstance.Modified = true diff --git a/code/ryzom/common/data_common/r2/r2_ui_property_sheet.lua b/code/ryzom/common/data_common/r2/r2_ui_property_sheet.lua index 962eaf315..e4fbd4632 100644 --- a/code/ryzom/common/data_common/r2/r2_ui_property_sheet.lua +++ b/code/ryzom/common/data_common/r2/r2_ui_property_sheet.lua @@ -47,13 +47,13 @@ function r2:buildEditBox(prop, textRef, entryType, multiLine, maxNumChars, onCha bg_texture="grey_40.tga" onchange="lua" onchange_params="getUICaller():setupDisplayText(); getUICaller():find('edit_text'):updateCoords(); getUICaller():getEnclosingContainer().Env.updateSize()" onenter="lua" on_focus_lost="lua"]] .. - [[ id= ]] .. strify(prop.Name) .. - [[ text_ref = ]] .. strify(textRef) .. - [[ entry_type = ]] .. strify(entryType) .. - [[ multi_line = ]] .. strify(multiLine) .. - [[ max_num_chars = ]] .. strify(maxNumChars) .. - [[ params = ]] .. strify(onChangeAction) .. - [[ on_focus_lost_params = ]] .. strify(onFocusLostAction) .. + [[ id= ]] .. strifyXml(prop.Name) .. + [[ text_ref = ]] .. strifyXml(textRef) .. + [[ entry_type = ]] .. strifyXml(entryType) .. + [[ multi_line = ]] .. strifyXml(multiLine) .. + [[ max_num_chars = ]] .. strifyXml(maxNumChars) .. + [[ params = ]] .. strifyXml(onChangeAction) .. + [[ on_focus_lost_params = ]] .. strifyXml(onFocusLostAction) .. "/>" return result end @@ -73,13 +73,13 @@ end -- bg_texture="grey_40.tga" -- onchange="lua" onchange_params="getUICaller():setupDisplayText(); getUICaller():find('edit_text'):updateCoords(); getUICaller():getEnclosingContainer().Env.updateSize()" -- onenter="lua" on_focus_lost="lua"]] .. --- [[ id= ]] .. strify(prop.Name) .. --- [[ text_ref = ]] .. strify(textRef) .. --- [[ entry_type = ]] .. strify(entryType) .. --- [[ multi_line = ]] .. strify(multiLine) .. --- [[ max_num_chars = ]] .. strify(maxNumChars) .. --- [[ params = ]] .. strify(onChangeAction) .. --- [[ on_focus_lost_params = ]] .. strify(onChangeAction) .. +-- [[ id= ]] .. strifyXml(prop.Name) .. +-- [[ text_ref = ]] .. strifyXml(textRef) .. +-- [[ entry_type = ]] .. strifyXml(entryType) .. +-- [[ multi_line = ]] .. strifyXml(multiLine) .. +-- [[ max_num_chars = ]] .. strifyXml(maxNumChars) .. +-- [[ params = ]] .. strifyXml(onChangeAction) .. +-- [[ on_focus_lost_params = ]] .. strifyXml(onChangeAction) .. -- [[ /> -- -- @@ -1043,7 +1043,7 @@ r2.WidgetStyles.Number = width1 = tmp end - local part0 = [[ ]] + local part0 = [[ ]] local tooltipTextId, tooltipTextIdFound = buildPropTooltipName(className, prop.Name) @@ -1051,7 +1051,7 @@ r2.WidgetStyles.Number = tooltip_parent="win" tooltip_posref="auto" instant_help="true" - tooltip=]] .. strify(tooltipTextId) .. ">" + tooltip=]] .. strifyXml(tooltipTextId) .. ">" part0 = part0 .. buildCoverAllButton(prop) local color = "255 255 255 255" @@ -1066,10 +1066,10 @@ r2.WidgetStyles.Number = end part0 = part0 .. [[ ]] + [[ id = ]] .. strifyXml(prop.Name .. "_Caption") .. + [[ hardtext = ]] .. strifyXml(hardText) .. + [[ color = ]] .. strifyXml(color) .. + [[ global_color=]] .. strifyXml(globalColor) .. [[ fontsize="12" shadow="true" auto_clamp="true"/> ]] part0 = part0 .. "" part0 = part0 .. "" @@ -1086,7 +1086,7 @@ r2.WidgetStyles.Number = -- local widgetXml = string.format([[ - " .. [[ + " .. [[ " result = result .. [[]] -- append enumerated values for k, v in pairs(prop.Enum) do - result = result .. [[]] + result = result .. [[]] end result = result .. "" return result, setter @@ -1201,10 +1201,10 @@ function r2:createPropertyXmlTable(props, className, posparent, posref, x, y, wi result = result .. value end add([[ ]] + part0 = [[ ]] part0 = part0 .. [[" + tooltip=]] .. strifyXml(tooltipTextId) .. ">" part0 = part0 .. [[ ]] + [[ id = ]] .. strifyXml(prop.Name .. "_Caption") .. + [[ hardtext = ]] .. strifyXml(hardText) .. + [[ color = ]] .. strifyXml(color) .. + [[ global_color=]] .. strifyXml(globalColor) .. [[ fontsize="12" shadow="true" auto_clamp="true"/> ]] part0 = part0 .. "" part0 = part0 .. "" else @@ -1268,13 +1268,13 @@ function r2:createPropertyXmlTable(props, className, posparent, posref, x, y, wi end -- build the widget - local part1 = [[ ]] + local part1 = [[ ]] part1 = part1 .. [[" + tooltip=]] .. strifyXml(tooltipTextId) .. ">" part1 = part1 .. widgetXmlDesc .. [[]] if invertWidget then @@ -1397,15 +1397,15 @@ function r2:buildPropRolloutXml(caption, id, posparent, posref, props, className -- add the rollout bar if not isForm then result = result .. - [[ ]] else result = result .. - [[ ]] end @@ -1475,9 +1475,9 @@ function r2:buildPropertySheetXml(class, className, id, title, isForm) if isForm then -- for forms, closing the form is equivalent to clicking on 'cancel' add(' resizer="true" ') local w = defaulting(class.Width, 500) - add(' pop_min_w=' .. strify(w)) - add(' pop_max_w=' .. strify(w)) - add(' w=' .. strify(w)) + add(' pop_min_w=' .. strifyXml(w)) + add(' pop_max_w=' .. strifyXml(w)) + add(' w=' .. strifyXml(w)) local cancelCode = [[ local form = getUICaller() if form.Env.Choice == nil then @@ -1518,7 +1518,7 @@ function r2:buildPropertySheetXml(class, className, id, title, isForm) - add([[id=]] .. strify(id) .. [[ + add([[id=]] .. strifyXml(id) .. [[ >]]) @@ -1647,7 +1647,7 @@ function r2:buildPropertySheetXml(class, className, id, title, isForm) - + ]]) diff --git a/code/ryzom/common/data_common/r2/unit_test/r2_unit_test.lua b/code/ryzom/common/data_common/r2/unit_test/r2_unit_test.lua index 572f2080a..b48e3da5a 100644 --- a/code/ryzom/common/data_common/r2/unit_test/r2_unit_test.lua +++ b/code/ryzom/common/data_common/r2/unit_test/r2_unit_test.lua @@ -36,7 +36,7 @@ UnitTest.testLoadAnimationScenarioUi = function() end local filename = form.LoadScenario_Name - if string.find(filename, '\.r2', -3) == nil then + if string.find(filename, '.r2', -3) == nil then local ui = r2:getForm("LoadScenario") ui.active = true @@ -134,12 +134,12 @@ UnitTest.testLoadScenarioUi = function() local ucName = ucstring() ucName:fromUtf8(form.LoadScenario_Name) local filename = tostring(ucName) - if string.find(filename, '\.r2', -3) == nil then + if string.find(filename, '.r2', -3) == nil then messageBox(i18n.get("uiR2EDLoadScenario_InvalidFileName")) return end --- if string.find(filename, '\.r2', -3) == nil then +-- if string.find(filename, '.r2', -3) == nil then -- filename = form.Name .. ".r2" -- end @@ -206,7 +206,7 @@ function UnitTest.saveScenario(name, overwrite) messageBox(i18n.get("uiR2EDInvalidName")) return end - if string.find(name, '\.r2', -3) == nil then + if string.find(name, '.r2', -3) == nil then name = name .. ".r2" end -- update scenario name with the new name @@ -1103,8 +1103,8 @@ end function t5() - local toto = "&ezr_çà'_\\)d //:1' 2 éééà'..)à\/:*?\"<>|à)@4 58ftgsfdg\"\/:*?\"<>|" - toto = string.gsub(toto, "[\\\/\:\*\?\"\<\>\|]", "_") + local toto = "&ezr_çà'_\\)d //:1' 2 éééà'..)à/:*?\"<>|à)@4 58ftgsfdg\"/:*?\"<>|" + toto = string.gsub(toto, "[\\/:*?\"<>|]", "_") end From 74e9aac960ffb71f8511ae173770dbb3b606a72a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 15 Sep 2014 17:42:24 +0200 Subject: [PATCH 124/240] Fix r2ed --HG-- branch : develop --- .../client/src/interface_v3/lua_ihm_ryzom.cpp | 1 - code/ryzom/common/data_common/r2/r2_misc.lua | 45 ++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp index 996bd698a..fe4c6a716 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp @@ -1931,7 +1931,6 @@ void CLuaIHMRyzom::rawDebugInfo(const std::string &dbg) #endif pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(dbg)); } - nldebug("LUA: '%s'", dbg.c_str()); } diff --git a/code/ryzom/common/data_common/r2/r2_misc.lua b/code/ryzom/common/data_common/r2/r2_misc.lua index f3c9fa865..827e91579 100644 --- a/code/ryzom/common/data_common/r2/r2_misc.lua +++ b/code/ryzom/common/data_common/r2/r2_misc.lua @@ -28,12 +28,26 @@ function forEach(table, fn) end end + +------------------------------------------------------------------------------------------------------------ +-- whatever +table.setn = function(table, n) + assert(table) + local mt = getmetatable(table) + if mt ~= nil then + if mt.__next ~= nil then + table.Size = n + end + end +end + ------------------------------------------------------------------------------------------------------------ -- extension to table library : remove all content of a table without deleting the table object function table.clear(tbl) while next(tbl) do - table.remove(tbl, next(tbl)) + tbl[next(tbl)] = nil end + table.setn(tbl, 0) end ------------------------------------------------------------------------------------------------------------ @@ -177,12 +191,12 @@ end ------------------------------------------------------------------------------------------------- -- enclose a string by double quotes function strifyXml(str) - strxml = string.gsub(str, ">", ">") + local strxml = string.gsub(tostring(str), ">", ">") strxml = string.gsub(strxml, "<", "<") strxml = string.gsub(strxml, "&", "&") strxml = string.gsub(strxml, "'", "'") strxml = string.gsub(strxml, '"', """) - return [["]] .. tostring(strxml) .. [["]] + return [["]] .. strxml .. [["]] end ------------------------------------------------------------------------------------------------------------ @@ -261,26 +275,37 @@ end -assert(table.getn ~= nil) -- default lib should have been opened +-- assert(table.getn ~= nil) -- default lib should have been opened + +--if oldTableGetnFunction == nil then +-- oldTableGetnFunction = table.getn +--end +-- +--table.getn = function(table) +-- assert(table) +-- local mt = getmetatable(table) +-- if mt ~= nil then +-- if mt.__next ~= nil then +-- return table.Size +-- end +-- end +-- return oldTableGetnFunction(table) +--end -if oldTableGetnFunction == nil then - oldTableGetnFunction = table.getn -end table.getn = function(table) assert(table) local mt = getmetatable(table) if mt ~= nil then if mt.__next ~= nil then - return table.Size + return table.Size end end - return oldTableGetnFunction(table) + return #table end - -- redefine the hardcoded 'pairs' function to use the redefined 'next' -- hardcoded version uses the C version of next, not the lua one if it has been redefined From c789a22155f5caed8a0e0ee6c445fb190f97c3bf Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 15 Sep 2014 18:15:40 +0200 Subject: [PATCH 125/240] Fix r2ed --HG-- branch : develop --- code/ryzom/common/data_common/r2/r2_translator.lua | 4 +++- code/ryzom/common/data_common/r2/r2_ui_event_handlers.lua | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/ryzom/common/data_common/r2/r2_translator.lua b/code/ryzom/common/data_common/r2/r2_translator.lua index 600928d98..e1c4701ba 100644 --- a/code/ryzom/common/data_common/r2/r2_translator.lua +++ b/code/ryzom/common/data_common/r2/r2_translator.lua @@ -541,7 +541,7 @@ Translator.translateEventHandlers = function(context, hlNpc, eventHandlers, rtNp while k do local caller = nil if devMode then - caller = function (...) arg[1](arg[2], arg[3], arg[4], arg[5]) return true end + caller = function (...) local arg = {...} arg[1](arg[2], arg[3], arg[4], arg[5]) return true end else caller = pcall @@ -898,6 +898,7 @@ end -- Returns a RtNpcEventHandlerAction if the action is allowed --first parameter: action type Translator.createAction = function(...) + local arg = {...} local debug=config.R2EDExtendedDebug local function header(toto) @@ -2774,6 +2775,7 @@ end --third param : GroupsByName --then, parameters Translator.createEvent = function(...) + local arg = {...} local event = r2.newComponent("RtNpcEventHandler") local eventType = arg[1] event.Event = eventType diff --git a/code/ryzom/common/data_common/r2/r2_ui_event_handlers.lua b/code/ryzom/common/data_common/r2/r2_ui_event_handlers.lua index 0cd5c8638..431d89eae 100644 --- a/code/ryzom/common/data_common/r2/r2_ui_event_handlers.lua +++ b/code/ryzom/common/data_common/r2/r2_ui_event_handlers.lua @@ -1030,6 +1030,7 @@ end -------------------- -------------------- function r2:updateAnimBarActions(...) + local arg = {...} -- forward to the real anim bar r2.ui.AnimBar:updateActions(arg) end From af744111042b5cea16d986efc39bb943863f4499 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 02:32:10 +0200 Subject: [PATCH 126/240] Parse expression files, and build the expression tree from the expressions parsed from these files. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 56 +++++ .../plugins/gui_editor/expression_editor.h | 8 + .../plugins/gui_editor/expression_editor.ui | 50 ----- .../src/plugins/gui_editor/expression_info.h | 34 +++ .../plugins/gui_editor/expression_loader.cpp | 203 ++++++++++++++++++ .../plugins/gui_editor/expression_loader.h | 39 ++++ .../plugins/gui_editor/expression_store.cpp | 105 +++++++++ .../src/plugins/gui_editor/expression_store.h | 46 ++++ .../plugins/gui_editor/gui_editor_window.cpp | 1 + 9 files changed, 492 insertions(+), 50 deletions(-) create mode 100644 code/studio/src/plugins/gui_editor/expression_info.h create mode 100644 code/studio/src/plugins/gui_editor/expression_loader.cpp create mode 100644 code/studio/src/plugins/gui_editor/expression_loader.h create mode 100644 code/studio/src/plugins/gui_editor/expression_store.cpp create mode 100644 code/studio/src/plugins/gui_editor/expression_store.h diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 45cd9c2d6..773191afc 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -26,14 +26,24 @@ #include "expression_node.h" #include "expression_link.h" #include "expr_link_dlg.h" +#include "expression_store.h" +#include "expression_info.h" #include #include +class ExpressionEditorPvt +{ +public: + ExpressionStore store; +}; + ExpressionEditor::ExpressionEditor( QWidget *parent ) : QMainWindow( parent ) { m_ui.setupUi( this ); + + m_pvt = new ExpressionEditorPvt(); m_selectionCount = 0; @@ -48,9 +58,27 @@ QMainWindow( parent ) ExpressionEditor::~ExpressionEditor() { + delete m_pvt; + m_pvt = NULL; m_scene = NULL; } +void ExpressionEditor::load() +{ + m_pvt->store.load(); + + QList< const ExpressionInfo* > l; + m_pvt->store.getExpressions( l ); + + QListIterator< const ExpressionInfo* > itr( l ); + while( itr.hasNext() ) + { + addExpression( itr.next() ); + } + + l.clear(); +} + void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) { QMenu menu; @@ -229,3 +257,31 @@ void ExpressionEditor::onChangeSlotCount() node->changeSlotCount( c ); } +void ExpressionEditor::addExpression( const ExpressionInfo *info ) +{ + QTreeWidgetItem *item = findTopLevelItem( info->category ); + if( item == NULL ) + { + item = new QTreeWidgetItem(); + item->setText( 0, info->category ); + m_ui.tree->addTopLevelItem( item ); + } + + QTreeWidgetItem *citem = new QTreeWidgetItem(); + citem->setText( 0, info->name ); + item->addChild( citem ); +} + +QTreeWidgetItem* ExpressionEditor::findTopLevelItem( const QString &text ) +{ + int c = m_ui.tree->topLevelItemCount(); + for( int i = 0; i < c; i++ ) + { + QTreeWidgetItem *item = m_ui.tree->topLevelItem( i ); + if( item->text( 0 ) == text ) + return item; + } + + return NULL; +} + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 26493b8a0..21f247249 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -23,6 +23,8 @@ #include "ui_expression_editor.h" class QGraphicsScene; +class ExpressionEditorPvt; +class ExpressionInfo; class ExpressionEditor : public QMainWindow { @@ -31,6 +33,8 @@ public: ExpressionEditor( QWidget *parent = NULL ); ~ExpressionEditor(); + void load(); + protected: void contextMenuEvent( QContextMenuEvent *e ); @@ -47,12 +51,16 @@ private Q_SLOTS: void onChangeSlotCount(); private: + void addExpression( const ExpressionInfo *info ); + QTreeWidgetItem* findTopLevelItem( const QString &text ); Ui::ExpressionEditor m_ui; QGraphicsScene *m_scene; int m_selectionCount; int m_nodeCount; + + ExpressionEditorPvt *m_pvt; }; #endif diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui index db71014bf..342b2b5f1 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.ui +++ b/code/studio/src/plugins/gui_editor/expression_editor.ui @@ -44,56 +44,6 @@ Expressions - - - Logical - - - - and - - - - - or - - - - - - Mathematical - - - - add - - - - - sub - - - - - - Value - - - - integer - - - - - string - - - - - boolean - - - diff --git a/code/studio/src/plugins/gui_editor/expression_info.h b/code/studio/src/plugins/gui_editor/expression_info.h new file mode 100644 index 000000000..854ea12c1 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_info.h @@ -0,0 +1,34 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_INFO +#define EXPRESSION_INFO + +#include +#include + +struct ExpressionInfo +{ + QString name; + QString category; + bool variable; + QStringList slotNames; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_loader.cpp b/code/studio/src/plugins/gui_editor/expression_loader.cpp new file mode 100644 index 000000000..ee3346a0c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_loader.cpp @@ -0,0 +1,203 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_loader.h" +#include "expression_info.h" + +#include +#include + +class ExpressionLoaderPvt +{ +public: + + bool parseName() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->name = text; + + return true; + } + + bool parseCategory() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->category = text; + + return true; + } + + bool parseVariable() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + if( text.toLower() == "true" ) + m_info->variable = true; + else + m_info->variable = false; + + return true; + } + + bool parseSlot() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->slotNames.push_back( text ); + + return true; + } + + bool parseSlots() + { + bool error = false; + + while( !reader.atEnd() ) + { + reader.readNext(); + + if( reader.isStartElement() ) + { + QString name = reader.name().toString(); + if( name == "slot" ) + error = !parseSlot(); + } + else + if( reader.isEndElement() ) + { + if( reader.name() == "slots" ) + break; + } + } + + if( reader.atEnd() ) + return false; + + return true; + } + + bool load( QFile *f ) + { + reader.clear(); + reader.setDevice( f ); + + bool error = false; + + // start of document + reader.readNext(); + if( reader.atEnd() ) + return false; + + // root node + reader.readNext(); + if( reader.atEnd() ) + return false; + + if( reader.isStartElement() ) + { + // Not an expression file? + if( reader.name() != "expression" ) + return false; + } + + while( !reader.atEnd() ) + { + reader.readNext(); + + if( reader.isStartElement() ) + { + QString name = reader.name().toString(); + + if( name == "name" ) + error = !parseName(); + else + if( name == "category" ) + error = !parseCategory(); + else + if( name == "variable" ) + error = !parseVariable(); + else + if( name == "slots" ) + error = !parseSlots(); + } + + if( error ) + break; + } + + if( error || reader.hasError() ) + { + return false; + } + + return true; + } + + void setInfo( ExpressionInfo *info ){ m_info = info; } + +private: + QXmlStreamReader reader; + ExpressionInfo *m_info; +}; + +ExpressionLoader::ExpressionLoader() +{ + m_pvt = new ExpressionLoaderPvt; +} + +ExpressionLoader::~ExpressionLoader() +{ + delete m_pvt; + m_pvt = NULL; +} + +ExpressionInfo* ExpressionLoader::load( const QString &filename ) +{ + ExpressionInfo *info = NULL; + bool ok = false; + + QFile f( filename ); + if( !f.open( QIODevice::ReadOnly | QIODevice::Text ) ) + return NULL; + + info = new ExpressionInfo(); + m_pvt->setInfo( info ); + ok = m_pvt->load( &f ); + + f.close(); + + if( !ok ) + { + delete info; + info = NULL; + } + + return info; +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_loader.h b/code/studio/src/plugins/gui_editor/expression_loader.h new file mode 100644 index 000000000..f315fcdcd --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_loader.h @@ -0,0 +1,39 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_LOADER +#define EXPRESSION_LOADER + +struct ExpressionInfo; +class QString; +class ExpressionLoaderPvt; + +class ExpressionLoader +{ +public: + ExpressionLoader(); + ~ExpressionLoader(); + + ExpressionInfo* load( const QString &filename ); + +private: + ExpressionLoaderPvt *m_pvt; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_store.cpp b/code/studio/src/plugins/gui_editor/expression_store.cpp new file mode 100644 index 000000000..9f2218b4e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_store.cpp @@ -0,0 +1,105 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_store.h" +#include "expression_info.h" +#include "expression_loader.h" +#include +#include + +class ExpressionStorePvt +{ +public: + + ~ExpressionStorePvt() + { + qDeleteAll( expressions ); + expressions.clear(); + } + + + QMap< QString, ExpressionInfo* > expressions; +}; + +ExpressionStore::ExpressionStore() +{ + m_pvt = new ExpressionStorePvt(); +} + +ExpressionStore::~ExpressionStore() +{ + delete m_pvt; + m_pvt = NULL; +} + + +bool ExpressionStore::load() +{ + QDir d( "expressions" ); + if( !d.exists() ) + return false; + + QFileInfoList l = d.entryInfoList(); + QListIterator< QFileInfo > itr( l ); + if( !itr.hasNext() ) + return false; + + ExpressionLoader loader; + + while( itr.hasNext() ) + { + const QFileInfo &info = itr.next(); + if( !info.isFile() ) + continue; + + if( info.suffix() != "xml" ) + continue; + + ExpressionInfo *expr = loader.load( info.absoluteFilePath() ); + if( expr == NULL ) + continue; + + m_pvt->expressions[ expr->name ] = expr; + } + + return false; +} + +void ExpressionStore::getExpressions( QList< const ExpressionInfo* > &l ) const +{ + l.clear(); + + QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.constBegin(); + while( itr != m_pvt->expressions.constEnd() ) + { + l.push_back( itr.value() ); + ++itr; + } +} + +const ExpressionInfo* ExpressionStore::getInfo( const QString &name ) +{ + QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.find( name ); + if( itr == m_pvt->expressions.end() ) + return NULL; + else + return itr.value(); +} + + + diff --git a/code/studio/src/plugins/gui_editor/expression_store.h b/code/studio/src/plugins/gui_editor/expression_store.h new file mode 100644 index 000000000..9c29fa0f6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_store.h @@ -0,0 +1,46 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_STORE +#define EXPRESSION_STORE + +#include +#include +#include "expression_info.h" + +//struct ExpressionInfo; +class ExpressionStorePvt; + +class ExpressionStore +{ +public: + ExpressionStore(); + ~ExpressionStore(); + + bool load(); + + void getExpressions( QList< const ExpressionInfo* > &l ) const; + + const ExpressionInfo* getInfo( const QString &name ); + +private: + ExpressionStorePvt *m_pvt; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index f6adacc8a..2447ac0af 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -75,6 +75,7 @@ namespace GUIEditor tc = new TextureChooser(); ee = new ExpressionEditor(); + ee->load(); createMenus(); readSettings(); From 89aaa52703e2b4dc804b67ca345e96e90d7b6f3a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 03:38:21 +0200 Subject: [PATCH 127/240] Set the number of slots and their names from the data loaded from XMLs. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 34 +++++-------------- .../plugins/gui_editor/expression_editor.h | 5 +-- .../plugins/gui_editor/expression_node.cpp | 11 ++++++ .../src/plugins/gui_editor/expression_node.h | 2 ++ 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 773191afc..81bd22373 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -205,37 +205,21 @@ void ExpressionEditor::onUnLinkItems() } } -void ExpressionEditor::addNode( const QString &name, int slotCount ) +void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) { + QString name = item->text( 0 ); + + const ExpressionInfo *info = m_pvt->store.getInfo( name ); + QString n = name; n += " #"; n += QString::number( m_nodeCount ); m_nodeCount++; - QGraphicsItem *item = new ExpressionNode( n, slotCount ); - item->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); - m_scene->addItem( item ); -} - -void ExpressionEditor::onAddNode1() -{ - addNode( "node", 1 ); -} - -void ExpressionEditor::onAddNode2() -{ - addNode( "node", 2 ); -} - -void ExpressionEditor::onAddNode3() -{ - addNode( "node", 3 ); -} - -void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) -{ - QString name = item->text( 0 ); - addNode( name, 3 ); + ExpressionNode *node = new ExpressionNode( n, info->slotNames.count() ); + node->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + node->setSlotNames( info->slotNames ); + m_scene->addItem( node ); } void ExpressionEditor::onChangeSlotCount() diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 21f247249..79ff908f1 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -23,6 +23,7 @@ #include "ui_expression_editor.h" class QGraphicsScene; +class QGraphicsItem; class ExpressionEditorPvt; class ExpressionInfo; @@ -43,10 +44,6 @@ private Q_SLOTS: void onSelectionChanged(); void onLinkItems(); void onUnLinkItems(); - void addNode( const QString &name, int slotCount ); - void onAddNode1(); - void onAddNode2(); - void onAddNode3(); void onItemDblClicked( QTreeWidgetItem *item ); void onChangeSlotCount(); diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 026857ee3..bb2eb451f 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -90,6 +90,7 @@ public: } QString text() const{ return m_info.text; } + void setText( const QString &text ){ m_info.text = text; } private: NodeSlotInfo m_info; @@ -229,6 +230,16 @@ ExpressionLink* ExpressionNode::link( int slot ) const return m_links[ slot ]; } +void ExpressionNode::setSlotNames( const QList< QString > &l ) +{ + int c = l.count(); + for( int i = 0; i < c; i++ ) + { + // "Out" slot is at position 0, so set the names with an offset of 1 + m_slots[ i + 1 ]->setText( l[ i ] ); + } +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { for( int i = 0; i < m_links.count(); i++ ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index cf49c212f..e43e717bb 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -53,6 +53,8 @@ public: QString name() const{ return m_name; } + void setSlotNames( const QList< QString > &l ); + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); From 142d82d78838799a732e26e05a63196e19a8ace3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 03:45:26 +0200 Subject: [PATCH 128/240] Only allow variable nodes to have their number of slots changed. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 22 +++++++++---------- .../plugins/gui_editor/expression_node.cpp | 2 ++ .../src/plugins/gui_editor/expression_node.h | 5 +++++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 81bd22373..df83a6732 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -84,15 +84,6 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) QMenu menu; QAction *a = NULL; - QMenu *mm = menu.addMenu( "Add node" ); - a = mm->addAction( "1 slot" ); - connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode1() ) ); - - a = mm->addAction( "2 slots" ); - connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode2() ) ); - - a = mm->addAction( "3 slots" ); - connect( a, SIGNAL( triggered() ), this, SLOT( onAddNode3() ) ); if( m_selectionCount > 0 ) { @@ -101,8 +92,16 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) if( m_selectionCount == 1 ) { - a = menu.addAction( "Change slot count" ); - connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ 0 ] ); + if( node != NULL ) + { + if( node->variable() ) + { + a = menu.addAction( "Change slot count" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); + } + } } else if( m_selectionCount == 2 ) @@ -219,6 +218,7 @@ void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) ExpressionNode *node = new ExpressionNode( n, info->slotNames.count() ); node->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); node->setSlotNames( info->slotNames ); + node->setVariable( info->variable ); m_scene->addItem( node ); } diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index bb2eb451f..8c736c919 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -105,6 +105,8 @@ QGraphicsItem( parent ) m_h = 100; m_hh = 20.0; + m_variable = false; + m_name = name; if( slotCount > 3 ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index e43e717bb..ebf2c9fd5 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -55,6 +55,9 @@ public: void setSlotNames( const QList< QString > &l ); + void setVariable( bool b ){ m_variable = b; } + bool variable() const{ return m_variable; } + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); @@ -70,6 +73,8 @@ private: QList< ExpressionLink* > m_links; QString m_name; + + bool m_variable; }; #endif From f0e78b5fbba34670eb8dc2d232c8cff8ec47179c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 15:15:31 +0200 Subject: [PATCH 129/240] Allow to set and change values of value nodes. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 33 +++++++++++++++++++ .../plugins/gui_editor/expression_editor.h | 1 + .../src/plugins/gui_editor/expression_info.h | 7 ++++ .../plugins/gui_editor/expression_loader.cpp | 17 ++++++++++ .../plugins/gui_editor/expression_node.cpp | 15 +++++++++ .../src/plugins/gui_editor/expression_node.h | 9 +++++ 6 files changed, 82 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index df83a6732..502c135e1 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -101,6 +101,12 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Change slot count" ); connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); } + + if( node->isValue() ) + { + a = menu.addAction( "Change value" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onChangeValue() ) ); + } } } else @@ -219,6 +225,11 @@ void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) node->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); node->setSlotNames( info->slotNames ); node->setVariable( info->variable ); + node->setIsValue( info->value ); + if( node->isValue() ) + { + node->setValue( "Value" ); + } m_scene->addItem( node ); } @@ -241,6 +252,28 @@ void ExpressionEditor::onChangeSlotCount() node->changeSlotCount( c ); } +void ExpressionEditor::onChangeValue() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + + QString oldValue = node->getValue(); + + QString newValue = QInputDialog::getText( this, + tr( "Change value" ), + tr( "Enter new value" ), + QLineEdit::Normal, + oldValue ); + + if( newValue.isEmpty() ) + return; + if( newValue == oldValue ) + return; + + node->setValue( newValue ); + node->update(); +} + void ExpressionEditor::addExpression( const ExpressionInfo *info ) { QTreeWidgetItem *item = findTopLevelItem( info->category ); diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 79ff908f1..9380c6b29 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -46,6 +46,7 @@ private Q_SLOTS: void onUnLinkItems(); void onItemDblClicked( QTreeWidgetItem *item ); void onChangeSlotCount(); + void onChangeValue(); private: void addExpression( const ExpressionInfo *info ); diff --git a/code/studio/src/plugins/gui_editor/expression_info.h b/code/studio/src/plugins/gui_editor/expression_info.h index 854ea12c1..86218b6af 100644 --- a/code/studio/src/plugins/gui_editor/expression_info.h +++ b/code/studio/src/plugins/gui_editor/expression_info.h @@ -25,9 +25,16 @@ struct ExpressionInfo { QString name; + bool value; QString category; bool variable; QStringList slotNames; + + ExpressionInfo() + { + value = false; + variable = false; + } }; #endif diff --git a/code/studio/src/plugins/gui_editor/expression_loader.cpp b/code/studio/src/plugins/gui_editor/expression_loader.cpp index ee3346a0c..07db432e0 100644 --- a/code/studio/src/plugins/gui_editor/expression_loader.cpp +++ b/code/studio/src/plugins/gui_editor/expression_loader.cpp @@ -37,6 +37,20 @@ public: return true; } + bool parseValue() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + if( text.toLower() == "true" ) + m_info->value = true; + else + m_info->value = false; + + return true; + } + bool parseCategory() { QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); @@ -136,6 +150,9 @@ public: if( name == "name" ) error = !parseName(); else + if( name == "value" ) + error = !parseValue(); + else if( name == "category" ) error = !parseCategory(); else diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8c736c919..3a67a2d8d 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -106,6 +106,7 @@ QGraphicsItem( parent ) m_hh = 20.0; m_variable = false; + m_isValue = false; m_name = name; @@ -152,6 +153,20 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o painter->setPen( p ); painter->drawText( header, Qt::AlignCenter, m_name ); + // Draw value if applicable + if( m_isValue ) + { + QRectF vbox; + vbox.setTopLeft( QPoint( 0.0, 20.0 ) ); + vbox.setWidth( header.width() ); + vbox.setHeight( header.height() ); + QPen vpen; + vpen.setColor( Qt::red ); + painter->setPen( vpen ); + painter->drawText( vbox, Qt::AlignCenter, m_value ); + painter->setPen( p ); + } + if( option->state & QStyle::State_Selected ) { p.setStyle( Qt::DotLine ); diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index ebf2c9fd5..52d515bbb 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -58,6 +58,12 @@ public: void setVariable( bool b ){ m_variable = b; } bool variable() const{ return m_variable; } + void setValue( const QString &value ){ m_value = value; } + QString getValue() const{ return m_value; } + + bool isValue() const{ return m_isValue; } + void setIsValue( bool b ){ m_isValue = b; } + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); @@ -75,6 +81,9 @@ private: QString m_name; bool m_variable; + + QString m_value; + bool m_isValue; }; #endif From 5e91c2f374c36facaf1e89733cd56d5c206a0dd5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 15:31:06 +0200 Subject: [PATCH 130/240] When changing the value of a node, change the size the node if needed. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expression_editor.cpp | 1 - .../src/plugins/gui_editor/expression_node.cpp | 13 +++++++++++++ .../studio/src/plugins/gui_editor/expression_node.h | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 502c135e1..1a16762e7 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -271,7 +271,6 @@ void ExpressionEditor::onChangeValue() return; node->setValue( newValue ); - node->update(); } void ExpressionEditor::addExpression( const ExpressionInfo *info ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 3a67a2d8d..d7a548dc4 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -257,6 +257,19 @@ void ExpressionNode::setSlotNames( const QList< QString > &l ) } } +void ExpressionNode::setValue( const QString &value ) +{ + m_value = value; + + int c = m_value.count(); + if( c < 15 ) + m_w = 100.0; + else + m_w = m_w + ( 100.0 / 15.0 ) * ( c - 15.0 ); + + update(); +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { for( int i = 0; i < m_links.count(); i++ ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 52d515bbb..f4b75ca1a 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -58,7 +58,7 @@ public: void setVariable( bool b ){ m_variable = b; } bool variable() const{ return m_variable; } - void setValue( const QString &value ){ m_value = value; } + void setValue( const QString &value ); QString getValue() const{ return m_value; } bool isValue() const{ return m_isValue; } From cc071e504802b0c49ec143b432c7cee89e52438a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 16 Sep 2014 15:54:53 +0200 Subject: [PATCH 131/240] Added sample expression files. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expressions/add.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/and.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/div.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/eq.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/ifthenelse.xml | 10 ++++++++++ code/studio/src/plugins/gui_editor/expressions/mul.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/ne.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/not.xml | 8 ++++++++ code/studio/src/plugins/gui_editor/expressions/or.xml | 9 +++++++++ code/studio/src/plugins/gui_editor/expressions/sub.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/value.xml | 6 ++++++ 11 files changed, 96 insertions(+) create mode 100644 code/studio/src/plugins/gui_editor/expressions/add.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/and.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/div.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/eq.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/mul.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/ne.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/not.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/or.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/sub.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/value.xml diff --git a/code/studio/src/plugins/gui_editor/expressions/add.xml b/code/studio/src/plugins/gui_editor/expressions/add.xml new file mode 100644 index 000000000..62cec88af --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/add.xml @@ -0,0 +1,9 @@ + +Mathematical +add +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/and.xml b/code/studio/src/plugins/gui_editor/expressions/and.xml new file mode 100644 index 000000000..cc8c05c6e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/and.xml @@ -0,0 +1,9 @@ + +Logical +and +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/div.xml b/code/studio/src/plugins/gui_editor/expressions/div.xml new file mode 100644 index 000000000..aba3faffc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/div.xml @@ -0,0 +1,9 @@ + +Mathematical +div +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/eq.xml b/code/studio/src/plugins/gui_editor/expressions/eq.xml new file mode 100644 index 000000000..77b7041cc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/eq.xml @@ -0,0 +1,9 @@ + +Logical +eq +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml new file mode 100644 index 000000000..248a68332 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml @@ -0,0 +1,10 @@ + +Logical +ifthenelse +false + +if +then +else + + diff --git a/code/studio/src/plugins/gui_editor/expressions/mul.xml b/code/studio/src/plugins/gui_editor/expressions/mul.xml new file mode 100644 index 000000000..54d03b025 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/mul.xml @@ -0,0 +1,9 @@ + +Mathematical +mul +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ne.xml b/code/studio/src/plugins/gui_editor/expressions/ne.xml new file mode 100644 index 000000000..31d62af02 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ne.xml @@ -0,0 +1,9 @@ + +Logical +ne +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/not.xml b/code/studio/src/plugins/gui_editor/expressions/not.xml new file mode 100644 index 000000000..872b9b7a4 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/not.xml @@ -0,0 +1,8 @@ + +Logical +not +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/or.xml b/code/studio/src/plugins/gui_editor/expressions/or.xml new file mode 100644 index 000000000..2d977267c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/or.xml @@ -0,0 +1,9 @@ + +Logical +or +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/sub.xml b/code/studio/src/plugins/gui_editor/expressions/sub.xml new file mode 100644 index 000000000..5f35c2895 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sub.xml @@ -0,0 +1,9 @@ + +Mathematical +sub +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/value.xml b/code/studio/src/plugins/gui_editor/expressions/value.xml new file mode 100644 index 000000000..9bd57fc95 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/value.xml @@ -0,0 +1,6 @@ + +Value +value +true +false + From 094a23bd09fea6198e575be6565c1b7b5b86bb45 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Tue, 16 Sep 2014 20:34:26 +0200 Subject: [PATCH 133/240] fixing #206 : passwords are now stored using SHA-512 instead of traditional DES --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- .../common/src/game_share/CMakeLists.txt | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 + .../src/game_share/{crypt.h => ccrypt.h} | 0 code/ryzom/common/src/game_share/crypt.cpp | 980 ------------------ .../src/monitor_service/service_main.cpp | 12 +- code/web/private_php/ams/autoload/users.php | 8 +- code/web/private_php/setup/sql/nel_00001.sql | 2 +- .../private_php/setup/sql/nel_ams_00001.sql | 2 +- code/web/public_php/ams/autoload/webusers.php | 9 +- code/web/public_php/ams/sql/db.sql | 4 +- code/web/public_php/login/r2_login.php | 17 +- 12 files changed, 75 insertions(+), 993 deletions(-) create mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp rename code/ryzom/common/src/game_share/{crypt.h => ccrypt.h} (100%) delete mode 100644 code/ryzom/common/src/game_share/crypt.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 091e24a80..673a5b5f4 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/crypt.h" +#include "game_share/ccrypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/CMakeLists.txt b/code/ryzom/common/src/game_share/CMakeLists.txt index 2648416ec..cbccfd6dd 100644 --- a/code/ryzom/common/src/game_share/CMakeLists.txt +++ b/code/ryzom/common/src/game_share/CMakeLists.txt @@ -30,7 +30,7 @@ NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC} ${R2}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges crypt ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) NL_DEFAULT_PROPS(ryzom_gameshare "Ryzom, Library: Game Share") NL_ADD_RUNTIME_FLAGS(ryzom_gameshare) NL_ADD_LIB_SUFFIX(ryzom_gameshare) diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp new file mode 100644 index 000000000..ea67cf7d6 --- /dev/null +++ b/code/ryzom/common/src/game_share/ccrypt.cpp @@ -0,0 +1,30 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "ccrypt.h" + +#define _GNU_SOURCE 1 +#include + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::crypt(password.c_str(), salt.c_str()); + + return result; +} diff --git a/code/ryzom/common/src/game_share/crypt.h b/code/ryzom/common/src/game_share/ccrypt.h similarity index 100% rename from code/ryzom/common/src/game_share/crypt.h rename to code/ryzom/common/src/game_share/ccrypt.h diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp deleted file mode 100644 index 0da908817..000000000 --- a/code/ryzom/common/src/game_share/crypt.cpp +++ /dev/null @@ -1,980 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "crypt.h" - -char * rz_crypt(register const char *key, register const char *setting); - - - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::rz_crypt(password.c_str(), salt.c_str()); - - return result; -} - - - - - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Tom Truscott. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -/* #include */ -#include -#include -#define RZ__PASSWORD_EFMT1 '-' - -#if DEBUG_CRYPT -void prtab(char *s, unsigned char *t, int num_rows); -#endif - -/* - * UNIX password, and DES, encryption. - * By Tom Truscott, trt@rti.rti.org, - * from algorithms by Robert W. Baldwin and James Gillogly. - * - * References: - * "Mathematical Cryptology for Computer Scientists and Mathematicians," - * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. - * - * "Password Security: A Case History," R. Morris and Ken Thompson, - * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. - * - * "DES will be Totally Insecure within Ten Years," M.E. Hellman, - * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. - */ - -/* ===== Configuration ==================== */ - -/* - * define "MUST_ALIGN" if your compiler cannot load/store - * long integers at arbitrary (e.g. odd) memory locations. - * (Either that or never pass unaligned addresses to des_cipher!) - */ -#if !defined(vax) -#define MUST_ALIGN -#endif - -#ifdef CHAR_BITS -#if CHAR_BITS != 8 - #error C_block structure assumes 8 bit characters -#endif -#endif - -/* - * define "LONG_IS_32_BITS" only if sizeof(long)==4. - * This avoids use of bit fields (your compiler may be sloppy with them). - */ -#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) -#define LONG_IS_32_BITS -#endif - -/* - * define "B64" to be the declaration for a 64 bit integer. - * XXX this feature is currently unused, see "endian" comment below. - */ -#if defined(cray) || defined(__LP64__) || defined(_LP64) -#define B64 long -#endif -#if defined(convex) -#define B64 long long -#endif - -/* - * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes - * of lookup tables. This speeds up des_setkey() and des_cipher(), but has - * little effect on crypt(). - */ -#if defined(notdef) -#define LARGEDATA -#endif - -/* ==================================== */ - -/* - * Cipher-block representation (Bob Baldwin): - * - * DES operates on groups of 64 bits, numbered 1..64 (sigh). One - * representation is to store one bit per byte in an array of bytes. Bit N of - * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. - * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the - * first byte, 9..16 in the second, and so on. The DES spec apparently has - * bit 1 in the MSB of the first byte, but that is particularly noxious so we - * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is - * the MSB of the first byte. Specifically, the 64-bit input data and key are - * converted to LSB format, and the output 64-bit block is converted back into - * MSB format. - * - * DES operates internally on groups of 32 bits which are expanded to 48 bits - * by permutation E and shrunk back to 32 bits by the S boxes. To speed up - * the computation, the expansion is applied only once, the expanded - * representation is maintained during the encryption, and a compression - * permutation is applied only at the end. To speed up the S-box lookups, - * the 48 bits are maintained as eight 6 bit groups, one per byte, which - * directly feed the eight S-boxes. Within each byte, the 6 bits are the - * most significant ones. The low two bits of each byte are zero. (Thus, - * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the - * first byte in the eight byte representation, bit 2 of the 48 bit value is - * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is - * used, in which the output is the 64 bit result of an S-box lookup which - * has been permuted by P and expanded by E, and is ready for use in the next - * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this - * lookup. Since each byte in the 48 bit path is a multiple of four, indexed - * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and - * "salt" are also converted to this 8*(6+2) format. The SPE table size is - * 8*64*8 = 4K bytes. - * - * To speed up bit-parallel operations (such as XOR), the 8 byte - * representation is "union"ed with 32 bit values "i0" and "i1", and, on - * machines which support it, a 64 bit value "b64". This data structure, - * "C_block", has two problems. First, alignment restrictions must be - * honored. Second, the byte-order (e.g. little-endian or big-endian) of - * the architecture becomes visible. - * - * The byte-order problem is unfortunate, since on the one hand it is good - * to have a machine-independent C_block representation (bits 1..8 in the - * first byte, etc.), and on the other hand it is good for the LSB of the - * first byte to be the LSB of i0. We cannot have both these things, so we - * currently use the "little-endian" representation and avoid any multi-byte - * operations that depend on byte order. This largely precludes use of the - * 64-bit datatype since the relative order of i0 and i1 are unknown. It - * also inhibits grouping the SPE table to look up 12 bits at a time. (The - * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 - * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the - * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup - * requires a 128 kilobyte table, so perhaps this is not a big loss. - * - * Permutation representation (Jim Gillogly): - * - * A transformation is defined by its effect on each of the 8 bytes of the - * 64-bit input. For each byte we give a 64-bit output that has the bits in - * the input distributed appropriately. The transformation is then the OR - * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for - * each transformation. Unless LARGEDATA is defined, however, a more compact - * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. - * The smaller table uses 16*16*8 = 2K bytes for each transformation. This - * is slower but tolerable, particularly for password encryption in which - * the SPE transformation is iterated many times. The small tables total 9K - * bytes, the large tables total 72K bytes. - * - * The transformations used are: - * IE3264: MSB->LSB conversion, initial permutation, and expansion. - * This is done by collecting the 32 even-numbered bits and applying - * a 32->64 bit transformation, and then collecting the 32 odd-numbered - * bits and applying the same transformation. Since there are only - * 32 input bits, the IE3264 transformation table is half the size of - * the usual table. - * CF6464: Compression, final permutation, and LSB->MSB conversion. - * This is done by two trivial 48->32 bit compressions to obtain - * a 64-bit block (the bit numbering is given in the "CIFP" table) - * followed by a 64->64 bit "cleanup" transformation. (It would - * be possible to group the bits in the 64-bit block so that 2 - * identical 32->32 bit transformations could be used instead, - * saving a factor of 4 in space and possibly 2 in time, but - * byte-ordering and other complications rear their ugly head. - * Similar opportunities/problems arise in the key schedule - * transforms.) - * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. - * This admittedly baroque 64->64 bit transformation is used to - * produce the first code (in 8*(6+2) format) of the key schedule. - * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. - * It would be possible to define 15 more transformations, each - * with a different rotation, to generate the entire key schedule. - * To save space, however, we instead permute each code into the - * next by using a transformation that "undoes" the PC2 permutation, - * rotates the code, and then applies PC2. Unfortunately, PC2 - * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not - * invertible. We get around that problem by using a modified PC2 - * which retains the 8 otherwise-lost bits in the unused low-order - * bits of each byte. The low-order bits are cleared when the - * codes are stored into the key schedule. - * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. - * This is faster than applying PC2ROT[0] twice, - * - * The Bell Labs "salt" (Bob Baldwin): - * - * The salting is a simple permutation applied to the 48-bit result of E. - * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and - * i+24 of the result are swapped. The salt is thus a 24 bit number, with - * 16777216 possible values. (The original salt was 12 bits and could not - * swap bits 13..24 with 36..48.) - * - * It is possible, but ugly, to warp the SPE table to account for the salt - * permutation. Fortunately, the conditional bit swapping requires only - * about four machine instructions and can be done on-the-fly with about an - * 8% performance penalty. - */ - -typedef union { - unsigned char b[8]; - struct { -#if defined(LONG_IS_32_BITS) - /* long is often faster than a 32-bit bit field */ - long i0; - long i1; -#else - long i0: 32; - long i1: 32; -#endif - } b32; -#if defined(B64) - B64 b64; -#endif -} C_block; - -/* - * Convert twenty-four-bit long in host-order - * to six bits (and 2 low-order zeroes) per char little-endian format. - */ -#define TO_SIX_BIT(rslt, src) { \ - C_block cvt; \ - cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ - cvt.b[3] = (unsigned char) (src&0xFF); \ - rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ - } - -/* - * These macros may someday permit efficient use of 64-bit integers. - */ -#define ZERO(d,d0,d1) d0 = 0, d1 = 0 -#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 -#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 -#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 -#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 -#define DCL_BLOCK(d,d0,d1) long d0, d1 - -#if defined(LARGEDATA) - /* Waste memory like crazy. Also, do permutations in line */ -#define LGCHUNKBITS 3 -#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); - STORE(D,D0,D1,*out); -} -#endif /* LARGEDATA */ - - -/* ===== (mostly) Standard DES Tables ==================== */ - -static unsigned char IP[] = { /* initial permutation */ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, -}; - -/* The final permutation is the inverse of IP - no table is necessary */ - -static unsigned char ExpandTr[] = { /* expansion operation */ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1, -}; - -static unsigned char PC1[] = { /* permuted choice table 1 */ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4, -}; - -static unsigned char Rotates[] = { /* PC1 rotation schedule */ - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, -}; - -/* note: each "row" of PC2 is left-padded with bits that make it invertible */ -static unsigned char PC2[] = { /* permuted choice table 2 */ - 9, 18, 14, 17, 11, 24, 1, 5, - 22, 25, 3, 28, 15, 6, 21, 10, - 35, 38, 23, 19, 12, 4, 26, 8, - 43, 54, 16, 7, 27, 20, 13, 2, - - 0, 0, 41, 52, 31, 37, 47, 55, - 0, 0, 30, 40, 51, 45, 33, 48, - 0, 0, 44, 49, 39, 56, 34, 53, - 0, 0, 46, 42, 50, 36, 29, 32, -}; - -static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ - /* S[1] */ - {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, - /* S[2] */ - {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, - /* S[3] */ - {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, - /* S[4] */ - { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, - /* S[5] */ - { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, - /* S[6] */ - {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, - /* S[7] */ - { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, - /* S[8] */ - {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} -}; - -static unsigned char P32Tr[] = { /* 32-bit permutation function */ - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25, -}; - -static unsigned char CIFP[] = { /* compressed/interleaved permutation */ - 1, 2, 3, 4, 17, 18, 19, 20, - 5, 6, 7, 8, 21, 22, 23, 24, - 9, 10, 11, 12, 25, 26, 27, 28, - 13, 14, 15, 16, 29, 30, 31, 32, - - 33, 34, 35, 36, 49, 50, 51, 52, - 37, 38, 39, 40, 53, 54, 55, 56, - 41, 42, 43, 44, 57, 58, 59, 60, - 45, 46, 47, 48, 61, 62, 63, 64, -}; - -static unsigned char itoa64[] = /* 0..63 => ascii-64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - -/* ===== Tables that are initialized at run time ==================== */ - - -static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ - -/* Initial key schedule permutation */ -static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ -static C_block CF6464[64/CHUNKBITS][1<= 0; ) { - if ((t = (unsigned char)setting[i]) == '\0') - t = '.'; - encp[i] = t; - num_iter = (num_iter<<6) | a64toi[t]; - } - setting += 4; - encp += 4; - salt_size = 4; - break; - default: - num_iter = 25; - salt_size = 2; - } - - salt = 0; - for (i = salt_size; --i >= 0; ) { - if ((t = (unsigned char)setting[i]) == '\0') - t = '.'; - encp[i] = t; - salt = (salt<<6) | a64toi[t]; - } - encp += salt_size; - if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, - salt, num_iter)) - return (NULL); - - /* - * Encode the 64 cipher bits as 11 ascii characters. - */ - i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; - encp[3] = itoa64[i&0x3f]; i >>= 6; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; encp += 4; - i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; - encp[3] = itoa64[i&0x3f]; i >>= 6; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; encp += 4; - i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; - encp[2] = itoa64[i&0x3f]; i >>= 6; - encp[1] = itoa64[i&0x3f]; i >>= 6; - encp[0] = itoa64[i]; - - encp[3] = 0; - - return (cryptresult); -} - - -/* - * The Key Schedule, filled in by des_setkey() or setkey(). - */ -#define KS_SIZE 16 -static C_block KS[KS_SIZE]; - -/* - * Set up the key schedule from the key. - */ -int rz_des_setkey(register const char *key) { - register DCL_BLOCK(K, K0, K1); - register C_block *ptabp; - register int i; - static int des_ready = 0; - - if (!des_ready) { - rz_init_des(); - des_ready = 1; - } - - PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); - key = (char *)&KS[0]; - STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); - for (i = 1; i < 16; i++) { - key += sizeof(C_block); - STORE(K,K0,K1,*(C_block *)key); - ptabp = (C_block *)PC2ROT[Rotates[i]-1]; - PERM6464(K,K0,K1,(unsigned char *)key,ptabp); - STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); - } - return (0); -} - -/* - * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) - * iterations of DES, using the given 24-bit salt and the pre-computed key - * schedule, and store the resulting 8 chars at "out" (in == out is permitted). - * - * NOTE: the performance of this routine is critically dependent on your - * compiler and machine architecture. - */ -int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { - /* variables that we want in registers, most important first */ -#if defined(pdp11) - register int j; -#endif - register long L0, L1, R0, R1, k; - register C_block *kp; - register int ks_inc, loop_count; - C_block B; - - L0 = salt; - TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ - -#if defined(vax) || defined(pdp11) - salt = ~salt; /* "x &~ y" is faster than "x & y". */ -#define SALT (~salt) -#else -#define SALT salt -#endif - -#if defined(MUST_ALIGN) - B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; - B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; - LOAD(L,L0,L1,B); -#else - LOAD(L,L0,L1,*(C_block *)in); -#endif - LOADREG(R,R0,R1,L,L0,L1); - L0 &= 0x55555555L; - L1 &= 0x55555555L; - L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ - R0 &= 0xaaaaaaaaL; - R1 = (R1 >> 1) & 0x55555555L; - L1 = R0 | R1; /* L1 is the odd-numbered input bits */ - STORE(L,L0,L1,B); - PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ - PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ - - if (num_iter >= 0) - { /* encryption */ - kp = &KS[0]; - ks_inc = sizeof(*kp); - } - else - { /* decryption */ - num_iter = -num_iter; - kp = &KS[KS_SIZE-1]; - ks_inc = -((int) sizeof(*kp)); - } - - while (--num_iter >= 0) { - loop_count = 8; - do { - -#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) -#if defined(gould) - /* use this if B.b[i] is evaluated just once ... */ -#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); -#else -#if defined(pdp11) - /* use this if your "long" int indexing is slow */ -#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); -#else - /* use this if "k" is allocated to a register ... */ -#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); -#endif -#endif - -#define CRUNCH(p0, p1, q0, q1) \ - k = (q0 ^ q1) & SALT; \ - B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ - B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ - kp = (C_block *)((char *)kp+ks_inc); \ - \ - DOXOR(p0, p1, 0); \ - DOXOR(p0, p1, 1); \ - DOXOR(p0, p1, 2); \ - DOXOR(p0, p1, 3); \ - DOXOR(p0, p1, 4); \ - DOXOR(p0, p1, 5); \ - DOXOR(p0, p1, 6); \ - DOXOR(p0, p1, 7); - - CRUNCH(L0, L1, R0, R1); - CRUNCH(R0, R1, L0, L1); - } while (--loop_count != 0); - kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); - - - /* swap L and R */ - L0 ^= R0; L1 ^= R1; - R0 ^= L0; R1 ^= L1; - L0 ^= R0; L1 ^= R1; - } - - /* store the encrypted (or decrypted) result */ - L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); - L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); - STORE(L,L0,L1,B); - PERM6464(L,L0,L1,B.b, (C_block *)CF6464); -#if defined(MUST_ALIGN) - STORE(L,L0,L1,B); - out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; - out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; -#else - STORE(L,L0,L1,*(C_block *)out); -#endif - return (0); -} - - -/* - * Initialize various tables. This need only be done once. It could even be - * done at compile time, if the compiler were capable of that sort of thing. - */ -/* STATIC */void rz_init_des() { - register int i, j; - register long k; - register int tableno; - static unsigned char perm[64], tmp32[32]; /* "static" for speed */ - - /* - * table that converts chars "./0-9A-Za-z"to integers 0-63. - */ - for (i = 0; i < 64; i++) - a64toi[itoa64[i]] = i; - - /* - * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. - */ - for (i = 0; i < 64; i++) - perm[i] = 0; - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - k += Rotates[0]-1; - if ((k%28) < Rotates[0]) k -= 28; - k = PC1[k]; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[i] = (unsigned char) k; - } -#ifdef DEBUG_CRYPT - prtab("pc1tab", perm, 8); -#endif - rz_init_perm(PC1ROT, perm, 8, 8); - - /* - * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. - */ - for (j = 0; j < 2; j++) { - unsigned char pc2inv[64]; - for (i = 0; i < 64; i++) - perm[i] = pc2inv[i] = 0; - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - pc2inv[k-1] = i+1; - } - for (i = 0; i < 64; i++) { - if ((k = PC2[i]) == 0) - continue; - k += j; - if ((k%28) <= j) k -= 28; - perm[i] = pc2inv[k]; - } -#ifdef DEBUG_CRYPT - prtab("pc2tab", perm, 8); -#endif - rz_init_perm(PC2ROT[j], perm, 8, 8); - } - - /* - * Bit reverse, then initial permutation, then expansion. - */ - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; - if (k > 32) - k -= 32; - else if (k > 0) - k--; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[i*8+j] = (unsigned char) k; - } - } -#ifdef DEBUG_CRYPT - prtab("ietab", perm, 8); -#endif - rz_init_perm(IE3264, perm, 4, 8); - - /* - * Compression, then final permutation, then bit reverse. - */ - for (i = 0; i < 64; i++) { - k = IP[CIFP[i]-1]; - if (k > 0) { - k--; - k = (k|07) - (k&07); - k++; - } - perm[k-1] = i+1; - } -#ifdef DEBUG_CRYPT - prtab("cftab", perm, 8); -#endif - rz_init_perm(CF6464, perm, 8, 8); - - /* - * SPE table - */ - for (i = 0; i < 48; i++) - perm[i] = P32Tr[ExpandTr[i]-1]; - for (tableno = 0; tableno < 8; tableno++) { - for (j = 0; j < 64; j++) { - k = (((j >> 0) &01) << 5)| - (((j >> 1) &01) << 3)| - (((j >> 2) &01) << 2)| - (((j >> 3) &01) << 1)| - (((j >> 4) &01) << 0)| - (((j >> 5) &01) << 4); - k = S[tableno][k]; - k = (((k >> 3)&01) << 0)| - (((k >> 2)&01) << 1)| - (((k >> 1)&01) << 2)| - (((k >> 0)&01) << 3); - for (i = 0; i < 32; i++) - tmp32[i] = 0; - for (i = 0; i < 4; i++) - tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); - k = 0; - for (i = 24; --i >= 0; ) - k = (k<<1) | tmp32[perm[i]-1]; - TO_SIX_BIT(SPE[0][tableno][j], k); - k = 0; - for (i = 24; --i >= 0; ) - k = (k<<1) | tmp32[perm[i+24]-1]; - TO_SIX_BIT(SPE[1][tableno][j], k); - } - } -} - -/* - * Initialize "perm" to represent transformation "p", which rearranges - * (perhaps with expansion and/or contraction) one packed array of bits - * (of size "chars_in" characters) into another array (of size "chars_out" - * characters). - * - * "perm" must be all-zeroes on entry to this routine. - */ -/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ - l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ - for (j = 0; j < (1<>3] |= 1<<(k&07); - } - } -} - -/* - * "setkey" routine (for backwards compatibility) - */ -int rz_setkey(register const char *key) { - register int i, j, k; - C_block keyblock; - - for (i = 0; i < 8; i++) { - k = 0; - for (j = 0; j < 8; j++) { - k <<= 1; - k |= (unsigned char)*key++; - } - keyblock.b[i] = k; - } - return (rz_des_setkey((char *)keyblock.b)); -} - -/* - * "encrypt" routine (for backwards compatibility) - */ -int rz_encrypt(register char *block, int flag) { - register int i, j, k; - C_block cblock; - - for (i = 0; i < 8; i++) { - k = 0; - for (j = 0; j < 8; j++) { - k <<= 1; - k |= (unsigned char)*block++; - } - cblock.b[i] = k; - } - if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) - return (1); - for (i = 7; i >= 0; i--) { - k = cblock.b[i]; - for (j = 7; j >= 0; j--) { - *--block = k&01; - k >>= 1; - } - } - return (0); -} - -#ifdef DEBUG_CRYPT -void prtab(char *s, unsigned char *t, int num_rows) -{ - register int i, j; - - (void)printf("%s:\n", s); - for (i = 0; i < num_rows; i++) { - for (j = 0; j < 8; j++) { - (void)printf("%3d", t[i*8+j]); - } - (void)printf("\n"); - } - (void)printf("\n"); -} -#endif diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index a0e577269..aa559b78d 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/crypt.h" +#include "game_share/ccrypt.h" #include "nel/misc/time_nl.h" #include "client.h" @@ -392,7 +392,15 @@ void clientAuthentication(CMessage &msgin, TSockId from, CCallbackNetBase &netba { if (strlen(row[0]) > 2) { - std::string salt = std::string(row[0], row[0] + 2); + std::string salt; + if (row[0][0] == '$') + { + salt = std::string(row[0], row[0] + 19); + } + else + { + salt = std::string(row[0], row[0] + 2); + } std::string cryptedVersion = CCrypt::crypt(password, salt); if (cryptedVersion == row[0]) { diff --git a/code/web/private_php/ams/autoload/users.php b/code/web/private_php/ams/autoload/users.php index ffc04ace2..67ed9af88 100644 --- a/code/web/private_php/ams/autoload/users.php +++ b/code/web/private_php/ams/autoload/users.php @@ -252,8 +252,8 @@ class Users{ * @param $length the length of the SALT which is by default 2 * @return a random salt of 2 chars */ - public static function generateSALT( $length = 2 ) - { + public static function generateSALT( $length = 16 ) + { // start with a blank salt $salt = ""; // define possible characters - any character in this string can be @@ -282,6 +282,10 @@ class Users{ } } // done! + if ($length > 2) + { + $salt = '$6$'.$salt; + } return $salt; } diff --git a/code/web/private_php/setup/sql/nel_00001.sql b/code/web/private_php/setup/sql/nel_00001.sql index 70e14419b..15743b1b9 100644 --- a/code/web/private_php/setup/sql/nel_00001.sql +++ b/code/web/private_php/setup/sql/nel_00001.sql @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `shard` ( CREATE TABLE IF NOT EXISTS `user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `ShardId` int(10) NOT NULL DEFAULT '-1', `State` enum('Offline','Online') NOT NULL DEFAULT 'Offline', `Privilege` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_ams_00001.sql b/code/web/private_php/setup/sql/nel_ams_00001.sql index c2b0a8895..38085bc1f 100644 --- a/code/web/private_php/setup/sql/nel_ams_00001.sql +++ b/code/web/private_php/setup/sql/nel_ams_00001.sql @@ -29,7 +29,7 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT '1', `FirstName` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/public_php/ams/autoload/webusers.php b/code/web/public_php/ams/autoload/webusers.php index b01ddf02d..ebc654f5d 100644 --- a/code/web/public_php/ams/autoload/webusers.php +++ b/code/web/public_php/ams/autoload/webusers.php @@ -80,7 +80,14 @@ class WebUsers extends Users{ $dbw = new DBLayer("web"); $statement = $dbw->select("ams_user", array('value' => $value),"Login=:value OR Email=:value"); $row = $statement->fetch(); - $salt = substr($row['Password'],0,2); + if ($row['Password'][0] == '$') + { + $salt = substr($row['Password'], 0, 19); + } + else + { + $salt = substr($row['Password'], 0, 2); + } $hashed_input_pass = crypt($password, $salt); if($hashed_input_pass == $row['Password']){ return $row; diff --git a/code/web/public_php/ams/sql/db.sql b/code/web/public_php/ams/sql/db.sql index ccc214125..6620a9856 100644 --- a/code/web/public_php/ams/sql/db.sql +++ b/code/web/public_php/ams/sql/db.sql @@ -5,7 +5,7 @@ DROP TABLE IF EXISTS ams_user; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL AUTO_INCREMENT, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(13) DEFAULT NULL, + `Password` varchar(106) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT 1, PRIMARY KEY (`UId`) @@ -21,4 +21,4 @@ CREATE TABLE ams_querycache ( `SID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `type` VARCHAR( 64 ) NOT NULL , `query` VARCHAR( 512 ) NOT NULL -); \ No newline at end of file +); diff --git a/code/web/public_php/login/r2_login.php b/code/web/public_php/login/r2_login.php index ee4b68819..fdce63958 100644 --- a/code/web/public_php/login/r2_login.php +++ b/code/web/public_php/login/r2_login.php @@ -14,6 +14,19 @@ include_once('../ring/join_shard.php'); + function get_salt($password) + { + if ($password[0] == '$') + { + $salt = substr($password, 0, 19); + } + else + { + $salt = substr($password, 0, 2); + } + return $salt; + } + // see errorMsg function errorMsgBlock($errNum=GENERIC_ERROR_NUM) // $mixedArgs { @@ -331,7 +344,7 @@ else { $row = mysqli_fetch_assoc ($result); - $salt = substr($row["Password"],0,2); + $salt = get_salt($row["Password"]); if (($cp && $row["Password"] == $password) || (!$cp && $row["Password"] == crypt($password, $salt))) { // Store the real login (with correct case) @@ -488,7 +501,7 @@ else { $res_array = mysqli_fetch_assoc($result); - $salt = substr($res_array['Password'], 0, 2); + $salt = get_salt($res_array['Password']); } echo "1:".$salt; From 5c2cc95dc98390addc04f19f83b6ba4fc3ee98cb Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Tue, 16 Sep 2014 22:43:36 +0200 Subject: [PATCH 134/240] Fixing the database migration system for issue #206 --HG-- branch : sha512-auth --- code/web/private_php/setup/sql/nel_00001.sql | 2 +- code/web/private_php/setup/sql/nel_00004.sql | 1 + code/web/private_php/setup/sql/nel_ams_00001.sql | 2 +- code/web/private_php/setup/sql/nel_ams_00002.sql | 1 + code/web/public_php/ams/sql/db.sql | 2 +- code/web/public_php/setup/database.php | 4 ++-- 6 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 code/web/private_php/setup/sql/nel_00004.sql create mode 100644 code/web/private_php/setup/sql/nel_ams_00002.sql diff --git a/code/web/private_php/setup/sql/nel_00001.sql b/code/web/private_php/setup/sql/nel_00001.sql index 15743b1b9..70e14419b 100644 --- a/code/web/private_php/setup/sql/nel_00001.sql +++ b/code/web/private_php/setup/sql/nel_00001.sql @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `shard` ( CREATE TABLE IF NOT EXISTS `user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `ShardId` int(10) NOT NULL DEFAULT '-1', `State` enum('Offline','Online') NOT NULL DEFAULT 'Offline', `Privilege` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_00004.sql b/code/web/private_php/setup/sql/nel_00004.sql new file mode 100644 index 000000000..8d48a4c8c --- /dev/null +++ b/code/web/private_php/setup/sql/nel_00004.sql @@ -0,0 +1 @@ +ALTER TABLE `user` MODIFY `Password` VARCHAR(106); diff --git a/code/web/private_php/setup/sql/nel_ams_00001.sql b/code/web/private_php/setup/sql/nel_ams_00001.sql index 38085bc1f..c2b0a8895 100644 --- a/code/web/private_php/setup/sql/nel_ams_00001.sql +++ b/code/web/private_php/setup/sql/nel_ams_00001.sql @@ -29,7 +29,7 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT '1', `FirstName` varchar(255) NOT NULL DEFAULT '', diff --git a/code/web/private_php/setup/sql/nel_ams_00002.sql b/code/web/private_php/setup/sql/nel_ams_00002.sql new file mode 100644 index 000000000..b1a9c9df4 --- /dev/null +++ b/code/web/private_php/setup/sql/nel_ams_00002.sql @@ -0,0 +1 @@ +ALTER TABLE `ams_user` MODIFY `Password` VARCHAR(106); diff --git a/code/web/public_php/ams/sql/db.sql b/code/web/public_php/ams/sql/db.sql index 6620a9856..b52ae65ed 100644 --- a/code/web/public_php/ams/sql/db.sql +++ b/code/web/public_php/ams/sql/db.sql @@ -5,7 +5,7 @@ DROP TABLE IF EXISTS ams_user; CREATE TABLE IF NOT EXISTS `ams_user` ( `UId` int(10) NOT NULL AUTO_INCREMENT, `Login` varchar(64) NOT NULL DEFAULT '', - `Password` varchar(106) DEFAULT NULL, + `Password` varchar(13) DEFAULT NULL, `Email` varchar(255) NOT NULL DEFAULT '', `Permission` int(3) NOT NULL DEFAULT 1, PRIMARY KEY (`UId`) diff --git a/code/web/public_php/setup/database.php b/code/web/public_php/setup/database.php index 6a1b836ea..3e195f2b8 100644 --- a/code/web/public_php/setup/database.php +++ b/code/web/public_php/setup/database.php @@ -1,11 +1,11 @@ Date: Wed, 17 Sep 2014 14:41:57 +0200 Subject: [PATCH 135/240] A root node can now be set. The root node is where the evaluation will start. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 25 ++++++++++++++++++- .../plugins/gui_editor/expression_editor.h | 1 + .../plugins/gui_editor/expression_node.cpp | 22 +++++++++++++--- .../src/plugins/gui_editor/expression_node.h | 2 ++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 1a16762e7..0967b33e1 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -35,7 +35,14 @@ class ExpressionEditorPvt { public: + + ExpressionEditorPvt() + { + m_root = NULL; + } + ExpressionStore store; + ExpressionNode *m_root; }; ExpressionEditor::ExpressionEditor( QWidget *parent ) : @@ -101,12 +108,15 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Change slot count" ); connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); } - + else if( node->isValue() ) { a = menu.addAction( "Change value" ); connect( a, SIGNAL( triggered() ), this, SLOT( onChangeValue() ) ); } + + a = menu.addAction( "Set as root" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSetRoot() ) ); } } else @@ -273,6 +283,19 @@ void ExpressionEditor::onChangeValue() node->setValue( newValue ); } +void ExpressionEditor::onSetRoot() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + + if( m_pvt->m_root != NULL ) + m_pvt->m_root->setRoot( false ); + + m_pvt->m_root = node; + node->setRoot( true ); +} + + void ExpressionEditor::addExpression( const ExpressionInfo *info ) { QTreeWidgetItem *item = findTopLevelItem( info->category ); diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 9380c6b29..448ac536c 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -47,6 +47,7 @@ private Q_SLOTS: void onItemDblClicked( QTreeWidgetItem *item ); void onChangeSlotCount(); void onChangeValue(); + void onSetRoot(); private: void addExpression( const ExpressionInfo *info ); diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index d7a548dc4..17343c11c 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -107,6 +107,7 @@ QGraphicsItem( parent ) m_variable = false; m_isValue = false; + m_isRoot = false; m_name = name; @@ -139,9 +140,18 @@ void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *o header.setHeight( m_hh ); // Draw filled rectangle, header - c.setRed( 44 ); - c.setGreen( 169 ); - c.setBlue( 232 ); + if( !m_isRoot ) + { + c.setRed( 44 ); + c.setGreen( 169 ); + c.setBlue( 232 ); + } + else + { + c.setRed( 255 ); + c.setGreen( 0 ); + c.setBlue( 0 ); + } br.setColor( c ); br.setStyle( Qt::SolidPattern ); p.setColor( c ); @@ -270,6 +280,12 @@ void ExpressionNode::setValue( const QString &value ) update(); } +void ExpressionNode::setRoot( bool b ) +{ + m_isRoot = b; + update(); +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { for( int i = 0; i < m_links.count(); i++ ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index f4b75ca1a..ec1fb9c67 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -63,6 +63,7 @@ public: bool isValue() const{ return m_isValue; } void setIsValue( bool b ){ m_isValue = b; } + void setRoot( bool b ); protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); @@ -84,6 +85,7 @@ private: QString m_value; bool m_isValue; + bool m_isRoot; }; #endif From 5f47f744312463dc7ea16957fbbe0e7551171e17 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 15:31:54 +0200 Subject: [PATCH 136/240] Expression can now be built. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 22 +++++++++++- .../plugins/gui_editor/expression_editor.h | 1 + .../src/plugins/gui_editor/expression_link.h | 3 ++ .../plugins/gui_editor/expression_node.cpp | 35 +++++++++++++++++++ .../src/plugins/gui_editor/expression_node.h | 2 ++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 0967b33e1..a1c35e892 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -89,7 +89,6 @@ void ExpressionEditor::load() void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) { QMenu menu; - QAction *a = NULL; if( m_selectionCount > 0 ) @@ -129,6 +128,11 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Unlink" ); connect( a, SIGNAL( triggered() ), this, SLOT( onUnLinkItems() ) ); } + else + { + a = menu.addAction( "Build expression" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onBuildExpression() ) ); + } menu.exec( e->globalPos() ); } @@ -295,6 +299,22 @@ void ExpressionEditor::onSetRoot() node->setRoot( true ); } +void ExpressionEditor::onBuildExpression() +{ + if( m_pvt->m_root == NULL ) + { + QMessageBox::information( this, + tr( "Building expression" ), + tr( "Failed to build expression: You must set a root node." ) ); + return; + } + + QString result = m_pvt->m_root->build(); + QMessageBox::information( this, + tr( "Building expression" ), + tr( "The result is\n" ) + result ); +} + void ExpressionEditor::addExpression( const ExpressionInfo *info ) { diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 448ac536c..700813618 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -48,6 +48,7 @@ private Q_SLOTS: void onChangeSlotCount(); void onChangeValue(); void onSetRoot(); + void onBuildExpression(); private: void addExpression( const ExpressionInfo *info ); diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h index a5235737c..4e6df90dd 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.h +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -36,6 +36,9 @@ public: void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + ExpressionNode* from() const{ return m_from; } + ExpressionNode* to() const{ return m_to; } + private: ExpressionNode *m_from; ExpressionNode *m_to; diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 17343c11c..8316d8901 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -286,6 +286,41 @@ void ExpressionNode::setRoot( bool b ) update(); } +QString ExpressionNode::build() const +{ + QString result; + + if( isValue() ) + return m_value; + + QStringList l = m_name.split( ' ' ); + result = l[ 0 ]; + result += "( "; + + int c = m_links.count(); + for( int i = 1; i < c; i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + ExpressionNode *node = NULL; + + if( link->from() == this ) + node = link->to(); + else + node = link->from(); + + result += node->build(); + + if( i != ( c - 1 ) ) + result += ", "; + } + + result += " )"; + return result; +} + void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) { for( int i = 0; i < m_links.count(); i++ ) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index ec1fb9c67..101a6ebf8 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -65,6 +65,8 @@ public: void setIsValue( bool b ){ m_isValue = b; } void setRoot( bool b ); + QString build() const; + protected: void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); From 83859cdd82b9012e36dc7488984c5552dcb682e3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 15:47:49 +0200 Subject: [PATCH 137/240] Save expression. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expression_editor.cpp | 13 +++++++++++++ .../src/plugins/gui_editor/expression_editor.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index a1c35e892..db77d18f6 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -132,6 +132,9 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) { a = menu.addAction( "Build expression" ); connect( a, SIGNAL( triggered() ), this, SLOT( onBuildExpression() ) ); + + a = menu.addAction( "Save" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSave() ) ); } menu.exec( e->globalPos() ); @@ -315,6 +318,16 @@ void ExpressionEditor::onBuildExpression() tr( "The result is\n" ) + result ); } +void ExpressionEditor::onSave() +{ + if( m_pvt->m_root != NULL ) + { + m_result = m_pvt->m_root->build(); + } + + hide(); +} + void ExpressionEditor::addExpression( const ExpressionInfo *info ) { diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 700813618..02db8e06b 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -35,6 +35,7 @@ public: ~ExpressionEditor(); void load(); + QString result() const{ return m_result; } protected: void contextMenuEvent( QContextMenuEvent *e ); @@ -49,6 +50,7 @@ private Q_SLOTS: void onChangeValue(); void onSetRoot(); void onBuildExpression(); + void onSave(); private: void addExpression( const ExpressionInfo *info ); @@ -61,6 +63,7 @@ private: int m_nodeCount; ExpressionEditorPvt *m_pvt; + QString m_result; }; #endif From b715b6eaf6056c8e5ad1baedd47f96252391719e Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 15:50:12 +0200 Subject: [PATCH 138/240] This is the GUI Editor not Georges... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expr_link_dlg.cpp | 2 +- code/studio/src/plugins/gui_editor/expr_link_dlg.h | 2 +- code/studio/src/plugins/gui_editor/expr_slot_info.h | 2 +- code/studio/src/plugins/gui_editor/expression_editor.cpp | 2 +- code/studio/src/plugins/gui_editor/expression_editor.h | 2 +- code/studio/src/plugins/gui_editor/expression_link.cpp | 2 +- code/studio/src/plugins/gui_editor/expression_link.h | 2 +- code/studio/src/plugins/gui_editor/expression_node.cpp | 2 +- code/studio/src/plugins/gui_editor/expression_node.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp index 9a91e5f21..e8d01af85 100644 --- a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.h b/code/studio/src/plugins/gui_editor/expr_link_dlg.h index 267787cf3..3f3ba97c0 100644 --- a/code/studio/src/plugins/gui_editor/expr_link_dlg.h +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.h @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expr_slot_info.h b/code/studio/src/plugins/gui_editor/expr_slot_info.h index 9614cd96a..470edf68d 100644 --- a/code/studio/src/plugins/gui_editor/expr_slot_info.h +++ b/code/studio/src/plugins/gui_editor/expr_slot_info.h @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index db77d18f6..32eefbf08 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 02db8e06b..9f7bd6101 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index 537d4891f..f946c10f2 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h index 4e6df90dd..a0e699451 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.h +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8316d8901..2dc9cf4fb 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index 101a6ebf8..c2fa739de 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -1,4 +1,4 @@ -// Ryzom Core Studio - Georges Editor Plugin +// Ryzom Core Studio - GUI Editor Plugin // // Copyright (C) 2014 Laszlo Kis-Adam // Copyright (C) 2010 Ryzom Core From bf12cbc53c9b69acaf866cb35f2ae6784c368092 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 16:01:23 +0200 Subject: [PATCH 139/240] Links shouldn't be selectable. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_link.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp index f946c10f2..54c7734b0 100644 --- a/code/studio/src/plugins/gui_editor/expression_link.cpp +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -26,8 +26,6 @@ QGraphicsLineItem( parent ) { m_from = NULL; m_to = NULL; - - setFlags( QGraphicsItem::ItemIsSelectable ); } ExpressionLink::~ExpressionLink() From 315e43a46923aff53a0d784b1e540449aa9cc5c5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 16:02:28 +0200 Subject: [PATCH 140/240] ExpressionNode flags are now set in it's constructor. --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_editor.cpp | 1 - code/studio/src/plugins/gui_editor/expression_node.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 32eefbf08..4aba6c4a5 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -239,7 +239,6 @@ void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) m_nodeCount++; ExpressionNode *node = new ExpressionNode( n, info->slotNames.count() ); - node->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); node->setSlotNames( info->slotNames ); node->setVariable( info->variable ); node->setIsValue( info->value ); diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 2dc9cf4fb..8f3425a37 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -101,6 +101,8 @@ private: ExpressionNode::ExpressionNode( const QString &name, int slotCount, QGraphicsItem *parent ) : QGraphicsItem( parent ) { + setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + m_w = 100; m_h = 100; m_hh = 20.0; From a9cd53878646dbb8916d1197cff526d3a5ef87a5 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 16:17:41 +0200 Subject: [PATCH 141/240] Instead of mouse move event, use the itemChange handler to move the links. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expression_node.cpp | 16 ++++++++++++---- .../src/plugins/gui_editor/expression_node.h | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8f3425a37..8a0ef774b 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -101,7 +101,7 @@ private: ExpressionNode::ExpressionNode( const QString &name, int slotCount, QGraphicsItem *parent ) : QGraphicsItem( parent ) { - setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ); + setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsScenePositionChanges ); m_w = 100; m_h = 100; @@ -323,7 +323,17 @@ QString ExpressionNode::build() const return result; } -void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) +QVariant ExpressionNode::itemChange( GraphicsItemChange change, const QVariant &value ) +{ + if( change == ItemScenePositionHasChanged ) + { + onNodeMove(); + } + + return QGraphicsItem::itemChange( change, value ); +} + +void ExpressionNode::onNodeMove() { for( int i = 0; i < m_links.count(); i++ ) { @@ -333,8 +343,6 @@ void ExpressionNode::mouseMoveEvent( QGraphicsSceneMouseEvent *e ) link->nodeMoved(); } - - QGraphicsItem::mouseMoveEvent( e ); } void ExpressionNode::createSlots( int count) diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h index c2fa739de..1e0290344 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.h +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -68,9 +68,10 @@ public: QString build() const; protected: - void mouseMoveEvent( QGraphicsSceneMouseEvent *e ); + QVariant itemChange( GraphicsItemChange change, const QVariant &value ); private: + void onNodeMove(); void createSlots( int count = 3 ); void paintSlots( QPainter *painter ); From df98492b1c589a65a237556403cbc19291962bd0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 19:19:43 +0200 Subject: [PATCH 142/240] Moved the Expression Editor to it's right place. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/expression_editor.cpp | 9 +++- .../plugins/gui_editor/expression_editor.h | 4 ++ .../plugins/gui_editor/expression_editor.ui | 3 ++ .../plugins/gui_editor/gui_editor_window.cpp | 15 ------ .../plugins/gui_editor/gui_editor_window.h | 4 -- .../src/plugins/gui_editor/link_editor.cpp | 48 +++++++++++++++++++ .../src/plugins/gui_editor/link_editor.h | 8 +++- .../src/plugins/gui_editor/link_editor.ui | 3 ++ 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 4aba6c4a5..5be3939fd 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -140,6 +140,13 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) menu.exec( e->globalPos() ); } +void ExpressionEditor::closeEvent( QCloseEvent *e ) +{ + QMainWindow::closeEvent( e ); + + Q_EMIT closing(); +} + void ExpressionEditor::onDeleteSelection() { QList< QGraphicsItem* > l = m_scene->selectedItems(); @@ -324,7 +331,7 @@ void ExpressionEditor::onSave() m_result = m_pvt->m_root->build(); } - hide(); + close(); } diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index 9f7bd6101..ce13ff58e 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -37,8 +37,12 @@ public: void load(); QString result() const{ return m_result; } +Q_SIGNALS: + void closing(); + protected: void contextMenuEvent( QContextMenuEvent *e ); + void closeEvent( QCloseEvent *e ); private Q_SLOTS: void onDeleteSelection(); diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui index 342b2b5f1..fa21420a2 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.ui +++ b/code/studio/src/plugins/gui_editor/expression_editor.ui @@ -2,6 +2,9 @@ ExpressionEditor + + Qt::ApplicationModal + 0 diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 2447ac0af..3f4e318db 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -46,8 +46,6 @@ #include "add_widget_widget.h" #include "texture_chooser.h" -#include "expression_editor.h" - namespace GUIEditor { QString _lastDir; @@ -74,8 +72,6 @@ namespace GUIEditor widgetInfoTree = new CWidgetInfoTree; tc = new TextureChooser(); - ee = new ExpressionEditor(); - ee->load(); createMenus(); readSettings(); @@ -124,8 +120,6 @@ namespace GUIEditor delete tc; tc = NULL; - delete ee; - ee = NULL; delete messageProcessor; messageProcessor = NULL; @@ -371,11 +365,6 @@ namespace GUIEditor tc->exec(); } - void GUIEditorWindow::onEEClicked() - { - ee->show(); - } - void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); @@ -426,10 +415,6 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTCClicked() ) ); m->addAction( a ); - a = new QAction( "Expression Editor", this ); - connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onEEClicked() ) ); - m->addAction( a ); - menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index d0dbe628e..978a8df72 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -29,7 +29,6 @@ class QtTreePropertyBrowser; class QMenu; class TextureChooser; -class ExpressionEditor; namespace GUIEditor { @@ -69,8 +68,6 @@ private Q_SLOTS: void onAddWidgetClicked(); void onTreeChanged(); void onTCClicked(); - void onEEClicked(); - protected: void hideEvent( QHideEvent *evnt ); @@ -105,7 +102,6 @@ private: QMenu *menu; TextureChooser *tc; - ExpressionEditor *ee; }; } diff --git a/code/studio/src/plugins/gui_editor/link_editor.cpp b/code/studio/src/plugins/gui_editor/link_editor.cpp index c57a6cd09..3cb49f37a 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.cpp +++ b/code/studio/src/plugins/gui_editor/link_editor.cpp @@ -18,20 +18,49 @@ #include "link_editor.h" #include "nel/gui/interface_group.h" #include "nel/gui/widget_manager.h" +#include "expression_editor.h" +#include namespace GUIEditor { + class LinkEditorPvt + { + public: + + LinkEditorPvt() + { + ee = new ExpressionEditor(); + ee->load(); + } + + ~LinkEditorPvt() + { + delete ee; + ee = NULL; + } + + ExpressionEditor *ee; + }; + + LinkEditor::LinkEditor( QWidget *parent ) : QWidget( parent ) { setupUi( this ); setup(); + + m_pvt = new LinkEditorPvt(); + connect( okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKButtonClicked() ) ); connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( hide() ) ); + connect( expressionEdit, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( onTextEditContextMenu( const QPoint& ) ) ); + connect( m_pvt->ee, SIGNAL( closing() ), this, SLOT( onEEClosing() ) ); } LinkEditor::~LinkEditor() { + delete m_pvt; + m_pvt = NULL; } void LinkEditor::setup() @@ -89,4 +118,23 @@ namespace GUIEditor hide(); } + + void LinkEditor::onTextEditContextMenu( const QPoint &pos ) + { + QMenu *menu = expressionEdit->createStandardContextMenu(); + QAction *a = menu->addAction( "Expression Editor" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onEE() ) ); + + menu->exec( mapToGlobal( pos ) ); + } + + void LinkEditor::onEE() + { + m_pvt->ee->show(); + } + + void LinkEditor::onEEClosing() + { + expressionEdit->setPlainText( m_pvt->ee->result() ); + } } diff --git a/code/studio/src/plugins/gui_editor/link_editor.h b/code/studio/src/plugins/gui_editor/link_editor.h index b70019d20..f5617982e 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.h +++ b/code/studio/src/plugins/gui_editor/link_editor.h @@ -23,6 +23,8 @@ namespace GUIEditor { + class LinkEditorPvt; + class LinkEditor : public QWidget, public Ui::LinkEditor { Q_OBJECT @@ -35,12 +37,16 @@ namespace GUIEditor Q_SIGNALS: void okClicked(); - + private Q_SLOTS: void onOKButtonClicked(); + void onTextEditContextMenu( const QPoint &pos ); + void onEE(); + void onEEClosing(); private: uint32 currentLinkId; + LinkEditorPvt *m_pvt; }; } diff --git a/code/studio/src/plugins/gui_editor/link_editor.ui b/code/studio/src/plugins/gui_editor/link_editor.ui index 13a6e7d7e..657b0eabc 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.ui +++ b/code/studio/src/plugins/gui_editor/link_editor.ui @@ -26,6 +26,9 @@ + + Qt::CustomContextMenu + From e77fed3c3d97eb33e45a2a34c1f11a6db6d0cfcd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 19:21:39 +0200 Subject: [PATCH 143/240] Texture Chooser shouldn't have been left in the main menu... --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/gui_editor_window.cpp | 16 ---------------- .../src/plugins/gui_editor/gui_editor_window.h | 6 ------ 2 files changed, 22 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 3f4e318db..9f6568936 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -44,7 +44,6 @@ #include "editor_selection_watcher.h" #include "editor_message_processor.h" #include "add_widget_widget.h" -#include "texture_chooser.h" namespace GUIEditor { @@ -71,8 +70,6 @@ namespace GUIEditor widgetInfoTree = new CWidgetInfoTree; - tc = new TextureChooser(); - createMenus(); readSettings(); @@ -118,9 +115,6 @@ namespace GUIEditor removeMenus(); - delete tc; - tc = NULL; - delete messageProcessor; messageProcessor = NULL; @@ -359,12 +353,6 @@ namespace GUIEditor GUICtrl->show(); } - void GUIEditorWindow::onTCClicked() - { - tc->load(); - tc->exec(); - } - void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); @@ -411,10 +399,6 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); - a = new QAction( "Texture Chooser", this ); - connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTCClicked() ) ); - m->addAction( a ); - menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index 978a8df72..cc2dfbc65 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -25,11 +25,8 @@ #include "property_browser_ctrl.h" class QtTreePropertyBrowser; - class QMenu; -class TextureChooser; - namespace GUIEditor { @@ -67,7 +64,6 @@ private Q_SLOTS: void onGUILoaded(); void onAddWidgetClicked(); void onTreeChanged(); - void onTCClicked(); protected: void hideEvent( QHideEvent *evnt ); @@ -100,8 +96,6 @@ private: QString currentProjectFile; QMenu *menu; - - TextureChooser *tc; }; } From 405954783576c56afcf98f3506f676cdced2fd92 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 19:27:06 +0200 Subject: [PATCH 144/240] Added support for clearing the Expression Editor scene. --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/expression_editor.cpp | 12 ++++++++++++ .../src/plugins/gui_editor/expression_editor.h | 1 + 2 files changed, 13 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 5be3939fd..392bdca41 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -135,6 +135,9 @@ void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) a = menu.addAction( "Save" ); connect( a, SIGNAL( triggered() ), this, SLOT( onSave() ) ); + + a = menu.addAction( "Clear" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onClear() ) ); } menu.exec( e->globalPos() ); @@ -334,6 +337,15 @@ void ExpressionEditor::onSave() close(); } +void ExpressionEditor::onClear() +{ + m_scene->clear(); + m_pvt->m_root = NULL; + m_nodeCount = 0; + m_selectionCount = 0; + m_result = ""; +} + void ExpressionEditor::addExpression( const ExpressionInfo *info ) { diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h index ce13ff58e..92cc959bd 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.h +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -55,6 +55,7 @@ private Q_SLOTS: void onSetRoot(); void onBuildExpression(); void onSave(); + void onClear(); private: void addExpression( const ExpressionInfo *info ); From 0c354f436dc5216bbad8aec286639ef197593937 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 20:49:26 +0200 Subject: [PATCH 145/240] Added the rest of the expression files. --HG-- branch : dfighter-tools --- .../studio/src/plugins/gui_editor/expressions/abs.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/band.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/bnot.xml | 8 ++++++++ .../studio/src/plugins/gui_editor/expressions/bor.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/bxor.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/dbcount.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/depends.xml | 8 ++++++++ .../plugins/gui_editor/expressions/extSign11To64.xml | 8 ++++++++ .../plugins/gui_editor/expressions/extSign8To64.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getAlpha.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getBlue.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getGreen.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getRed.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/getbit.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/getprop.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/identity.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/ilinear.xml | 10 ++++++++++ .../studio/src/plugins/gui_editor/expressions/int.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/intToColor.xml | 8 ++++++++ .../plugins/gui_editor/expressions/isFinalVersion.xml | 5 +++++ .../src/plugins/gui_editor/expressions/localize.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/makeRGB.xml | 11 +++++++++++ .../studio/src/plugins/gui_editor/expressions/max.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/min.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/mod.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/oldvalue.xml | 8 ++++++++ .../src/plugins/gui_editor/expressions/rand.xml | 5 +++++ .../studio/src/plugins/gui_editor/expressions/sal.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/sar.xml | 9 +++++++++ .../gui_editor/expressions/secondsToTimeString.xml | 8 ++++++++ .../expressions/secondsToTimeStringShort.xml | 8 ++++++++ .../studio/src/plugins/gui_editor/expressions/shl.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/shr.xml | 9 +++++++++ .../studio/src/plugins/gui_editor/expressions/str.xml | 9 +++++++++ .../src/plugins/gui_editor/expressions/switch.xml | 10 ++++++++++ 35 files changed, 293 insertions(+) create mode 100644 code/studio/src/plugins/gui_editor/expressions/abs.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/band.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bnot.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/bxor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/dbcount.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/depends.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getAlpha.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getBlue.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getGreen.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getRed.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getbit.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/getprop.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/identity.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/ilinear.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/int.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/intToColor.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/localize.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/makeRGB.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/max.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/min.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/mod.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/oldvalue.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/rand.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/sal.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/sar.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/shl.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/shr.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/str.xml create mode 100644 code/studio/src/plugins/gui_editor/expressions/switch.xml diff --git a/code/studio/src/plugins/gui_editor/expressions/abs.xml b/code/studio/src/plugins/gui_editor/expressions/abs.xml new file mode 100644 index 000000000..5a5fe2c70 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/abs.xml @@ -0,0 +1,8 @@ + +Mathematical +abs +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/band.xml b/code/studio/src/plugins/gui_editor/expressions/band.xml new file mode 100644 index 000000000..1ce1534ec --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/band.xml @@ -0,0 +1,9 @@ + +Bits +band +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bnot.xml b/code/studio/src/plugins/gui_editor/expressions/bnot.xml new file mode 100644 index 000000000..bde93f6e7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bnot.xml @@ -0,0 +1,8 @@ + +Bits +bnot +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bor.xml b/code/studio/src/plugins/gui_editor/expressions/bor.xml new file mode 100644 index 000000000..906678bc2 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bor.xml @@ -0,0 +1,9 @@ + +Bits +bor +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/bxor.xml b/code/studio/src/plugins/gui_editor/expressions/bxor.xml new file mode 100644 index 000000000..2bfedb167 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/bxor.xml @@ -0,0 +1,9 @@ + +Bits +bxor +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/dbcount.xml b/code/studio/src/plugins/gui_editor/expressions/dbcount.xml new file mode 100644 index 000000000..df8e0aac6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/dbcount.xml @@ -0,0 +1,8 @@ + +Database +dbcount +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/depends.xml b/code/studio/src/plugins/gui_editor/expressions/depends.xml new file mode 100644 index 000000000..225d48dd6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/depends.xml @@ -0,0 +1,8 @@ + +Logical +depends +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml b/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml new file mode 100644 index 000000000..e227fc8cb --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/extSign11To64.xml @@ -0,0 +1,8 @@ + +Bits +extSign11To64 +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml b/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml new file mode 100644 index 000000000..f029c15fc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/extSign8To64.xml @@ -0,0 +1,8 @@ + +Bits +extSign8To64 +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml b/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml new file mode 100644 index 000000000..acdc5e322 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getAlpha.xml @@ -0,0 +1,8 @@ + +Color +getAlpha +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getBlue.xml b/code/studio/src/plugins/gui_editor/expressions/getBlue.xml new file mode 100644 index 000000000..be35a6c17 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getBlue.xml @@ -0,0 +1,8 @@ + +Color +getBlue +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getGreen.xml b/code/studio/src/plugins/gui_editor/expressions/getGreen.xml new file mode 100644 index 000000000..da8e16bc4 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getGreen.xml @@ -0,0 +1,8 @@ + +Color +getGreen +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getRed.xml b/code/studio/src/plugins/gui_editor/expressions/getRed.xml new file mode 100644 index 000000000..3a918857b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getRed.xml @@ -0,0 +1,8 @@ + +Color +getRed +false + +Color + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getbit.xml b/code/studio/src/plugins/gui_editor/expressions/getbit.xml new file mode 100644 index 000000000..6cc08e10b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getbit.xml @@ -0,0 +1,9 @@ + +Bits +getbit +false + +Integer +Bit + + diff --git a/code/studio/src/plugins/gui_editor/expressions/getprop.xml b/code/studio/src/plugins/gui_editor/expressions/getprop.xml new file mode 100644 index 000000000..1098635aa --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/getprop.xml @@ -0,0 +1,8 @@ + +Database +getprop +false + +property + + diff --git a/code/studio/src/plugins/gui_editor/expressions/identity.xml b/code/studio/src/plugins/gui_editor/expressions/identity.xml new file mode 100644 index 000000000..cd36facd6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/identity.xml @@ -0,0 +1,8 @@ + +Mathematical +identity +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ilinear.xml b/code/studio/src/plugins/gui_editor/expressions/ilinear.xml new file mode 100644 index 000000000..9284b4e82 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ilinear.xml @@ -0,0 +1,10 @@ + +Mathematical +ilinear +false + +Interpolant +Start +End + + diff --git a/code/studio/src/plugins/gui_editor/expressions/int.xml b/code/studio/src/plugins/gui_editor/expressions/int.xml new file mode 100644 index 000000000..117225b6b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/int.xml @@ -0,0 +1,8 @@ + +Mathematical +int +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/intToColor.xml b/code/studio/src/plugins/gui_editor/expressions/intToColor.xml new file mode 100644 index 000000000..2993365d7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/intToColor.xml @@ -0,0 +1,8 @@ + +Color +intToColor +false + +Integer + + diff --git a/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml b/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml new file mode 100644 index 000000000..3c9ddc64c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/isFinalVersion.xml @@ -0,0 +1,5 @@ + +Nel +isFinalVersion +false + diff --git a/code/studio/src/plugins/gui_editor/expressions/localize.xml b/code/studio/src/plugins/gui_editor/expressions/localize.xml new file mode 100644 index 000000000..f8d3f0f4e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/localize.xml @@ -0,0 +1,8 @@ + +Localization +localize +false + +String + + diff --git a/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml b/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml new file mode 100644 index 000000000..a2cb2d352 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/makeRGB.xml @@ -0,0 +1,11 @@ + +Color +makeRGB +false + +R +G +B +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/max.xml b/code/studio/src/plugins/gui_editor/expressions/max.xml new file mode 100644 index 000000000..6592aecd7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/max.xml @@ -0,0 +1,9 @@ + +Mathematical +max +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/min.xml b/code/studio/src/plugins/gui_editor/expressions/min.xml new file mode 100644 index 000000000..753955ed9 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/min.xml @@ -0,0 +1,9 @@ + +Mathematical +min +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/mod.xml b/code/studio/src/plugins/gui_editor/expressions/mod.xml new file mode 100644 index 000000000..d306f3371 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/mod.xml @@ -0,0 +1,9 @@ + +Mathematical +mod +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml b/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml new file mode 100644 index 000000000..299706c79 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/oldvalue.xml @@ -0,0 +1,8 @@ + +Database +oldvalue +false + +property + + diff --git a/code/studio/src/plugins/gui_editor/expressions/rand.xml b/code/studio/src/plugins/gui_editor/expressions/rand.xml new file mode 100644 index 000000000..b284dc241 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/rand.xml @@ -0,0 +1,5 @@ + +Mathematical +rand +false + diff --git a/code/studio/src/plugins/gui_editor/expressions/sal.xml b/code/studio/src/plugins/gui_editor/expressions/sal.xml new file mode 100644 index 000000000..3190f4420 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sal.xml @@ -0,0 +1,9 @@ + +Bits +sal +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/sar.xml b/code/studio/src/plugins/gui_editor/expressions/sar.xml new file mode 100644 index 000000000..75fcd57d7 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sar.xml @@ -0,0 +1,9 @@ + +Bits +sar +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml new file mode 100644 index 000000000..fda7dd1c8 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeString.xml @@ -0,0 +1,8 @@ + +Time +secondsToTimeString +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml new file mode 100644 index 000000000..042cf06de --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/secondsToTimeStringShort.xml @@ -0,0 +1,8 @@ + +Time +secondsToTimeStringShort +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/shl.xml b/code/studio/src/plugins/gui_editor/expressions/shl.xml new file mode 100644 index 000000000..653a142a6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/shl.xml @@ -0,0 +1,9 @@ + +Bits +shl +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/shr.xml b/code/studio/src/plugins/gui_editor/expressions/shr.xml new file mode 100644 index 000000000..435816f6e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/shr.xml @@ -0,0 +1,9 @@ + +Bits +shr +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/str.xml b/code/studio/src/plugins/gui_editor/expressions/str.xml new file mode 100644 index 000000000..c98ae89eb --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/str.xml @@ -0,0 +1,9 @@ + +String +str +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/switch.xml b/code/studio/src/plugins/gui_editor/expressions/switch.xml new file mode 100644 index 000000000..19f94f9d3 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/switch.xml @@ -0,0 +1,10 @@ + +Logical +switch +true + +A +B +C + + From 4d760c751586bbe57bb4f3017ea38ef810e3b3b9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 20:51:45 +0200 Subject: [PATCH 146/240] When removing the root node, don't retain the pointer to it... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_editor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp index 392bdca41..858c63c9c 100644 --- a/code/studio/src/plugins/gui_editor/expression_editor.cpp +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -176,6 +176,9 @@ void ExpressionEditor::onDeleteSelection() } } + if( item == m_pvt->m_root ) + m_pvt->m_root = NULL; + m_scene->removeItem( item ); delete item; } From 012fae0ef687f7f96840d6ed4ec2f334b035c861 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 20:54:16 +0200 Subject: [PATCH 147/240] don't evaluate the child-nodes when there are none, directly just return () --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/expression_node.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp index 8a0ef774b..80ef571e2 100644 --- a/code/studio/src/plugins/gui_editor/expression_node.cpp +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -297,9 +297,16 @@ QString ExpressionNode::build() const QStringList l = m_name.split( ' ' ); result = l[ 0 ]; - result += "( "; int c = m_links.count(); + if( c == 1 ) + { + result += "()"; + return result; + } + + result += "( "; + for( int i = 1; i < c; i++ ) { ExpressionLink *link = m_links[ i ]; From 780394f989c129688570c2d83495c5485ac90102 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 17 Sep 2014 22:36:58 +0200 Subject: [PATCH 148/240] Fixed Object Viewer build. --HG-- branch : dfighter-tools --- code/studio/src/plugins/object_viewer/object_viewer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/object_viewer/object_viewer.cpp b/code/studio/src/plugins/object_viewer/object_viewer.cpp index 566869e84..240a0d9e9 100644 --- a/code/studio/src/plugins/object_viewer/object_viewer.cpp +++ b/code/studio/src/plugins/object_viewer/object_viewer.cpp @@ -120,7 +120,7 @@ void CObjectViewer::init( NL3D::UDriver *driver ) NL3D::CBloomEffect::instance().setDriver(_Driver); NL3D::CBloomEffect::instance().setScene(_Scene); - NL3D::CBloomEffect::instance().init(!_Direct3D); + NL3D::CBloomEffect::instance().init(); NL3D::CBloomEffect::instance().setDensityBloom(uint8(_BloomDensity)); NL3D::CBloomEffect::instance().setSquareBloom(_BloomSquare); @@ -172,7 +172,7 @@ void CObjectViewer::renderDriver() // Render the scene. if((NL3D::CBloomEffect::instance().getDriver() != 0) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().initBloom(); + NL3D::CBloomEffect::instance().init(); } _Driver->clearBuffers(_BackgroundColor); } @@ -184,8 +184,7 @@ void CObjectViewer::renderScene() if((NL3D::CBloomEffect::instance().getDriver() != 0) && (_BloomEffect)) { - NL3D::CBloomEffect::instance().endBloom(); - NL3D::CBloomEffect::instance().endInterfacesDisplayBloom(); + NL3D::CBloomEffect::instance().applyBloom(); } } From c1b8ea9bd013d1044bfcbc77f849e58a8170f1e5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 11:31:19 +0200 Subject: [PATCH 149/240] Backed out incomplete changes to GL driver --HG-- branch : develop --- .../src/3d/driver/opengl/driver_opengl.cpp | 4 - code/nel/src/3d/driver/opengl/driver_opengl.h | 6 - .../3d/driver/opengl/driver_opengl_window.cpp | 141 ++---------------- 3 files changed, 14 insertions(+), 137 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index e9965e0f1..ce60d7f42 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -234,10 +234,6 @@ CDriverGL::CDriverGL() _CursorScale = 1.f; _MouseCaptured = false; -#if defined(NL_OS_WINDOWS) - _BorderlessFullscreen = false; -#endif - _NeedToRestaureGammaRamp = false; _win = EmptyWindow; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index fb6069447..c4540b9da 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -996,12 +996,6 @@ private: EWindowStyle getWindowStyle() const; bool setWindowStyle(EWindowStyle windowStyle); -#if defined(NL_OS_WINDOWS) - static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData); - bool _BorderlessFullscreen; -#endif - std::string _CurrentDisplayDevice; - // Methods to manage screen resolutions bool restoreScreenMode(); bool saveScreenMode(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 4e08884b0..751e72149 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1271,86 +1271,10 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info) // *************************************************************************** -#if defined(NL_OS_WINDOWS) - -struct CMonitorEnumParams -{ -public: - CDriverGL *Driver; - const char *DeviceName; - bool Success; -}; - -BOOL CALLBACK CDriverGL::monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - CMonitorEnumParams *p = reinterpret_cast(dwData); - - MONITORINFOEXA monitorInfo; - memset(&monitorInfo, 0, sizeof(monitorInfo)); - monitorInfo.cbSize = sizeof(monitorInfo); - GetMonitorInfoA(hMonitor, &monitorInfo); - nldebug("3D: Monitor: '%s'", monitorInfo.szDevice); - - size_t devLen = strlen(monitorInfo.szDevice); - size_t targetLen = strlen(p->DeviceName); - - nlassert(devLen < 32); - size_t minLen = min(devLen, targetLen); - if (!memcmp(monitorInfo.szDevice, p->DeviceName, minLen)) - { - if (devLen == targetLen - || (devLen < targetLen && (p->DeviceName[minLen] == '\\')) - || (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\'))) - { - nldebug("3D: Remapping '%s' to '%s'", p->DeviceName, monitorInfo.szDevice); - nldebug("3D: Found requested monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); - p->Driver->_CurrentMode.Windowed = false; - p->Driver->setWindowStyle(CDriverGL::EWSWindowed); - p->Driver->setWindowSize(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top); - LONG dwStyle = GetWindowLong(p->Driver->_win, GWL_STYLE); - SetWindowLong(p->Driver->_win, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); - SetWindowPos(p->Driver->_win, NULL, - monitorInfo.rcMonitor.left, - monitorInfo.rcMonitor.top, - monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, - monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, - SWP_FRAMECHANGED); - p->Driver->_WindowX = monitorInfo.rcMonitor.left; - p->Driver->_WindowY = monitorInfo.rcMonitor.top; - p->Driver->_CurrentDisplayDevice = std::string(p->DeviceName); - p->Driver->_BorderlessFullscreen = true; - p->Driver->_CurrentMode.Windowed = false; - p->Success = true; - return FALSE; - } - } - p->Success = false; - return TRUE; // continue -}; - -#endif - -// *************************************************************************** - bool CDriverGL::setScreenMode(const GfxMode &mode) { H_AUTO_OGL(CDriverGL_setScreenMode) - nldebug("3D: setScreenMode"); - -#if defined(NL_OS_WINDOWS) - if (_BorderlessFullscreen) - { - _BorderlessFullscreen = false; - LONG dwStyle = GetWindowLong(_win, GWL_STYLE); - dwStyle |= WS_OVERLAPPEDWINDOW; - if (!_Resizable) dwStyle ^= WS_MAXIMIZEBOX|WS_THICKFRAME; - SetWindowLong(_win, GWL_STYLE, dwStyle); - SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - _CurrentMode.Windowed = true; - } -#endif - if (mode.Windowed) { // if fullscreen, switch back to desktop screen mode @@ -1360,17 +1284,13 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) return true; } - if (_CurrentDisplayDevice != mode.DisplayDevice) - restoreScreenMode(); - // save previous screen mode only if switching from windowed to fullscreen if (_CurrentMode.Windowed) saveScreenMode(); // if switching exactly to the same screen mode, doesn't change it GfxMode previousMode; - if (_CurrentDisplayDevice == mode.DisplayDevice - && getCurrentScreenMode(previousMode) + if (getCurrentScreenMode(previousMode) && mode.Width == previousMode.Width && mode.Height == previousMode.Height && mode.Depth == previousMode.Depth @@ -1379,9 +1299,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) #if defined(NL_OS_WINDOWS) - const char *deviceName = mode.DisplayDevice.c_str(); - - DEVMODEA devMode; + DEVMODE devMode; memset(&devMode, 0, sizeof(DEVMODE)); devMode.dmSize = sizeof(DEVMODE); devMode.dmDriverExtra = 0; @@ -1389,42 +1307,22 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) devMode.dmPelsWidth = mode.Width; devMode.dmPelsHeight = mode.Height; - if (mode.Depth > 0) + if(mode.Depth > 0) { devMode.dmBitsPerPel = mode.Depth; devMode.dmFields |= DM_BITSPERPEL; } - if (mode.Frequency > 0) + if(mode.Frequency > 0) { devMode.dmDisplayFrequency = mode.Frequency; devMode.dmFields |= DM_DISPLAYFREQUENCY; } - - if (deviceName[0]) - { - // First attempt exclusive fullscreen - nldebug("3D: ChangeDisplaySettingsEx"); - LONG resex; - if ((resex = ChangeDisplaySettingsExA(deviceName, &devMode, NULL, CDS_FULLSCREEN, NULL)) != DISP_CHANGE_SUCCESSFUL) - { - nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex); - // Workaround, resize to monitor and make borderless - CMonitorEnumParams p; - p.DeviceName = deviceName; - p.Driver = this; - EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p); - return p.Success; - } - } - else + + if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { - nldebug("3D: ChangeDisplaySettings"); - if (ChangeDisplaySettingsA(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) - { - nlwarning("3D: Fullscreen mode switch failed"); - return false; - } + nlwarning("3D: Fullscreen mode switch failed"); + return false; } #elif defined(NL_OS_MAC) @@ -1830,11 +1728,7 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) dwNewStyle |= WS_VISIBLE; if (dwStyle != dwNewStyle) - { SetWindowLong(_win, GWL_STYLE, dwNewStyle); - if (windowStyle == EWSWindowed) - SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - } // if (windowStyle == EWSMaximized && isVisible && !isMaximized) // ShowWindow(_hWnd, SW_SHOWMAXIMIZED); @@ -1962,24 +1856,19 @@ bool CDriverGL::setMode(const GfxMode& mode) && ScreenToClient(_win, &cursorPos); sint curX = (sint)cursorPos.x * (sint)mode.Width; sint curY = (sint)cursorPos.y * (sint)mode.Height; - if (_BorderlessFullscreen) - ReleaseCapture(); #endif if (!setScreenMode(mode)) return false; - if (!_BorderlessFullscreen) - { - // when changing window style, it's possible system change window size too - setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); + // when changing window style, it's possible system change window size too + setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); - if (!mode.Windowed) - _CurrentMode.Depth = mode.Depth; + if (!mode.Windowed) + _CurrentMode.Depth = mode.Depth; - setWindowSize(mode.Width, mode.Height); - setWindowPos(_WindowX, _WindowY); - } + setWindowSize(mode.Width, mode.Height); + setWindowPos(_WindowX, _WindowY); switch (_CurrentMode.Depth) { @@ -1996,8 +1885,6 @@ bool CDriverGL::setMode(const GfxMode& mode) cursorPos.y = curY / (sint)mode.Height; ClientToScreen(_win, &cursorPos); SetCursorPos(cursorPos.x, cursorPos.y); - if (_BorderlessFullscreen) - SetCapture(_win); } #endif From 027860be16f8de33d900f3ddcf3f5e3dff91aee9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 13:02:32 +0200 Subject: [PATCH 150/240] Fix missing include --HG-- branch : develop --- code/ryzom/client/src/release.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 4e712a10d..f88849197 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -27,6 +27,7 @@ #include "nel/misc/system_utils.h" // 3D Interface. #include "nel/3d/bloom_effect.h" +#include "nel/3d/fxaa.h" #include "nel/3d/fasthls_modifier.h" #include "nel/3d/particle_system_manager.h" #include "nel/3d/particle_system.h" @@ -661,7 +662,7 @@ void release() delete &CLuaManager::getInstance(); NLGUI::CDBManager::release(); CWidgetManager::release(); - + From 5e9c3b82fca48966ed0e0899066cdbe83a9a9147 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 14:10:03 +0200 Subject: [PATCH 151/240] Add particle system path fixing script --HG-- branch : develop --- .../scripts/nel_assets_ps_batched.ms | 378 ++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms new file mode 100644 index 000000000..f8165e25e --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms @@ -0,0 +1,378 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +fn findFile dir fileName = +( + if (doesFileExist (dir + "\\" + fileName)) then + ( + return (dir + "\\" + fileName) + ) + + dirArr = GetDirectories (dir + "\\*") + + for d in dirArr do + ( + local fileFound = findFile d fileName + if (fileFound != "") then + return fileFound + ) + + return "" +) + +fn getFixedPath ps = +( + if not (doesFileExist ps) then + ( + local fileName = filenameFromPath ps + local fileFound = findFile "W:\\database\\sfx" fileName + if (fileFound != "") then + return fileFound + else + return fileName + ) + else + ( + return ps + ) +) + +fn renameParticleSystem ps = +( + local newFileName = getFixedPath ps.ps_file_name + if (newFileName != ps.ps_file_name) then + ( + ps.ps_file_name = newFileName + return 1 + ) + else + ( + return 0 + ) +) + + +rollout assets_ps_rollout "Properties" +( + fn do_it = + ( + local result = 0 + + for m in getClassInstances nel_ps do + ( + if (renameParticleSystem m) == 1 then + result = 1 + ) + + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return result + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Open the max project + if loadMaxFile file quiet:true == true then + ( + objXRefMgr.UpdateAllRecords() + + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_ps_floater = newRolloutFloater "NeL Assets PS Database" 550 400 +addrollout assets_ps_rollout assets_ps_floater rolledUp:false + + From 902a873e78126c9ce0681ecefe2d02eb915c96d3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 17:40:07 +0200 Subject: [PATCH 152/240] Add resave scripts --HG-- branch : develop --- .../plugin_max/scripts/nel_assets_resave.ms | 329 ++++++++++++++++++ .../scripts/nel_assets_resave_hard.ms | 316 +++++++++++++++++ 2 files changed, 645 insertions(+) create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms new file mode 100644 index 000000000..ab9e45325 --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms @@ -0,0 +1,329 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +rollout assets_resave_rollout "Properties" +( + fn do_it = + ( + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return 1 + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Open the max project + if loadMaxFile file quiet:true == true then + ( + origAnimStart = animationRange.start + origAnimEnd = animationRange.end + origFrameRate = frameRate + + resetMAXFile #noprompt + + animationRange = interval origAnimStart origAnimEnd + frameRate = origFrameRate + + -- Merge the max project + if mergeMaxFile file quiet:true == true then + ( + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_resave_floater = newRolloutFloater "NeL Assets Resave Database" 550 874 +addrollout assets_resave_rollout assets_resave_floater rolledUp:false + diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms new file mode 100644 index 000000000..05220c7a5 --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms @@ -0,0 +1,316 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +rollout assets_resave_rollout "Properties" +( + fn do_it = + ( + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return 1 + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Merge the max project + if mergeMaxFile file quiet:true == true then + ( + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_resave_floater = newRolloutFloater "NeL Assets Resave Database Hard" 550 874 +addrollout assets_resave_rollout assets_resave_floater rolledUp:false + From 0275d0fe2974e3265786bde3e13e9bdf317e31c2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 21:02:14 +0200 Subject: [PATCH 153/240] It works on my machine --HG-- branch : develop --- code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp index 5cb7c6922..a15f8c6d3 100644 --- a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp +++ b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp @@ -27,7 +27,7 @@ #include "nel/misc/file.h" // Game share -#include "server_share/bmp4image.h" +#include "game_share/bmp4image.h" // AI share #include "ai_share/world_map.h" From 0ed6e8111bbc136b9879e97ddb91ed17490f2ec1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 18 Sep 2014 21:55:34 +0200 Subject: [PATCH 154/240] Increment web version --HG-- branch : sha512-auth --- code/web/public_php/setup/version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/public_php/setup/version.php b/code/web/public_php/setup/version.php index 3204d1e7b..476c514f0 100644 --- a/code/web/public_php/setup/version.php +++ b/code/web/public_php/setup/version.php @@ -1,6 +1,6 @@ Date: Fri, 19 Sep 2014 19:48:17 +0200 Subject: [PATCH 155/240] Add extra search paths --HG-- branch : develop --- code/nel/tools/build_gamedata/processes/clodbank/0_setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py b/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py index 532113523..a4ab0f4df 100755 --- a/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py +++ b/code/nel/tools/build_gamedata/processes/clodbank/0_setup.py @@ -74,6 +74,8 @@ cfgOut.write("{\n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ClodExportDirectory + "\", \n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + SkelExportDirectory + "\", \n") cfgOut.write("\t\"" + ExportBuildDirectory + "/" + AnimBuildDirectory + "\", \n") +cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ShapeOptimizedBuildDirectory + "\", \n") +cfgOut.write("\t\"" + ExportBuildDirectory + "/" + ShapeWithCoarseMeshBuildDirectory + "\", \n") cfgOut.write("};\n") cfgOut.write("\n") cfgOut.close() From 5b7bc8cc549b6996a5893a24316e52fe5229607f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 20 Sep 2014 20:51:08 +0200 Subject: [PATCH 156/240] GUI Editor should no longer crash on Linux --HG-- branch : dfighter-tools --- .../plugins/core/Nel3DWidget/nel3d_widget.cpp | 3 +-- .../src/plugins/core/Nel3DWidget/nel3d_widget.h | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp index dc0bb858b..bc83b5d78 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.cpp @@ -14,7 +14,6 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . - #include "nel3d_widget.h" #include "nel/3d/u_driver.h" #include "nel/3d/text_context.h" @@ -29,7 +28,7 @@ #include Nel3DWidget::Nel3DWidget( QWidget *parent ) : -QWidget( parent ) +NEL3DWIDGET( parent ) { driver = NULL; textContext = NULL; diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h index 059e1b738..afed4cf65 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h @@ -18,10 +18,22 @@ #ifndef NEL3D_WIDGET_H #define NEL3D_WIDGET_H -#include #include "nel/misc/types_nl.h" #include +#ifdef NEL3DWIDGET +#undef NEL3DWIDGET +#endif + +#ifdef NL_OS_WINDOWS +#include +#define NEL3DWIDGET QWidget +#else +#include +#define NEL3DWIDGET QGLWidget +#endif + + #include "../core_global.h" namespace NL3D @@ -31,7 +43,7 @@ namespace NL3D } /// Nel 3D interface to Qt -class CORE_EXPORT Nel3DWidget : public QWidget +class CORE_EXPORT Nel3DWidget : public QGLWidget { Q_OBJECT public: From 648b2cb46b39097bc98997e26f75aa13d4150efd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 20 Sep 2014 20:55:30 +0200 Subject: [PATCH 157/240] oups --HG-- branch : dfighter-tools --- code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h index afed4cf65..254001b25 100644 --- a/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h +++ b/code/studio/src/plugins/core/Nel3DWidget/nel3d_widget.h @@ -43,7 +43,7 @@ namespace NL3D } /// Nel 3D interface to Qt -class CORE_EXPORT Nel3DWidget : public QGLWidget +class CORE_EXPORT Nel3DWidget : public NEL3DWIDGET { Q_OBJECT public: From cec992c4a59d360b66e7b7d3e18b75b6542d6b88 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 21 Sep 2014 12:31:02 +0200 Subject: [PATCH 158/240] Fix double delete --HG-- branch : develop --- .../server/build_world_packed_col/build_world_packed_col.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp index 9bd4f7f3c..f03489196 100644 --- a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp @@ -211,7 +211,7 @@ int main(int argc, char* argv[]) catch(const EStream &) { mustRebuild = true; // damaged file or bad version ? -> force rebuild - delete packedIsland; // remove whatever was serialized + // delete packedIsland; // remove whatever was serialized // NOPE. smart pointer packedIsland = new CPackedWorldHolder; } } From eff07ebbf9b13459b587d84315f81410fdb7641b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 21 Sep 2014 13:24:33 +0200 Subject: [PATCH 159/240] Add an assert --HG-- branch : develop --- .../tools/client/r2_islands_textures/screenshot_islands.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp index 8228c3e2e..4f167ea9c 100644 --- a/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp +++ b/code/ryzom/tools/client/r2_islands_textures/screenshot_islands.cpp @@ -1784,6 +1784,7 @@ void CScreenshotIslands::buildBackTextureHLS(const std::string & islandName, con // keep more filled eighth of circle + nlassert(!sortedHLS.empty()); // If it crashes here, you may be missing .zonel's. itHLS = sortedHLS.begin(); uint h, s, v; RGB2HSV(*itHLS, h, s, v); From f61438d7d966df264f853b6b636b34c9f319de88 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 22 Sep 2014 23:24:48 +0200 Subject: [PATCH 160/240] Studio should no longer crash when multiple plugins that use LIGO are loaded. LIGO classes are now guarded against multiple registrations. If it's tried log messages are generated. Mission Compiler and World Editor will now apply their own LIGO configs when the user switches to their tab. --HG-- branch : dfighter-tools --- code/nel/src/ligo/primitive.cpp | 11 ++++ .../src/plugins/core/context_manager.cpp | 4 +- code/studio/src/plugins/core/icontext.h | 2 + .../mission_compiler_main_window.cpp | 5 ++ .../mission_compiler_main_window.h | 2 + .../mission_compiler_plugin.h | 6 ++ .../world_editor/world_editor_plugin.cpp | 65 ++++++++++--------- .../world_editor/world_editor_plugin.h | 6 +- .../world_editor/world_editor_window.h | 1 + 9 files changed, 69 insertions(+), 33 deletions(-) diff --git a/code/nel/src/ligo/primitive.cpp b/code/nel/src/ligo/primitive.cpp index 9cf7df13f..ba9b69435 100644 --- a/code/nel/src/ligo/primitive.cpp +++ b/code/nel/src/ligo/primitive.cpp @@ -2738,8 +2738,17 @@ CPrimitiveContext::CPrimitiveContext(): } +static bool LIGORegistered = false; + + void Register () { + if( LIGORegistered ) + { + nlinfo( "LIGO classes have already been registered." ); + return; + } + NLMISC_REGISTER_CLASS(CPropertyString); NLMISC_REGISTER_CLASS(CPropertyStringArray); NLMISC_REGISTER_CLASS(CPropertyColor); @@ -2748,6 +2757,8 @@ void Register () NLMISC_REGISTER_CLASS(CPrimPath); NLMISC_REGISTER_CLASS(CPrimZone); NLMISC_REGISTER_CLASS(CPrimAlias); + + LIGORegistered = true; } // *************************************************************************** diff --git a/code/studio/src/plugins/core/context_manager.cpp b/code/studio/src/plugins/core/context_manager.cpp index 3b02b411c..203738faf 100644 --- a/code/studio/src/plugins/core/context_manager.cpp +++ b/code/studio/src/plugins/core/context_manager.cpp @@ -143,6 +143,8 @@ void ContextManager::currentTabChanged(int index) if (index >= 0) { IContext *context = d->m_contexts.at(index); + context->onActivated(); + Q_EMIT currentContextChanged(context); } } @@ -158,4 +160,4 @@ int ContextManager::indexOf(const QString &id) const return -1; } -} /* namespace Core */ \ No newline at end of file +} /* namespace Core */ diff --git a/code/studio/src/plugins/core/icontext.h b/code/studio/src/plugins/core/icontext.h index d2cbb412c..616e0db14 100644 --- a/code/studio/src/plugins/core/icontext.h +++ b/code/studio/src/plugins/core/icontext.h @@ -69,6 +69,8 @@ public: virtual void newDocument(){} virtual void close(){} + + virtual void onActivated(){} }; } // namespace Core diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp index 10985aa38..efadd3949 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.cpp @@ -484,6 +484,11 @@ void MissionCompilerMainWindow::saveConfig() { settings->sync(); } +void MissionCompilerMainWindow::onActivated() +{ + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; +} + void MissionCompilerMainWindow::handleChangedSettings() { QStringList servers; diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h index dc19db1c6..3d59e206a 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_main_window.h @@ -31,6 +31,8 @@ public: void saveConfig(); QUndoStack *getUndoStack() { return m_undoStack; } + void onActivated(); + typedef std::map TMissionContainer; public Q_SLOTS: diff --git a/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h b/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h index 2ad92b40f..cc2cac47c 100644 --- a/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h +++ b/code/studio/src/plugins/mission_compiler/mission_compiler_plugin.h @@ -83,6 +83,12 @@ public: virtual void open() {} + void onActivated() + { + m_missionCompilerMainWindow->onActivated(); + } + + MissionCompilerMainWindow *m_missionCompilerMainWindow; }; diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp index 3170bce60..722c14733 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp @@ -54,36 +54,6 @@ bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManage WorldEditorSettingsPage *weSettings = new WorldEditorSettingsPage(this); addAutoReleasedObject(weSettings); - - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(Constants::WORLD_EDITOR_SECTION); - m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); - m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); - m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt(); - QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString(); - settings->endGroup(); - try - { - // Search path of file world_editor_classes.xml - std::string ligoPath = NLMISC::CPath::lookup(fileName.toUtf8().constData()); - // Init LIGO - m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true); - NLLIGO::Register(); - NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; - } - catch (NLMISC::Exception &e) - { - *errorString = tr("(%1)").arg(e.what()); - return false; - } - - // Reset - m_ligoConfig.resetPrimitiveConfiguration (); - - // TODO: get file names! from settings - m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); - - addAutoReleasedObject(new WorldEditorContext(this)); return true; } @@ -117,6 +87,34 @@ WorldEditorContext::WorldEditorContext(QObject *parent) m_worldEditorWindow(0) { m_worldEditorWindow = new WorldEditorWindow(); + + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Constants::WORLD_EDITOR_SECTION); + m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); + m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); + m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt(); + QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString(); + settings->endGroup(); + try + { + // Search path of file world_editor_classes.xml + std::string ligoPath = NLMISC::CPath::lookup(fileName.toUtf8().constData()); + // Init LIGO + m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true); + NLLIGO::Register(); + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; + } + catch (NLMISC::Exception &e) + { + nlinfo( "Error starting LIGO." ); + } + + // Reset + m_ligoConfig.resetPrimitiveConfiguration (); + + // TODO: get file names! from settings + m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); + } QUndoStack *WorldEditorContext::undoStack() @@ -124,6 +122,11 @@ QUndoStack *WorldEditorContext::undoStack() return m_worldEditorWindow->undoStack(); } +void WorldEditorContext::onActivated() +{ + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig; +} + void WorldEditorContext::open() { m_worldEditorWindow->open(); @@ -136,4 +139,4 @@ QWidget *WorldEditorContext::widget() } -Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin) \ No newline at end of file +Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin) diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.h b/code/studio/src/plugins/world_editor/world_editor_plugin.h index 686b87e14..cfb5448e3 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.h +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.h @@ -59,7 +59,6 @@ protected: NLMISC::CLibraryContext *m_libContext; private: - NLLIGO::CLigoConfig m_ligoConfig; ExtensionSystem::IPluginManager *m_plugMan; QList m_autoReleaseObjects; }; @@ -88,9 +87,14 @@ public: virtual QUndoStack *undoStack(); + void onActivated(); + virtual QWidget *widget(); WorldEditorWindow *m_worldEditorWindow; + +private: + NLLIGO::CLigoConfig m_ligoConfig; }; } // namespace WorldEditor diff --git a/code/studio/src/plugins/world_editor/world_editor_window.h b/code/studio/src/plugins/world_editor/world_editor_window.h index 60a6a988a..9080187f9 100644 --- a/code/studio/src/plugins/world_editor/world_editor_window.h +++ b/code/studio/src/plugins/world_editor/world_editor_window.h @@ -46,6 +46,7 @@ public: ~WorldEditorWindow(); QUndoStack *undoStack() const; + void onActivated(); void maybeSave(); Q_SIGNALS: From e67e9594e1efe4e298c37b62574e4445f0ec693f Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 22 Sep 2014 23:41:55 +0200 Subject: [PATCH 161/240] Call the onActivate method of the current context after all plugins are initialized. --HG-- branch : dfighter-tools --- code/studio/src/plugins/core/main_window.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/core/main_window.cpp b/code/studio/src/plugins/core/main_window.cpp index 4ccd32564..c181376e8 100644 --- a/code/studio/src/plugins/core/main_window.cpp +++ b/code/studio/src/plugins/core/main_window.cpp @@ -108,8 +108,14 @@ void MainWindow::extensionsInitialized() readSettings(); connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext *)), this, SLOT(updateContext(Core::IContext *))); - if (m_contextManager->currentContext() != NULL) - updateContext(m_contextManager->currentContext()); + + Core::IContext *context = m_contextManager->currentContext(); + if (context != NULL) + { + updateContext(context); + context->onActivated(); + } + show(); } From 7ef9920bace7e1eceab2cc9f64d9e942ebf24e8a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Tue, 23 Sep 2014 00:16:57 +0200 Subject: [PATCH 162/240] Instantiate the Wold Editor window after the LIGO setup. --HG-- branch : dfighter-tools --- code/studio/src/plugins/world_editor/world_editor_plugin.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp index 722c14733..9b9622d00 100644 --- a/code/studio/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/studio/src/plugins/world_editor/world_editor_plugin.cpp @@ -86,9 +86,7 @@ WorldEditorContext::WorldEditorContext(QObject *parent) : IContext(parent), m_worldEditorWindow(0) { - m_worldEditorWindow = new WorldEditorWindow(); - - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Constants::WORLD_EDITOR_SECTION); m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat(); @@ -115,6 +113,7 @@ WorldEditorContext::WorldEditorContext(QObject *parent) // TODO: get file names! from settings m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); + m_worldEditorWindow = new WorldEditorWindow(); } QUndoStack *WorldEditorContext::undoStack() From e714e37c4c9f331069c03b10a64c3fcdd441a5f4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 13:54:02 +0200 Subject: [PATCH 163/240] Fix EGS sheet rebuild crashes --HG-- branch : develop --- .../egs_sheets/egs_static_game_item.cpp | 90 +++++++++---------- .../egs_sheets/egs_static_game_item.h | 4 +- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp index f36fe91ab..42517c190 100644 --- a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp +++ b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.cpp @@ -237,24 +237,12 @@ void SItemSpecialEffects::serial(class NLMISC::IStream &f) //-------------------------------------------------------------- // init() //-------------------------------------------------------------- -void CStaticItem::init() +void CStaticItem::init(bool doDelete) { Family = ITEMFAMILY::UNDEFINED; Type = ITEM_TYPE::UNDEFINED; - Armor = NULL; - MeleeWeapon = NULL; - RangeWeapon = NULL; - Ammo = NULL; - Shield = NULL; - TamingTool = NULL; - Mp = NULL; - GuildOption = NULL; - Cosmetics = NULL; - ItemServiceData = NULL; - ConsumableItem = NULL; - XpCatalyser = NULL; - CommandTicket = NULL; + clearPtrs(doDelete); Skill = SKILLS::unknown; MinSkill = 0; @@ -287,16 +275,54 @@ void CStaticItem::init() RequiredCharacQualityFactor = 0.0f; RequiredCharacQualityOffset = 0; - ItemSpecialEffects = NULL; } // init // +// *************************************************************************** +void CStaticItem::clearPtrs(bool doDelete) +{ + if (doDelete) + { + delete Armor; + delete MeleeWeapon; + delete RangeWeapon; + delete Ammo; + delete Shield; + delete TamingTool; + delete Mp; + delete GuildOption; + delete Cosmetics; + delete ItemServiceData; + delete ConsumableItem; + delete XpCatalyser; + delete CommandTicket; + delete ItemSpecialEffects; + } + + Armor = NULL; + MeleeWeapon = NULL; + RangeWeapon = NULL; + Ammo = NULL; + Shield = NULL; + TamingTool = NULL; + Mp = NULL; + GuildOption = NULL; + Cosmetics = NULL; + ItemServiceData = NULL; + ConsumableItem = NULL; + XpCatalyser = NULL; + CommandTicket = NULL; + ItemSpecialEffects = NULL; +} + //-------------------------------------------------------------- // copy constructor //-------------------------------------------------------------- CStaticItem::CStaticItem( const CStaticItem& itm ) { + clearPtrs(false); + *this = itm; if(itm.Armor) { @@ -1443,6 +1469,9 @@ void CStaticItem::readGeorges (const NLMISC::CSmartPtr &form, if (form == NULL) return; + // Clear pointers to previous data + clearPtrs(true); + // Get the root node, always exist UFormElm &root = form->getRootNode (); @@ -1993,37 +2022,6 @@ float CStaticItem::getBaseWeight() const } #endif -// *************************************************************************** -void CStaticItem::clearPtrs(bool doDelete) -{ - if(doDelete) - { - if (Ammo != NULL ) delete Ammo; - if (Armor != NULL ) delete Armor; - if (MeleeWeapon != NULL ) delete MeleeWeapon; - if (RangeWeapon != NULL ) delete RangeWeapon; - if (Cosmetics != NULL ) delete Cosmetics; - if (Mp != NULL ) delete Mp; - if (GuildOption != NULL ) delete GuildOption; - if (Shield != NULL ) delete Shield; - if (TamingTool != NULL) delete TamingTool; - if (ItemServiceData != NULL) delete ItemServiceData; - if (CommandTicket != NULL) delete CommandTicket; - } - - Ammo = NULL; - Armor = NULL; - MeleeWeapon = NULL; - RangeWeapon = NULL; - Cosmetics = NULL; - Mp = NULL; - GuildOption = NULL; - Shield = NULL; - TamingTool = NULL; - ItemServiceData = NULL; - CommandTicket = NULL; -} - uint32 CStaticItem::getMaxStackSize() const { diff --git a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h index ddea7be9c..96aae2e98 100644 --- a/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h +++ b/code/ryzom/server/src/entities_game_service/egs_sheets/egs_static_game_item.h @@ -812,13 +812,13 @@ public: public: /// Constructor - CStaticItem() { init(); } + CStaticItem() { init(false); } /// copy constructor CStaticItem( const CStaticItem& itm ); /// init method - void init(); + void init(bool doDelete = true); /// destructor virtual ~CStaticItem(); From cb022c6bbbc6c4ff322d0eda8f757d34e822cc70 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 18:18:14 +0200 Subject: [PATCH 164/240] Remove debug message --HG-- branch : develop --- code/ryzom/client/src/progress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/src/progress.cpp b/code/ryzom/client/src/progress.cpp index 8b5f72941..2631984e7 100644 --- a/code/ryzom/client/src/progress.cpp +++ b/code/ryzom/client/src/progress.cpp @@ -225,7 +225,7 @@ void CProgress::internalProgress (float value) if (!stereoHMD || StereoDisplay->wantInterface2D()) { - nldebug("Draw progress 2D"); + // nldebug("Draw progress 2D"); // Font factor float fontFactor = 1; From 6551881171338bfbaece82c122b625aab0171d8a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 23 Sep 2014 19:47:06 +0200 Subject: [PATCH 165/240] Handle GUI event only once --HG-- branch : develop --- code/nel/src/gui/widget_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e3f1064fa..18a1f066f 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2313,7 +2313,9 @@ namespace NLGUI getCapturePointerLeft() != getCapturePointerRight() ) handled|= getCapturePointerRight()->handleEvent(evnt); - if( _CapturedView != NULL ) + if( _CapturedView != NULL && + _CapturedView != getCapturePointerLeft() && + _CapturedView != getCapturePointerRight() ) _CapturedView->handleEvent( evnt ); CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); From 27cbd59a0fae25bb3505a9917385bf3a0ee74ec4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 24 Sep 2014 01:07:12 +0200 Subject: [PATCH 166/240] Add some more practical data build batch scripts --HG-- branch : develop --- code/nel/tools/build_gamedata/characters_dev.bat | 11 +++++++++++ code/nel/tools/build_gamedata/panoply_dev.bat | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 code/nel/tools/build_gamedata/characters_dev.bat create mode 100644 code/nel/tools/build_gamedata/panoply_dev.bat diff --git a/code/nel/tools/build_gamedata/characters_dev.bat b/code/nel/tools/build_gamedata/characters_dev.bat new file mode 100644 index 000000000..f2b374c47 --- /dev/null +++ b/code/nel/tools/build_gamedata/characters_dev.bat @@ -0,0 +1,11 @@ +title Ryzom Core: 1_export.py (CHARACTERS) +1_export.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: 2_build.py (CHARACTERS) +2_build.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: 3_install.py (CHARACTERS) +3_install.py -ipj common/characters common/characters_maps_hr +title Ryzom Core: b1_client_dev.py (CHARACTERS) +b1_client_dev.py +title Ryzom Core: b2_shard_data.py (CHARACTERS) +b2_shard_data.py +title Ryzom Core: Ready (CHARACTERS) diff --git a/code/nel/tools/build_gamedata/panoply_dev.bat b/code/nel/tools/build_gamedata/panoply_dev.bat new file mode 100644 index 000000000..13afac56c --- /dev/null +++ b/code/nel/tools/build_gamedata/panoply_dev.bat @@ -0,0 +1,11 @@ +title Ryzom Core: 1_export.py (PANOPLY) +1_export.py -ipj common/characters_maps_hr +title Ryzom Core: 2_build.py (PANOPLY) +2_build.py -ipj common/characters_maps_hr +title Ryzom Core: 3_install.py (PANOPLY) +3_install.py -ipj common/characters_maps_hr +title Ryzom Core: b1_client_dev.py (PANOPLY) +b1_client_dev.py +title Ryzom Core: b2_shard_data.py (PANOPLY) +b2_shard_data.py +title Ryzom Core: Ready (PANOPLY) From 3bd552ebb0b49009c1ab60d67fe6f5ba3a2afd55 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 24 Sep 2014 12:34:40 +0200 Subject: [PATCH 167/240] Add useful default config variables to dev client --HG-- branch : develop --- code/nel/tools/build_gamedata/b1_client_dev.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/tools/build_gamedata/b1_client_dev.py b/code/nel/tools/build_gamedata/b1_client_dev.py index d8c77c1fa..a23ee693c 100755 --- a/code/nel/tools/build_gamedata/b1_client_dev.py +++ b/code/nel/tools/build_gamedata/b1_client_dev.py @@ -52,6 +52,10 @@ if not os.path.isfile(ClientDevDirectory + "/client.cfg"): cfg.write("PreDataPath = {\n") cfg.write("\t\"" + InstallDirectory + "\", \"user\", \"patch\", \"data\", \"examples\" \n") cfg.write("};\n") + cfg.write("PatchWanted = 0;\n") + cfg.write("DisplayLuaDebugInfo = 1;\n") + cfg.write("AllowDebugLua = 1;\n") + cfg.write("FullScreen = 0;\n") printLog(log, "") printLog(log, ">>> Install data <<<") From 62744db86d24b6aad5f61ff19394875c877d83f8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:20:25 +0200 Subject: [PATCH 168/240] Dragged elements will no longer disappear. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 ++- code/nel/src/gui/widget_manager.cpp | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 5d2468e7a..ccf561d45 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -532,7 +532,8 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; - NLMISC::CRefPtr< CInterfaceElement > draggedElement; + NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging + std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e3f1064fa..c985557c5 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1036,6 +1036,8 @@ namespace NLGUI setCapturePointerLeft(NULL); setCapturePointerRight(NULL); _CapturedView = NULL; + + _OrphanElements.clear(); resetColorProps(); resetAlphaRolloverSpeedProps(); @@ -2039,6 +2041,15 @@ namespace NLGUI } } + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); + while( oeitr != _OrphanElements.end() ) + { + CInterfaceElement *e = *oeitr; + CViewBase *v = dynamic_cast< CViewBase* >( e ); + v->draw(); + ++oeitr; + } + if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2657,7 +2668,11 @@ namespace NLGUI void CWidgetManager::stopDragging() { - draggedElement = NULL; + if( draggedElement != NULL ) + { + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; + } } // ------------------------------------------------------------------------------------------------ @@ -3454,6 +3469,8 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { + _OrphanElements.clear(); + for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From f9dbef7df70fb0cc5e21723fe3caa77d8109bd6a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:31:26 +0200 Subject: [PATCH 169/240] Set dragged widgets' coordinates based on the move rather than the mouse pointer's coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c985557c5..5b131ee36 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,8 +2633,11 @@ namespace NLGUI else if( draggedElement != NULL ) { - draggedElement->setXReal( newX ); - draggedElement->setYReal( newY ); + sint32 dx = newX - oldX; + sint32 dy = newY - oldY; + + draggedElement->setXReal( draggedElement->getXReal() + dx ); + draggedElement->setYReal( draggedElement->getYReal() + dy ); draggedElement->invalidateCoords(); } } From bd7cb1eea3d4e3d974279b8f4b5e412a1c65bda1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 18:45:52 +0200 Subject: [PATCH 170/240] Add widget to a new parent when the widget being dragged is dropped, otherwise add it to the orphanlist so that it's drawn anyways. NOTE: The dropped widget can be clipped. If it is clipped, it never shows up even tho it's there. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 1 + code/nel/src/gui/interface_group.cpp | 30 ++++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 19 +++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index ff0efac3b..daf6d2d53 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -57,6 +57,7 @@ namespace NLGUI CInterfaceElement* findFromShortId(const std::string &id); /// Dynamic creation + virtual void addElement (CInterfaceElement *child, sint eltOrder = -1 ); virtual void addView (CViewBase *child , sint eltOrder = -1); virtual void addCtrl (CCtrlBase *child, sint eltOrder = -1); virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 4d37eda1c..05f210568 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -911,6 +911,31 @@ namespace NLGUI } } + // ------------------------------------------------------------------------------------------------ + void CInterfaceGroup::addElement (CInterfaceElement *child, sint eltOrder /*= -1*/) + { + if (!child) + { + nlwarning(" : tried to add a NULL view"); + return; + } + + if( child->isGroup() ) + { + addGroup( static_cast< CInterfaceGroup* >( child ), eltOrder ); + } + else + if( child->isCtrl() ) + { + addCtrl( static_cast< CCtrlBase* >( child ), eltOrder ); + } + else + if( child->isView() ) + { + addView( static_cast< CViewBase* >( child ), eltOrder ); + } + } + // ------------------------------------------------------------------------------------------------ void CInterfaceGroup::addView (CViewBase *child, sint eltOrder /*= -1*/) { @@ -1312,6 +1337,11 @@ namespace NLGUI for (ite = _EltOrder.begin() ; ite != _EltOrder.end(); ite++) { CViewBase *pVB = *ite; + if( pVB->getName() == "=MARKED=" ) + { + nlinfo( "=MARKED=" ); + } + if (pVB->getActive()) pVB->draw(); } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b131ee36..e44fa4d15 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2673,7 +2673,24 @@ namespace NLGUI { if( draggedElement != NULL ) { - _OrphanElements.push_back( draggedElement ); + CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + + if( g != NULL ) + { + CInterfaceElement *e = draggedElement; + e->setName( "=MARKED=" ); + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + g->addElement( e ); + + e->setParentPos( g ); + e->setParentSize( g ); + + checkCoords(); + } + else + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; } } From e7ab56beea0861700c24a414db2eb7454af41690 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 20:40:37 +0200 Subject: [PATCH 171/240] Orphaned widgets won't get stuck. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 62 ++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e44fa4d15..771bcf50e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2410,20 +2410,45 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + + if( CInterfaceElement::getEditorMode() ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); + while( itr != _OrphanElements.rend() ) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + CInterfaceElement *e = *itr; + + int x = getPointer()->getXReal(); + int y = getPointer()->getYReal(); + + if( e->isIn( x, y ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); + _CapturedView = static_cast< CViewBase* >( e ); captured = true; + break; + } + + ++itr; + } + } + + if( !captured ) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + { + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + { + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } @@ -2674,23 +2699,22 @@ namespace NLGUI if( draggedElement != NULL ) { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + CInterfaceElement *e = draggedElement; + + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + e->setParentPos( g ); + e->setParentSize( g ); if( g != NULL ) { - CInterfaceElement *e = draggedElement; - e->setName( "=MARKED=" ); - e->setParent( g ); - e->setIdRecurse( e->getShortId() ); g->addElement( e ); - - e->setParentPos( g ); - e->setParentSize( g ); - - checkCoords(); } else _OrphanElements.push_back( draggedElement ); + checkCoords(); + draggedElement = NULL; } } From a658be39b71bf9d16946b3e3e89944bd2b027fd9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 22:59:40 +0200 Subject: [PATCH 172/240] No need for free floating elements when we can simply reparent to the top window... --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 1 - code/nel/src/gui/widget_manager.cpp | 73 +++++------------------ 2 files changed, 16 insertions(+), 58 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index ccf561d45..8bd9052e5 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -533,7 +533,6 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging - std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 771bcf50e..40df50cb2 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1037,8 +1037,6 @@ namespace NLGUI setCapturePointerRight(NULL); _CapturedView = NULL; - _OrphanElements.clear(); - resetColorProps(); resetAlphaRolloverSpeedProps(); resetGlobalAlphasProps(); @@ -2041,15 +2039,6 @@ namespace NLGUI } } - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); - while( oeitr != _OrphanElements.end() ) - { - CInterfaceElement *e = *oeitr; - CViewBase *v = dynamic_cast< CViewBase* >( e ); - v->draw(); - ++oeitr; - } - if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2411,44 +2400,20 @@ namespace NLGUI if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); - while( itr != _OrphanElements.rend() ) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CInterfaceElement *e = *itr; - - int x = getPointer()->getXReal(); - int y = getPointer()->getYReal(); - - if( e->isIn( x, y ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - _CapturedView = static_cast< CViewBase* >( e ); + nMaxDepth = d; + setCapturePointerLeft( ctrl ); captured = true; - break; - } - - ++itr; - } - } - - if( !captured ) - { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) - { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) - { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; - } } } } @@ -2690,7 +2655,7 @@ namespace NLGUI e->setParent( NULL ); draggedElement = e; - + return true; } @@ -2700,20 +2665,16 @@ namespace NLGUI { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); CInterfaceElement *e = draggedElement; + CInterfaceGroup *tw = getTopWindow(); + + if( g == NULL ) + g = tw; e->setParent( g ); e->setIdRecurse( e->getShortId() ); e->setParentPos( g ); e->setParentSize( g ); - - if( g != NULL ) - { - g->addElement( e ); - } - else - _OrphanElements.push_back( draggedElement ); - - checkCoords(); + g->addElement( e ); draggedElement = NULL; } @@ -3513,8 +3474,6 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { - _OrphanElements.clear(); - for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From 006f87278b78ae7ef08d3de6a6d0856194f29559 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:32:24 +0200 Subject: [PATCH 173/240] Refactored IWidgetAdditionWatcher, now it's called IWidgetWatcher and it also reports widget moves. --HG-- branch : dfighter-tools --- .../include/nel/gui/widget_addition_watcher.h | 32 ------------- code/nel/include/nel/gui/widget_manager.h | 22 ++++++--- code/nel/src/gui/widget_manager.cpp | 45 ++++++++++++------- .../plugins/gui_editor/widget_hierarchy.cpp | 29 +++++++----- .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 5 files changed, 66 insertions(+), 63 deletions(-) delete mode 100644 code/nel/include/nel/gui/widget_addition_watcher.h diff --git a/code/nel/include/nel/gui/widget_addition_watcher.h b/code/nel/include/nel/gui/widget_addition_watcher.h deleted file mode 100644 index a2717e398..000000000 --- a/code/nel/include/nel/gui/widget_addition_watcher.h +++ /dev/null @@ -1,32 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef WIDGET_ADD_WATCHER -#define WIDGET_ADD_WATCHER - -#include - -namespace NLGUI -{ - class IWidgetAdditionWatcher - { - public: - virtual void widgetAdded( const std::string &name ) = 0; - }; -} - -#endif - diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8bd9052e5..89023c445 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -75,6 +75,16 @@ namespace NLGUI virtual void process() = 0; }; + // Interface for event handlers that can be called when widgets are added or moved + class IWidgetWatcher + { + public: + IWidgetWatcher(){} + virtual ~IWidgetWatcher(){} + virtual void onWidgetAdded( const std::string &name ) = 0; + virtual void onWidgetMoved( const std::string &oldid, const std::string &newid ) = 0; + }; + /// Frame render times struct SInterfaceTimes { @@ -498,10 +508,12 @@ namespace NLGUI void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); - - void notifyAdditionWatchers( const std::string &widgetName ); - void registerAdditionWatcher( IWidgetAdditionWatcher *watcher ); - void unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ); + + + void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); + void registerWidgetWatcher( IWidgetWatcher *watcher ); + void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); @@ -594,7 +606,7 @@ namespace NLGUI std::vector< INewScreenSizeHandler* > newScreenSizeHandlers; std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers; std::vector< IEditorSelectionWatcher* > selectionWatchers; - std::vector< IWidgetAdditionWatcher* > additionWatchers; + std::vector< IWidgetWatcher* > widgetWatchers; std::string currentEditorSelection; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 40df50cb2..11ad888f4 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -34,7 +34,6 @@ #include "nel/gui/interface_expr.h" #include "nel/gui/reflect_register.h" #include "nel/gui/editor_selection_watcher.h" -#include "nel/gui/widget_addition_watcher.h" #include "nel/misc/events.h" namespace NLGUI @@ -2669,6 +2668,8 @@ namespace NLGUI if( g == NULL ) g = tw; + + std::string oldid = e->getId(); e->setParent( g ); e->setIdRecurse( e->getShortId() ); @@ -2677,6 +2678,8 @@ namespace NLGUI g->addElement( e ); draggedElement = NULL; + + onWidgetMoved( oldid, e->getId() ); } } @@ -3364,36 +3367,46 @@ namespace NLGUI selectionWatchers.erase( itr ); } - void CWidgetManager::notifyAdditionWatchers( const std::string &widgetName ) + void CWidgetManager::onWidgetAdded( const std::string &id ) + { + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) + { + (*itr)->onWidgetAdded( id ); + ++itr; + } + } + + void CWidgetManager::onWidgetMoved( const std::string &oldid, const std::string &newid ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr = additionWatchers.begin(); - while( itr != additionWatchers.end() ) + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) { - (*itr)->widgetAdded( widgetName ); + (*itr)->onWidgetMoved( oldid, newid ); ++itr; } } - void CWidgetManager::registerAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::registerWidgetWatcher( IWidgetWatcher *watcher ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); + std::vector< IWidgetWatcher* >::const_iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); // already exists - if( itr != additionWatchers.end() ) + if( itr != widgetWatchers.end() ) return; - additionWatchers.push_back( watcher ); + widgetWatchers.push_back( watcher ); } - void CWidgetManager::unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::unregisterWidgetWatcher( IWidgetWatcher *watcher ) { - std::vector< IWidgetAdditionWatcher* >::iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); + std::vector< IWidgetWatcher* >::iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); // doesn't exist - if( itr == additionWatchers.end() ) + if( itr == widgetWatchers.end() ) return; - additionWatchers.erase( itr ); + widgetWatchers.erase( itr ); } CInterfaceElement* CWidgetManager::addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ) @@ -3426,7 +3439,7 @@ namespace NLGUI else g->addView( v ); - notifyAdditionWatchers( v->getId() ); + onWidgetAdded( v->getId() ); return v; } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 24208f4a3..8318ea926 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -18,7 +18,6 @@ #include "widget_hierarchy.h" #include "nel/gui/interface_group.h" #include "nel/gui/widget_manager.h" -#include "nel/gui/widget_addition_watcher.h" namespace { @@ -76,18 +75,24 @@ namespace GUIEditor::WidgetHierarchy *h; }; - class CWidgetAdditionWatcher : public IWidgetAdditionWatcher + class CWidgetWatcher : public CWidgetManager::IWidgetWatcher { public: - CWidgetAdditionWatcher(){ h = NULL; } - ~CWidgetAdditionWatcher(){} + CWidgetWatcher(){ h = NULL; } + ~CWidgetWatcher(){} - void widgetAdded( const std::string &name ) + void onWidgetAdded( const std::string &name ) { if( h != NULL ) h->onWidgetAdded( name ); } - + + void onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + if( h != NULL ) + h->onWidgetMoved( oldid, newid ); + } + void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; } private: @@ -95,7 +100,7 @@ namespace }; CWidgetDeletionWatcher deletionWatcher; - CWidgetAdditionWatcher additionWatcher; + CWidgetWatcher widgetwatcher; } namespace GUIEditor @@ -107,7 +112,7 @@ namespace GUIEditor connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); deletionWatcher.setWidgetHierarchy( this ); - additionWatcher.setWidgetHierarchy( this ); + widgetwatcher.setWidgetHierarchy( this ); } WidgetHierarchy::~WidgetHierarchy() @@ -117,7 +122,7 @@ namespace GUIEditor void WidgetHierarchy::clearHierarchy() { CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->unregisterAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->unregisterWidgetWatcher( &widgetwatcher ); widgetHT->clear(); widgetHierarchyMap.clear(); } @@ -126,7 +131,7 @@ namespace GUIEditor { clearHierarchy(); CInterfaceElement::registerDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->registerAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->registerWidgetWatcher( &widgetwatcher ); CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup ); if( mg != NULL ) @@ -231,6 +236,10 @@ namespace GUIEditor widgetHierarchyMap[ id ] = item; } + void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + } + void WidgetHierarchy::getCurrentGroup( QString &g ) { std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 4641c8ce8..e416ec145 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -44,6 +44,7 @@ namespace GUIEditor void onWidgetDeleted( const std::string &id ); void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); void getCurrentGroup( QString &g ); From 9cae0c179397b26b44312d2b1f4fc152eba24937 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:56:11 +0200 Subject: [PATCH 174/240] When repareting a widget, remove the old item from the hierarchy and add a new one at the right place. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 48 +++++++++++++++++++ .../src/plugins/gui_editor/widget_hierarchy.h | 2 + 2 files changed, 50 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 8318ea926..333386aca 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -182,6 +182,27 @@ namespace GUIEditor } } + QTreeWidgetItem* WidgetHierarchy::findItem( const std::string &id ) + { + std::map< std::string, QTreeWidgetItem* >::iterator itr + = widgetHierarchyMap.find( id ); + if( itr == widgetHierarchyMap.end() ) + return NULL; + else + return itr->second; + } + + QTreeWidgetItem* WidgetHierarchy::findParent( const std::string &id ) + { + // Get the parent's name + std::string::size_type p = id.find_last_of( ':' ); + if( p == std::string::npos ) + return NULL; + std::string parentId = id.substr( 0, p ); + + return findItem( parentId ); + } + void WidgetHierarchy::onWidgetDeleted( const std::string &id ) { std::map< std::string, QTreeWidgetItem* >::iterator itr @@ -238,6 +259,33 @@ namespace GUIEditor void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) { + QTreeWidgetItem *newParent = NULL; + QTreeWidgetItem *item = NULL; + QString id; + + newParent = findParent( newid ); + item = findItem( oldid ); + + if( ( newParent == NULL ) || ( item == NULL ) ) + return; + + // Remove old item + QTreeWidgetItem *p = item->parent(); + if( p != NULL ) + p->setExpanded( false ); + id = item->data( 0, Qt::DisplayRole ).toString(); + delete item; + item = NULL; + + // Remove reference to old item + widgetHierarchyMap.erase( oldid ); + + // Add new item + item = new QTreeWidgetItem(); + item->setData( 0, Qt::DisplayRole, id ); + item->setSelected( true ); + newParent->addChild( item ); + newParent->setExpanded( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index e416ec145..3d748e15f 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -50,6 +50,8 @@ namespace GUIEditor private: void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); + QTreeWidgetItem* findItem( const std::string &id ); + QTreeWidgetItem* findParent( const std::string &id ); public Q_SLOTS: void onGUILoaded(); From 4ec13e57e4097b9962e67d63203e1047037e3281 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 25 Sep 2014 00:37:25 +0200 Subject: [PATCH 175/240] Collapse the tree, and only expand the items that are needed to get to the selected items. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 34 +++++++++++++------ .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 333386aca..d52f55e27 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -285,7 +285,24 @@ namespace GUIEditor item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - newParent->setExpanded( true ); + + + selectItem( item ); + } + + void WidgetHierarchy::selectItem( QTreeWidgetItem *item ) + { + widgetHT->collapseAll(); + + QTreeWidgetItem *currItem = item; + while( currItem != NULL ) + { + currItem->setExpanded( true ); + currItem = currItem->parent(); + } + + widgetHT->setCurrentItem( item ); + item->setSelected( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) @@ -345,18 +362,11 @@ namespace GUIEditor if( widgetHT->currentItem() != NULL ) widgetHT->currentItem()->setSelected( false ); - // expand the tree items, so that we can see the selected item - QTreeWidgetItem *item = itr->second; - QTreeWidgetItem *currItem = item; - while( currItem != NULL ) - { - currItem->setExpanded( true ); - currItem = currItem->parent(); - } + widgetHT->collapseAll(); // select the current item - item->setSelected( true ); - widgetHT->setCurrentItem( item ); + QTreeWidgetItem *item = itr->second; + selectItem( item ); currentSelection = newSelection; } @@ -364,6 +374,8 @@ namespace GUIEditor { if( item->parent() == NULL ) return; + + selectItem( item ); std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 3d748e15f..27218715d 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -52,6 +52,7 @@ namespace GUIEditor void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); QTreeWidgetItem* findItem( const std::string &id ); QTreeWidgetItem* findParent( const std::string &id ); + void selectItem( QTreeWidgetItem *item ); public Q_SLOTS: void onGUILoaded(); From 8bc49f5b4b0c87fb886f0d5c1d9f12262125daeb Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Fri, 26 Sep 2014 22:30:56 +0200 Subject: [PATCH 176/240] rolling back to include a crypt(3) implementation and adding sha512 support --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 - code/ryzom/common/src/game_share/crypt.cpp | 985 ++++++++++++++++++ .../src/game_share/{ccrypt.h => crypt.h} | 0 .../common/src/game_share/crypt_sha512.cpp | 371 +++++++ .../src/monitor_service/service_main.cpp | 2 +- 6 files changed, 1358 insertions(+), 32 deletions(-) delete mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp create mode 100644 code/ryzom/common/src/game_share/crypt.cpp rename code/ryzom/common/src/game_share/{ccrypt.h => crypt.h} (100%) create mode 100644 code/ryzom/common/src/game_share/crypt_sha512.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 673a5b5f4..091e24a80 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp deleted file mode 100644 index ea67cf7d6..000000000 --- a/code/ryzom/common/src/game_share/ccrypt.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "ccrypt.h" - -#define _GNU_SOURCE 1 -#include - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::crypt(password.c_str(), salt.c_str()); - - return result; -} diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp new file mode 100644 index 000000000..881b42f1e --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -0,0 +1,985 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "crypt.h" + +char * rz_crypt(register const char *key, register const char *setting); +char *__crypt_sha512(const char *key, const char *setting, char *output); + + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::rz_crypt(password.c_str(), salt.c_str()); + + return result; +} + + + + + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* #include */ +#include +#include +#define RZ__PASSWORD_EFMT1 '-' + +#if DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows); +#endif + +/* + * UNIX password, and DES, encryption. + * By Tom Truscott, trt@rti.rti.org, + * from algorithms by Robert W. Baldwin and James Gillogly. + * + * References: + * "Mathematical Cryptology for Computer Scientists and Mathematicians," + * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. + * + * "Password Security: A Case History," R. Morris and Ken Thompson, + * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. + * + * "DES will be Totally Insecure within Ten Years," M.E. Hellman, + * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. + */ + +/* ===== Configuration ==================== */ + +/* + * define "MUST_ALIGN" if your compiler cannot load/store + * long integers at arbitrary (e.g. odd) memory locations. + * (Either that or never pass unaligned addresses to des_cipher!) + */ +#if !defined(vax) +#define MUST_ALIGN +#endif + +#ifdef CHAR_BITS +#if CHAR_BITS != 8 + #error C_block structure assumes 8 bit characters +#endif +#endif + +/* + * define "LONG_IS_32_BITS" only if sizeof(long)==4. + * This avoids use of bit fields (your compiler may be sloppy with them). + */ +#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) +#define LONG_IS_32_BITS +#endif + +/* + * define "B64" to be the declaration for a 64 bit integer. + * XXX this feature is currently unused, see "endian" comment below. + */ +#if defined(cray) || defined(__LP64__) || defined(_LP64) +#define B64 long +#endif +#if defined(convex) +#define B64 long long +#endif + +/* + * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes + * of lookup tables. This speeds up des_setkey() and des_cipher(), but has + * little effect on crypt(). + */ +#if defined(notdef) +#define LARGEDATA +#endif + +/* ==================================== */ + +/* + * Cipher-block representation (Bob Baldwin): + * + * DES operates on groups of 64 bits, numbered 1..64 (sigh). One + * representation is to store one bit per byte in an array of bytes. Bit N of + * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. + * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the + * first byte, 9..16 in the second, and so on. The DES spec apparently has + * bit 1 in the MSB of the first byte, but that is particularly noxious so we + * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is + * the MSB of the first byte. Specifically, the 64-bit input data and key are + * converted to LSB format, and the output 64-bit block is converted back into + * MSB format. + * + * DES operates internally on groups of 32 bits which are expanded to 48 bits + * by permutation E and shrunk back to 32 bits by the S boxes. To speed up + * the computation, the expansion is applied only once, the expanded + * representation is maintained during the encryption, and a compression + * permutation is applied only at the end. To speed up the S-box lookups, + * the 48 bits are maintained as eight 6 bit groups, one per byte, which + * directly feed the eight S-boxes. Within each byte, the 6 bits are the + * most significant ones. The low two bits of each byte are zero. (Thus, + * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the + * first byte in the eight byte representation, bit 2 of the 48 bit value is + * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is + * used, in which the output is the 64 bit result of an S-box lookup which + * has been permuted by P and expanded by E, and is ready for use in the next + * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this + * lookup. Since each byte in the 48 bit path is a multiple of four, indexed + * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and + * "salt" are also converted to this 8*(6+2) format. The SPE table size is + * 8*64*8 = 4K bytes. + * + * To speed up bit-parallel operations (such as XOR), the 8 byte + * representation is "union"ed with 32 bit values "i0" and "i1", and, on + * machines which support it, a 64 bit value "b64". This data structure, + * "C_block", has two problems. First, alignment restrictions must be + * honored. Second, the byte-order (e.g. little-endian or big-endian) of + * the architecture becomes visible. + * + * The byte-order problem is unfortunate, since on the one hand it is good + * to have a machine-independent C_block representation (bits 1..8 in the + * first byte, etc.), and on the other hand it is good for the LSB of the + * first byte to be the LSB of i0. We cannot have both these things, so we + * currently use the "little-endian" representation and avoid any multi-byte + * operations that depend on byte order. This largely precludes use of the + * 64-bit datatype since the relative order of i0 and i1 are unknown. It + * also inhibits grouping the SPE table to look up 12 bits at a time. (The + * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 + * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the + * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup + * requires a 128 kilobyte table, so perhaps this is not a big loss. + * + * Permutation representation (Jim Gillogly): + * + * A transformation is defined by its effect on each of the 8 bytes of the + * 64-bit input. For each byte we give a 64-bit output that has the bits in + * the input distributed appropriately. The transformation is then the OR + * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for + * each transformation. Unless LARGEDATA is defined, however, a more compact + * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. + * The smaller table uses 16*16*8 = 2K bytes for each transformation. This + * is slower but tolerable, particularly for password encryption in which + * the SPE transformation is iterated many times. The small tables total 9K + * bytes, the large tables total 72K bytes. + * + * The transformations used are: + * IE3264: MSB->LSB conversion, initial permutation, and expansion. + * This is done by collecting the 32 even-numbered bits and applying + * a 32->64 bit transformation, and then collecting the 32 odd-numbered + * bits and applying the same transformation. Since there are only + * 32 input bits, the IE3264 transformation table is half the size of + * the usual table. + * CF6464: Compression, final permutation, and LSB->MSB conversion. + * This is done by two trivial 48->32 bit compressions to obtain + * a 64-bit block (the bit numbering is given in the "CIFP" table) + * followed by a 64->64 bit "cleanup" transformation. (It would + * be possible to group the bits in the 64-bit block so that 2 + * identical 32->32 bit transformations could be used instead, + * saving a factor of 4 in space and possibly 2 in time, but + * byte-ordering and other complications rear their ugly head. + * Similar opportunities/problems arise in the key schedule + * transforms.) + * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. + * This admittedly baroque 64->64 bit transformation is used to + * produce the first code (in 8*(6+2) format) of the key schedule. + * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. + * It would be possible to define 15 more transformations, each + * with a different rotation, to generate the entire key schedule. + * To save space, however, we instead permute each code into the + * next by using a transformation that "undoes" the PC2 permutation, + * rotates the code, and then applies PC2. Unfortunately, PC2 + * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not + * invertible. We get around that problem by using a modified PC2 + * which retains the 8 otherwise-lost bits in the unused low-order + * bits of each byte. The low-order bits are cleared when the + * codes are stored into the key schedule. + * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. + * This is faster than applying PC2ROT[0] twice, + * + * The Bell Labs "salt" (Bob Baldwin): + * + * The salting is a simple permutation applied to the 48-bit result of E. + * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and + * i+24 of the result are swapped. The salt is thus a 24 bit number, with + * 16777216 possible values. (The original salt was 12 bits and could not + * swap bits 13..24 with 36..48.) + * + * It is possible, but ugly, to warp the SPE table to account for the salt + * permutation. Fortunately, the conditional bit swapping requires only + * about four machine instructions and can be done on-the-fly with about an + * 8% performance penalty. + */ + +typedef union { + unsigned char b[8]; + struct { +#if defined(LONG_IS_32_BITS) + /* long is often faster than a 32-bit bit field */ + long i0; + long i1; +#else + long i0: 32; + long i1: 32; +#endif + } b32; +#if defined(B64) + B64 b64; +#endif +} C_block; + +/* + * Convert twenty-four-bit long in host-order + * to six bits (and 2 low-order zeroes) per char little-endian format. + */ +#define TO_SIX_BIT(rslt, src) { \ + C_block cvt; \ + cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[3] = (unsigned char) (src&0xFF); \ + rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ + } + +/* + * These macros may someday permit efficient use of 64-bit integers. + */ +#define ZERO(d,d0,d1) d0 = 0, d1 = 0 +#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 +#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 +#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 +#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 +#define DCL_BLOCK(d,d0,d1) long d0, d1 + +#if defined(LARGEDATA) + /* Waste memory like crazy. Also, do permutations in line */ +#define LGCHUNKBITS 3 +#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); + STORE(D,D0,D1,*out); +} +#endif /* LARGEDATA */ + + +/* ===== (mostly) Standard DES Tables ==================== */ + +static unsigned char IP[] = { /* initial permutation */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* The final permutation is the inverse of IP - no table is necessary */ + +static unsigned char ExpandTr[] = { /* expansion operation */ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +static unsigned char PC1[] = { /* permuted choice table 1 */ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +static unsigned char Rotates[] = { /* PC1 rotation schedule */ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* note: each "row" of PC2 is left-padded with bits that make it invertible */ +static unsigned char PC2[] = { /* permuted choice table 2 */ + 9, 18, 14, 17, 11, 24, 1, 5, + 22, 25, 3, 28, 15, 6, 21, 10, + 35, 38, 23, 19, 12, 4, 26, 8, + 43, 54, 16, 7, 27, 20, 13, 2, + + 0, 0, 41, 52, 31, 37, 47, 55, + 0, 0, 30, 40, 51, 45, 33, 48, + 0, 0, 44, 49, 39, 56, 34, 53, + 0, 0, 46, 42, 50, 36, 29, 32, +}; + +static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ + /* S[1] */ + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + /* S[2] */ + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + /* S[3] */ + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + /* S[4] */ + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + /* S[5] */ + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + /* S[6] */ + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + /* S[7] */ + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + /* S[8] */ + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} +}; + +static unsigned char P32Tr[] = { /* 32-bit permutation function */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +static unsigned char CIFP[] = { /* compressed/interleaved permutation */ + 1, 2, 3, 4, 17, 18, 19, 20, + 5, 6, 7, 8, 21, 22, 23, 24, + 9, 10, 11, 12, 25, 26, 27, 28, + 13, 14, 15, 16, 29, 30, 31, 32, + + 33, 34, 35, 36, 49, 50, 51, 52, + 37, 38, 39, 40, 53, 54, 55, 56, + 41, 42, 43, 44, 57, 58, 59, 60, + 45, 46, 47, 48, 61, 62, 63, 64, +}; + +static unsigned char itoa64[] = /* 0..63 => ascii-64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + +/* ===== Tables that are initialized at run time ==================== */ + + +static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ + +/* Initial key schedule permutation */ +static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ +static C_block CF6464[64/CHUNKBITS][1<= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + num_iter = (num_iter<<6) | a64toi[t]; + } + setting += 4; + encp += 4; + salt_size = 4; + break; + default: + num_iter = 25; + salt_size = 2; + } + + salt = 0; + for (i = salt_size; --i >= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + salt = (salt<<6) | a64toi[t]; + } + encp += salt_size; + if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, + salt, num_iter)) + return (NULL); + + /* + * Encode the 64 cipher bits as 11 ascii characters. + */ + i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; + + encp[3] = 0; + + return (cryptresult); +} + + +/* + * The Key Schedule, filled in by des_setkey() or setkey(). + */ +#define KS_SIZE 16 +static C_block KS[KS_SIZE]; + +/* + * Set up the key schedule from the key. + */ +int rz_des_setkey(register const char *key) { + register DCL_BLOCK(K, K0, K1); + register C_block *ptabp; + register int i; + static int des_ready = 0; + + if (!des_ready) { + rz_init_des(); + des_ready = 1; + } + + PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); + key = (char *)&KS[0]; + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + for (i = 1; i < 16; i++) { + key += sizeof(C_block); + STORE(K,K0,K1,*(C_block *)key); + ptabp = (C_block *)PC2ROT[Rotates[i]-1]; + PERM6464(K,K0,K1,(unsigned char *)key,ptabp); + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + } + return (0); +} + +/* + * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) + * iterations of DES, using the given 24-bit salt and the pre-computed key + * schedule, and store the resulting 8 chars at "out" (in == out is permitted). + * + * NOTE: the performance of this routine is critically dependent on your + * compiler and machine architecture. + */ +int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { + /* variables that we want in registers, most important first */ +#if defined(pdp11) + register int j; +#endif + register long L0, L1, R0, R1, k; + register C_block *kp; + register int ks_inc, loop_count; + C_block B; + + L0 = salt; + TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ + +#if defined(vax) || defined(pdp11) + salt = ~salt; /* "x &~ y" is faster than "x & y". */ +#define SALT (~salt) +#else +#define SALT salt +#endif + +#if defined(MUST_ALIGN) + B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; + B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; + LOAD(L,L0,L1,B); +#else + LOAD(L,L0,L1,*(C_block *)in); +#endif + LOADREG(R,R0,R1,L,L0,L1); + L0 &= 0x55555555L; + L1 &= 0x55555555L; + L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ + R0 &= 0xaaaaaaaaL; + R1 = (R1 >> 1) & 0x55555555L; + L1 = R0 | R1; /* L1 is the odd-numbered input bits */ + STORE(L,L0,L1,B); + PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ + PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ + + if (num_iter >= 0) + { /* encryption */ + kp = &KS[0]; + ks_inc = sizeof(*kp); + } + else + { /* decryption */ + num_iter = -num_iter; + kp = &KS[KS_SIZE-1]; + ks_inc = -((int) sizeof(*kp)); + } + + while (--num_iter >= 0) { + loop_count = 8; + do { + +#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) +#if defined(gould) + /* use this if B.b[i] is evaluated just once ... */ +#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); +#else +#if defined(pdp11) + /* use this if your "long" int indexing is slow */ +#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); +#else + /* use this if "k" is allocated to a register ... */ +#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); +#endif +#endif + +#define CRUNCH(p0, p1, q0, q1) \ + k = (q0 ^ q1) & SALT; \ + B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ + B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ + kp = (C_block *)((char *)kp+ks_inc); \ + \ + DOXOR(p0, p1, 0); \ + DOXOR(p0, p1, 1); \ + DOXOR(p0, p1, 2); \ + DOXOR(p0, p1, 3); \ + DOXOR(p0, p1, 4); \ + DOXOR(p0, p1, 5); \ + DOXOR(p0, p1, 6); \ + DOXOR(p0, p1, 7); + + CRUNCH(L0, L1, R0, R1); + CRUNCH(R0, R1, L0, L1); + } while (--loop_count != 0); + kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); + + + /* swap L and R */ + L0 ^= R0; L1 ^= R1; + R0 ^= L0; R1 ^= L1; + L0 ^= R0; L1 ^= R1; + } + + /* store the encrypted (or decrypted) result */ + L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); + L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); + STORE(L,L0,L1,B); + PERM6464(L,L0,L1,B.b, (C_block *)CF6464); +#if defined(MUST_ALIGN) + STORE(L,L0,L1,B); + out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; + out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; +#else + STORE(L,L0,L1,*(C_block *)out); +#endif + return (0); +} + + +/* + * Initialize various tables. This need only be done once. It could even be + * done at compile time, if the compiler were capable of that sort of thing. + */ +/* STATIC */void rz_init_des() { + register int i, j; + register long k; + register int tableno; + static unsigned char perm[64], tmp32[32]; /* "static" for speed */ + + /* + * table that converts chars "./0-9A-Za-z"to integers 0-63. + */ + for (i = 0; i < 64; i++) + a64toi[itoa64[i]] = i; + + /* + * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. + */ + for (i = 0; i < 64; i++) + perm[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += Rotates[0]-1; + if ((k%28) < Rotates[0]) k -= 28; + k = PC1[k]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i] = (unsigned char) k; + } +#ifdef DEBUG_CRYPT + prtab("pc1tab", perm, 8); +#endif + rz_init_perm(PC1ROT, perm, 8, 8); + + /* + * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. + */ + for (j = 0; j < 2; j++) { + unsigned char pc2inv[64]; + for (i = 0; i < 64; i++) + perm[i] = pc2inv[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + pc2inv[k-1] = i+1; + } + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += j; + if ((k%28) <= j) k -= 28; + perm[i] = pc2inv[k]; + } +#ifdef DEBUG_CRYPT + prtab("pc2tab", perm, 8); +#endif + rz_init_perm(PC2ROT[j], perm, 8, 8); + } + + /* + * Bit reverse, then initial permutation, then expansion. + */ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; + if (k > 32) + k -= 32; + else if (k > 0) + k--; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i*8+j] = (unsigned char) k; + } + } +#ifdef DEBUG_CRYPT + prtab("ietab", perm, 8); +#endif + rz_init_perm(IE3264, perm, 4, 8); + + /* + * Compression, then final permutation, then bit reverse. + */ + for (i = 0; i < 64; i++) { + k = IP[CIFP[i]-1]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[k-1] = i+1; + } +#ifdef DEBUG_CRYPT + prtab("cftab", perm, 8); +#endif + rz_init_perm(CF6464, perm, 8, 8); + + /* + * SPE table + */ + for (i = 0; i < 48; i++) + perm[i] = P32Tr[ExpandTr[i]-1]; + for (tableno = 0; tableno < 8; tableno++) { + for (j = 0; j < 64; j++) { + k = (((j >> 0) &01) << 5)| + (((j >> 1) &01) << 3)| + (((j >> 2) &01) << 2)| + (((j >> 3) &01) << 1)| + (((j >> 4) &01) << 0)| + (((j >> 5) &01) << 4); + k = S[tableno][k]; + k = (((k >> 3)&01) << 0)| + (((k >> 2)&01) << 1)| + (((k >> 1)&01) << 2)| + (((k >> 0)&01) << 3); + for (i = 0; i < 32; i++) + tmp32[i] = 0; + for (i = 0; i < 4; i++) + tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i]-1]; + TO_SIX_BIT(SPE[0][tableno][j], k); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i+24]-1]; + TO_SIX_BIT(SPE[1][tableno][j], k); + } + } +} + +/* + * Initialize "perm" to represent transformation "p", which rearranges + * (perhaps with expansion and/or contraction) one packed array of bits + * (of size "chars_in" characters) into another array (of size "chars_out" + * characters). + * + * "perm" must be all-zeroes on entry to this routine. + */ +/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ + l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ + for (j = 0; j < (1<>3] |= 1<<(k&07); + } + } +} + +/* + * "setkey" routine (for backwards compatibility) + */ +int rz_setkey(register const char *key) { + register int i, j, k; + C_block keyblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*key++; + } + keyblock.b[i] = k; + } + return (rz_des_setkey((char *)keyblock.b)); +} + +/* + * "encrypt" routine (for backwards compatibility) + */ +int rz_encrypt(register char *block, int flag) { + register int i, j, k; + C_block cblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*block++; + } + cblock.b[i] = k; + } + if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) + return (1); + for (i = 7; i >= 0; i--) { + k = cblock.b[i]; + for (j = 7; j >= 0; j--) { + *--block = k&01; + k >>= 1; + } + } + return (0); +} + +#ifdef DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows) +{ + register int i, j; + + (void)printf("%s:\n", s); + for (i = 0; i < num_rows; i++) { + for (j = 0; j < 8; j++) { + (void)printf("%3d", t[i*8+j]); + } + (void)printf("\n"); + } + (void)printf("\n"); +} +#endif diff --git a/code/ryzom/common/src/game_share/ccrypt.h b/code/ryzom/common/src/game_share/crypt.h similarity index 100% rename from code/ryzom/common/src/game_share/ccrypt.h rename to code/ryzom/common/src/game_share/crypt.h diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp new file mode 100644 index 000000000..c12359485 --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -0,0 +1,371 @@ +/* + * public domain sha512 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha512 implementation based on fips180-3 */ +/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ + +struct sha512 { + uint64_t len; /* processed message length */ + uint64_t h[8]; /* hash state */ + uint8_t buf[128]; /* message block buffer */ +}; + +static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) +#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) +#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) +#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) + +static const uint64_t K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +static void processblock(struct sha512 *s, const uint8_t *buf) +{ + uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint64_t)buf[8*i]<<56; + W[i] |= (uint64_t)buf[8*i+1]<<48; + W[i] |= (uint64_t)buf[8*i+2]<<40; + W[i] |= (uint64_t)buf[8*i+3]<<32; + W[i] |= (uint64_t)buf[8*i+4]<<24; + W[i] |= (uint64_t)buf[8*i+5]<<16; + W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] |= buf[8*i+7]; + } + for (; i < 80; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 80; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha512 *s) +{ + unsigned r = s->len % 128; + + s->buf[r++] = 0x80; + if (r > 112) { + memset(s->buf + r, 0, 128 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 120 - r); + s->len *= 8; + s->buf[120] = s->len >> 56; + s->buf[121] = s->len >> 48; + s->buf[122] = s->len >> 40; + s->buf[123] = s->len >> 32; + s->buf[124] = s->len >> 24; + s->buf[125] = s->len >> 16; + s->buf[126] = s->len >> 8; + s->buf[127] = s->len; + processblock(s, s->buf); +} + +static void sha512_init(struct sha512 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667f3bcc908ULL; + s->h[1] = 0xbb67ae8584caa73bULL; + s->h[2] = 0x3c6ef372fe94f82bULL; + s->h[3] = 0xa54ff53a5f1d36f1ULL; + s->h[4] = 0x510e527fade682d1ULL; + s->h[5] = 0x9b05688c2b3e6c1fULL; + s->h[6] = 0x1f83d9abfb41bd6bULL; + s->h[7] = 0x5be0cd19137e2179ULL; +} + +static void sha512_sum(struct sha512 *s, uint8_t *md) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[8*i] = s->h[i] >> 56; + md[8*i+1] = s->h[i] >> 48; + md[8*i+2] = s->h[i] >> 40; + md[8*i+3] = s->h[i] >> 32; + md[8*i+4] = s->h[i] >> 24; + md[8*i+5] = s->h[i] >> 16; + md[8*i+6] = s->h[i] >> 8; + md[8*i+7] = s->h[i]; + } +} + +static void sha512_update(struct sha512 *s, const void *m, unsigned long len) +{ + const uint8_t *p = (uint8_t *)m; + unsigned r = s->len % 128; + + s->len += len; + if (r) { + if (len < 128 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 128 - r); + len -= 128 - r; + p += 128 - r; + processblock(s, s->buf); + } + for (; len >= 128; len -= 128, p += 128) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static const unsigned char b64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 9999999 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha512 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 64; i -= 64) + sha512_update(s, md, 64); + sha512_update(s, md, i); +} + +static char *sha512crypt(const char *key, const char *setting, char *output) +{ + struct sha512 ctx; + unsigned char md[64], kmd[64], smd[64]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + for (i = 0; i <= KEY_MAX && key[i]; i++); + if (i > KEY_MAX) + return 0; + klen = i; + + /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$6$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha512_update(&ctx, md, sizeof md); + else + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha512_init(&ctx); + for (i = 0; i < klen; i++) + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha512_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha512_update(&ctx, salt, slen); + sha512_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha512_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha512_update(&ctx, md, sizeof md); + if (i % 3) + sha512_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha512_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha512_sum(&ctx, md); + } + + /* output is $6$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); +#if 1 + static const unsigned char perm[][3] = { + 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, + 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, + 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, + 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, + 62,20,41 }; + for (i=0; i<21; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); +#else + p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); + p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); + p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); + p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); + p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); + p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); + p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); + p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); + p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); + p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); + p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); + p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); + p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); + p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); + p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); + p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); + p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); + p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); + p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); + p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); + p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); +#endif + p = to64(p, md[63], 2); + *p = 0; + return output; +} + +char *__crypt_sha512(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; + static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; + char testbuf[128]; + char *p, *q; + + p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha512crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index aa559b78d..84bbcbe86 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "nel/misc/time_nl.h" #include "client.h" From 938c36027d1e175ce1f4714739d7b041a0c00617 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 26 Sep 2014 23:29:38 +0200 Subject: [PATCH 177/240] Editbox selection should be stopped when the mouse button goes up, even if it happens outside of the box. --HG-- branch : develop --- code/nel/src/gui/group_editbox.cpp | 21 +++++++++++---------- code/nel/src/gui/widget_manager.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 751d9241b..c18c69134 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -1320,6 +1320,16 @@ namespace NLGUI } } + // if click, and not frozen, then get the focus + if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen) + { + _SelectingText = false; + if (_SelectCursorPos == _CursorPos) + _CurrSelection = NULL; + + return true; + } + if (!isIn(eventDesc.getX(), eventDesc.getY())) return false; @@ -1329,6 +1339,7 @@ namespace NLGUI _SelectingText = true; stopParentBlink(); CWidgetManager::getInstance()->setCaptureKeyboard (this); + CWidgetManager::getInstance()->setCapturePointerLeft (this); // set the right cursor position uint newCurPos; bool cursorAtPreviousLineEnd; @@ -1356,16 +1367,6 @@ namespace NLGUI return true; } - // if click, and not frozen, then get the focus - if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup && !_Frozen) - { - _SelectingText = false; - if (_SelectCursorPos == _CursorPos) - _CurrSelection = NULL; - - return true; - } - if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown) { CWidgetManager::getInstance()->setCapturePointerRight(this); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 18a1f066f..a448603c0 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2539,6 +2539,12 @@ namespace NLGUI { if ( getCapturePointerLeft() != NULL) { + if( !handled ) + { + CCtrlBase *c = getCapturePointerLeft(); + c->handleEvent( evnt ); + } + setCapturePointerLeft(NULL); handled = true; } From 8c3702f826f8826e0044b01647a4d1db5924ebee Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:00:52 +0200 Subject: [PATCH 178/240] Update coords when changing something. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bd73fb7fa..bfdd0d6fa 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -493,6 +493,10 @@ namespace GUIEditor if( e == NULL ) return; e->setProperty( propName.toUtf8().constData(), propValue.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); // Make sure the changes are applied @@ -631,6 +635,16 @@ namespace GUIEditor e->setProperty( propName.toUtf8().constData(), v ); } + + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e != NULL ) + { + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); + } + } @@ -643,6 +657,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::onTexturePropertyChanged( QtProperty *p, const QString &v ) @@ -654,6 +672,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::enablePropertyWatchers() From 0af278e50a7fe94d8d8e83e19bbbd202691d6219 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:04:49 +0200 Subject: [PATCH 179/240] A little bit of refactoring. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bfdd0d6fa..c005f80e5 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -518,13 +518,12 @@ namespace GUIEditor return; std::string type = itr->second; + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e == NULL ) + return; if( type == "button_type" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelButtonType::toString( value ); if( v.empty() ) @@ -535,10 +534,6 @@ namespace GUIEditor else if( type == "text_justification" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelTxtJustification::toString( value ); if( v.empty() ) @@ -549,10 +544,6 @@ namespace GUIEditor else if( type == "posref" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRef::toString( value ); if( v.empty() ) return; @@ -562,10 +553,6 @@ namespace GUIEditor else if( type == "posreftt" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRefTT::toString( value ); if( v.empty() ) return; @@ -612,10 +599,6 @@ namespace GUIEditor else if( type == "tooltip_parent" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelTTParent::toString( value ); if( v.empty() ) return; @@ -625,10 +608,6 @@ namespace GUIEditor else if( type == "bitmap_align" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelBMAlign::toString( value ); if( v.empty() ) return; @@ -637,13 +616,9 @@ namespace GUIEditor } - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e != NULL ) - { - CInterfaceGroup *g = e->getParent(); - if( g != NULL ) - g->updateCoords(); - } + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } From 0d6265015946c73504fd77fedd7338f60aca2920 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 27 Sep 2014 15:55:57 +0300 Subject: [PATCH 180/240] Add maxlength attribute to input and textarea tags --HG-- branch : html-maxlength-attr --- code/nel/include/nel/gui/group_html.h | 3 ++- code/nel/include/nel/gui/libwww.h | 1 + code/nel/src/gui/group_html.cpp | 27 +++++++++++++++++---------- code/nel/src/gui/libwww.cpp | 1 + 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 3f5526197..ba34af2dd 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -285,7 +285,7 @@ namespace NLGUI void addImage(const char *image, bool globalColor, bool reloadImg=false); // Add a text area in the current paragraph - CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content); + CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength); // Add a combo box in the current paragraph CDBGroupComboBox *addComboBox(const std::string &templateName, const char *name); @@ -557,6 +557,7 @@ namespace NLGUI std::string _TextAreaName; uint _TextAreaRow; uint _TextAreaCols; + uint _TextAreaMaxLength; // current mode is in select option bool _SelectOption; diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index 8da217382..ec23cafd2 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -189,6 +189,7 @@ namespace NLGUI HTML_ATTR(TEXTAREA,DISABLED), HTML_ATTR(TEXTAREA,ID), HTML_ATTR(TEXTAREA,LANG), + HTML_ATTR(TEXTAREA,MAXLENGTH), HTML_ATTR(TEXTAREA,NAME), HTML_ATTR(TEXTAREA,READONLY), HTML_ATTR(TEXTAREA,ROWS), diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 9f19f383a..1a2ae5b4b 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1289,16 +1289,19 @@ namespace NLGUI string name; ucstring ucValue; uint size = 120; + uint maxlength = 1024; if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME]) name = value[MY_HTML_INPUT_NAME]; if (present[MY_HTML_INPUT_SIZE] && value[MY_HTML_INPUT_SIZE]) fromString(value[MY_HTML_INPUT_SIZE], size); if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE]) ucValue.fromUtf8(value[MY_HTML_INPUT_VALUE]); + if (present[MY_HTML_INPUT_MAXLENGTH] && value[MY_HTML_INPUT_MAXLENGTH]) + fromString(value[MY_HTML_INPUT_MAXLENGTH], maxlength); string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup); // Add the editbox - CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue); + CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength); if (textArea) { // Add the text area to the form @@ -1553,12 +1556,15 @@ namespace NLGUI _TextAreaRow = 1; _TextAreaCols = 10; _TextAreaContent = ""; - if (present[HTML_TEXTAREA_NAME] && value[HTML_TEXTAREA_NAME]) - _TextAreaName = value[HTML_TEXTAREA_NAME]; - if (present[HTML_TEXTAREA_ROWS] && value[HTML_TEXTAREA_ROWS]) - fromString(value[HTML_TEXTAREA_ROWS], _TextAreaRow); - if (present[HTML_TEXTAREA_COLS] && value[HTML_TEXTAREA_COLS]) - fromString(value[HTML_TEXTAREA_COLS], _TextAreaCols); + _TextAreaMaxLength = 1024; + if (present[MY_HTML_TEXTAREA_NAME] && value[MY_HTML_TEXTAREA_NAME]) + _TextAreaName = value[MY_HTML_TEXTAREA_NAME]; + if (present[MY_HTML_TEXTAREA_ROWS] && value[MY_HTML_TEXTAREA_ROWS]) + fromString(value[MY_HTML_TEXTAREA_ROWS], _TextAreaRow); + if (present[MY_HTML_TEXTAREA_COLS] && value[MY_HTML_TEXTAREA_COLS]) + fromString(value[MY_HTML_TEXTAREA_COLS], _TextAreaCols); + if (present[MY_HTML_TEXTAREA_MAXLENGTH] && value[MY_HTML_TEXTAREA_MAXLENGTH]) + fromString(value[MY_HTML_TEXTAREA_MAXLENGTH], _TextAreaMaxLength); _TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup; _TextArea = true; @@ -1680,7 +1686,7 @@ namespace NLGUI // nlinfo("textarea name '%s'", _TextAreaName.c_str()); // nlinfo("textarea %d %d", _TextAreaRow, _TextAreaCols); // nlinfo("textarea content '%s'", _TextAreaContent.toUtf8().c_str()); - CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent); + CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); if (textArea) { // Add the text area to the form @@ -3258,7 +3264,7 @@ namespace NLGUI // *************************************************************************** - CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content) + CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content, uint maxlength) { // In a paragraph ? if (!_Paragraph) @@ -3280,7 +3286,8 @@ namespace NLGUI templateParams.push_back (std::pair ("multiline", multiLine?"true":"false")); templateParams.push_back (std::pair ("want_return", multiLine?"true":"false")); templateParams.push_back (std::pair ("enter_recover_focus", "false")); - templateParams.push_back (std::pair ("max_num_chars", "1024")); + if (maxlength > 0) + templateParams.push_back (std::pair ("max_num_chars", toString(maxlength))); CInterfaceGroup *textArea = CWidgetManager::getInstance()->getParser()->createGroupInstance (templateName.c_str(), getParagraph()->getId(), templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size()); diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp index 1e5f7a226..0b759a7aa 100644 --- a/code/nel/src/gui/libwww.cpp +++ b/code/nel/src/gui/libwww.cpp @@ -201,6 +201,7 @@ namespace NLGUI HTML_ATTR(TEXTAREA,DISABLED), HTML_ATTR(TEXTAREA,ID), HTML_ATTR(TEXTAREA,LANG), + HTML_ATTR(TEXTAREA,MAXLENGTH), HTML_ATTR(TEXTAREA,NAME), HTML_ATTR(TEXTAREA,READONLY), HTML_ATTR(TEXTAREA,ROWS), From c6df57adf1267e12841cbd18740033ede6613a36 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 18:20:29 +0200 Subject: [PATCH 181/240] Initialize struct member before use... --HG-- branch : develop --- code/nel/src/3d/driver/opengl/driver_opengl_window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 751e72149..5bea65771 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1851,6 +1851,9 @@ bool CDriverGL::setMode(const GfxMode& mode) #if defined(NL_OS_WINDOWS) // save relative cursor POINT cursorPos; + cursorPos.x = 0; + cursorPos.y = 0; + BOOL cursorPosOk = isSystemCursorInClientArea() && GetCursorPos(&cursorPos) && ScreenToClient(_win, &cursorPos); From 4797b150d8015c209ef3f268d0dc69f449d641d4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 19:54:19 +0200 Subject: [PATCH 182/240] Move the text too with the text button. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/view_text.h | 9 ++++++++- code/nel/src/gui/ctrl_text_button.cpp | 22 ++++++++++------------ code/nel/src/gui/view_text.cpp | 13 +++++++++++-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index df3cf27e3..e7cc54d82 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -202,7 +202,11 @@ namespace NLGUI REFLECT_EXPORT_END - virtual void serial(NLMISC::IStream &f); + virtual void serial(NLMISC::IStream &f); + + // Sets the parent element + // See the comment at the field + void setParentElm( CInterfaceElement *parent ){ _ParentElm = parent; } protected: std::string _HardtextFormat; @@ -379,6 +383,9 @@ namespace NLGUI /// Dynamic tooltips std::vector _Tooltips; + // Parent element is the element where this text belongs to + // For example: text button + CInterfaceElement *_ParentElm; private: void setup (); diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index d3a0f6765..b14fb27ca 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -66,8 +66,6 @@ namespace NLGUI { if( _ViewText != NULL ) { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); delete _ViewText; _ViewText = NULL; } @@ -569,6 +567,7 @@ namespace NLGUI ((CViewTextID*)_ViewText)->parseTextIdOptions(cur); // Same RenderLayer as us. _ViewText->setRenderLayer(getRenderLayer()); + _ViewText->setParentElm(this); // Parse the hardText (if not text id) if(!_IsViewTextId) { @@ -863,6 +862,12 @@ namespace NLGUI } if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); + + // When dragging the button, the text needs to move too + if( CInterfaceElement::editorMode ) + _ViewText->updateCoords(); + + _ViewText->draw(); } } @@ -873,6 +878,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); + _ViewText->updateCoords(); + // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) { @@ -910,15 +917,13 @@ namespace NLGUI } // setup the viewText and add to parent - _ViewText->setParent (getParent()); + _ViewText->setParentElm (this); _ViewText->setParentPos (this); _ViewText->setParentPosRef (_TextParentPosRef); _ViewText->setPosRef (_TextPosRef); _ViewText->setActive(_Active); _ViewText->setX(_TextX); _ViewText->setY(_TextY); - - getParent()->addView(_ViewText); } // *************************************************************************** @@ -1007,17 +1012,10 @@ namespace NLGUI // *************************************************************************** void CCtrlTextButton::onRemoved() { - if( _ViewText != NULL ) - { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); - } } void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { - if( e == _ViewText ) - _ViewText = NULL; } } diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6ff1930af..602126dd8 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1814,9 +1814,18 @@ namespace NLGUI if (_AutoClamp) { CViewBase::updateCoords (); - if (_Parent) + + // If there's no parent, try the parent of the parent element. + // Since we will be under the same group + CInterfaceGroup *parent = _Parent; + if( parent == NULL ) + { + if( _ParentElm != NULL ) + parent = _ParentElm->getParent(); + } + + if (parent) { - CInterfaceGroup *parent = _Parent; // avoid resizing parents to compute the limiter while (parent && (parent->getResizeFromChildW() || parent->isGroupList() )) { From 0055e2dd91d95c562c9620fddf01908f719895b8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:15:46 +0200 Subject: [PATCH 183/240] A little refactoring. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/ctrl_text_button.h | 1 + code/nel/include/nel/gui/interface_element.h | 8 ++++++++ code/nel/src/gui/ctrl_text_button.cpp | 12 ++++++++---- code/nel/src/gui/widget_manager.cpp | 4 +--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index 183b6a65e..d2b49ffa9 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -126,6 +126,7 @@ namespace NLGUI void onRemoved(); void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); protected: diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index db7a499c8..048ec4b6e 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -510,6 +510,14 @@ namespace NLGUI /// so other widgets in the group can check if it belongs to them virtual void onWidgetDeleted( CInterfaceElement *e ){} + /// Move the element by x in the X direction and y in the Y direction + // Uses real coordinates + virtual void moveBy( sint32 x, sint32 y ) + { + _XReal += x; + _YReal += y; + } + protected: bool editorSelected; diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index b14fb27ca..03db2b797 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -863,10 +863,6 @@ namespace NLGUI if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); - // When dragging the button, the text needs to move too - if( CInterfaceElement::editorMode ) - _ViewText->updateCoords(); - _ViewText->draw(); } } @@ -1017,5 +1013,13 @@ namespace NLGUI void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { } + + void CCtrlTextButton::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + if( _ViewText != NULL ) + _ViewText->updateCoords(); + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 54b180ef1..5b51fcb6b 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,9 +2633,7 @@ namespace NLGUI sint32 dx = newX - oldX; sint32 dy = newY - oldY; - draggedElement->setXReal( draggedElement->getXReal() + dx ); - draggedElement->setYReal( draggedElement->getYReal() + dy ); - draggedElement->invalidateCoords(); + draggedElement->moveBy( dx, dy ); } } From 22d9accae616b7bf2c655d148c7454e84a39d9bd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:54:44 +0200 Subject: [PATCH 184/240] When moving a widget, save the reference to the hierarchy lookup map... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_hierarchy.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index d52f55e27..5605d6439 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -279,13 +279,15 @@ namespace GUIEditor // Remove reference to old item widgetHierarchyMap.erase( oldid ); - + // Add new item item = new QTreeWidgetItem(); item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - + + // Add reference to new item + widgetHierarchyMap[ newid ] = item; selectItem( item ); } From 2603ad3a2ba040e2ee2ffbc1fe1606553c10b95b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 21:48:51 +0200 Subject: [PATCH 185/240] Refactoring. Added CInterfaceFactory. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_factory.h | 35 ++++++++++++++++++++ code/nel/src/gui/ctrl_text_button.cpp | 3 +- code/nel/src/gui/group_editbox.cpp | 3 +- code/nel/src/gui/interface_factory.cpp | 29 ++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 code/nel/include/nel/gui/interface_factory.h create mode 100644 code/nel/src/gui/interface_factory.cpp diff --git a/code/nel/include/nel/gui/interface_factory.h b/code/nel/include/nel/gui/interface_factory.h new file mode 100644 index 000000000..bd7f8352a --- /dev/null +++ b/code/nel/include/nel/gui/interface_factory.h @@ -0,0 +1,35 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef IFACE_FACTORY +#define IFACE_FACTORY + +#include + +namespace NLGUI +{ + class CViewBase; + + /// Simple interface element ( widget ) factory + class CInterfaceFactory + { + public: + static CViewBase* createClass( const std::string &name ); + }; +} + + +#endif diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index 03db2b797..a3a10d93e 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -23,6 +23,7 @@ #include "nel/gui/group_container_base.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/widget_manager.h" +#include "nel/gui/interface_factory.h" #include "nel/misc/i18n.h" using namespace std; @@ -904,7 +905,7 @@ namespace NLGUI if( _ViewText == NULL ) { - CViewBase *v = CWidgetManager::getInstance()->getParser()->createClass( "text" ); + CViewBase *v = CInterfaceFactory::createClass( "text" ); nlassert( v != NULL ); _ViewText = dynamic_cast< CViewText* >( v ); _ViewText->setId( _Id + "_text" ); diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index c18c69134..ba65a07c4 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -27,6 +27,7 @@ #include "nel/gui/widget_manager.h" #include "nel/gui/view_renderer.h" #include "nel/gui/db_manager.h" +#include "nel/gui/interface_factory.h" #include using namespace std; @@ -1543,7 +1544,7 @@ namespace NLGUI if( editorMode ) { nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() ); - _ViewText = dynamic_cast< CViewText* >( CWidgetManager::getInstance()->getParser()->createClass( "text" ) ); + _ViewText = dynamic_cast< CViewText* >( CInterfaceFactory::createClass( "text" ) ); if( _ViewText != NULL ) { _ViewText->setParent( this ); diff --git a/code/nel/src/gui/interface_factory.cpp b/code/nel/src/gui/interface_factory.cpp new file mode 100644 index 000000000..ec914baa6 --- /dev/null +++ b/code/nel/src/gui/interface_factory.cpp @@ -0,0 +1,29 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "nel/gui/interface_factory.h" +#include "nel/gui/view_base.h" +#include "nel/misc/factory.h" + +namespace NLGUI +{ + CViewBase* CInterfaceFactory::createClass( const std::string &name ) + { + return NLMISC_GET_FACTORY( CViewBase, std::string ).createObject( std::string( name ) , CViewBase::TCtorParam() ); + } +} + + From 86007c9156b50455d7140a3c13e49ebc56fa354c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:23:22 +0200 Subject: [PATCH 186/240] Posref changes in the editor should apply... --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 4 ++-- code/nel/src/gui/widget_manager.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 0225d2797..981d93a9b 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -226,13 +226,13 @@ namespace NLGUI else if( name == "posref" ) { - convertHotSpot( value.c_str() ); + _PosRef = convertHotSpot( value.c_str() ); return; } else if( name == "parentposref" ) { - convertHotSpot( value.c_str() ); + _ParentPosRef = convertHotSpot( value.c_str() ); } else if( name == "sizeref" ) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b51fcb6b..92b94b112 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,6 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); + //e->setName( "==MARKED==" ); + draggedElement = NULL; onWidgetMoved( oldid, e->getId() ); From 4571038fa665c8000e00f6ee04f1914139baf18c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:38:24 +0200 Subject: [PATCH 187/240] Update CCtrlTextButton's CViewText's coords after updating it's own coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/ctrl_text_button.cpp | 5 ++++- code/nel/src/gui/widget_manager.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index a3a10d93e..cdf9ea0d2 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -875,7 +875,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); - _ViewText->updateCoords(); + if( _Name == "==MARKED==" ) + bool marked = true; // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) @@ -890,6 +891,8 @@ namespace NLGUI } CViewBase::updateCoords(); + + _ViewText->updateCoords(); } // *************************************************************************** diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 92b94b112..65c3e101e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,7 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - //e->setName( "==MARKED==" ); + e->setName( "==MARKED==" ); draggedElement = NULL; From d2587df8c14cb748e7ff1031ce59ef2dd3ba0b46 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 20:29:04 +0200 Subject: [PATCH 188/240] From now on dragged widgets will be re-aligned on drop. They will find the nearest hotspot of the group they are dropped into, and calculate an offset so they will align to the hotspot and yet remain where they were dropped. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 9 ++ code/nel/src/gui/interface_element.cpp | 91 ++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 048ec4b6e..3b095ac85 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -518,6 +518,15 @@ namespace NLGUI _YReal += y; } + /// Retrieves the coordinates of the specified hotspot + void getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const; + + /// Tells which hotspot is the closest to the specified element + void getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ); + + /// Aligns the element to the other element specified + void alignTo( CInterfaceElement *other ); + protected: bool editorSelected; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 981d93a9b..75fee53f2 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1594,6 +1594,97 @@ namespace NLGUI } } + void CInterfaceElement::getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const + { + x = _XReal; + y = _YReal; + + if( ( hs & Hotspot_Mx ) != 0 ) + y += _HReal / 2; + else + if( ( hs & Hotspot_Tx ) != 0 ) + y += _HReal; + + + if( ( hs & Hotspot_xM ) != 0 ) + x += _WReal / 2; + else + if( ( hs & Hotspot_xR ) != 0 ) + x += _WReal; + } + + void CInterfaceElement::getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ) + { + /// Iterate over the following hotspots, calculate the distance and store the closest + + + static THotSpot hslist[] = + { + Hotspot_BL, + Hotspot_BR, + Hotspot_MM, + Hotspot_TL, + Hotspot_TR + }; + + int c = sizeof( hslist ) / sizeof( THotSpot ); + + int x,y,ox,oy,vx,vy; + float d; + float closestd = 9999999.0f; + THotSpot closestHS = Hotspot_TR; + + for( int i = 0; i < c; i++ ) + { + other->getHSCoords( hslist[ i ], ox, oy ); + getHSCoords( hslist[ i ], x, y ); + + // Make a vector between the two hotspots + vx = x - ox; + vy = y - oy; + + // Calculate length + d = sqrt( pow( vx, 2.0f ) + pow( vy, 2.0f ) ); + + // If these hotspots are the closest, store the hotspot + if( d < closestd ) + { + closestd = d; + closestHS = hslist[ i ]; + } + } + + hs = closestHS; + } + + void CInterfaceElement::alignTo( CInterfaceElement *other ) + { + if( other == this ) + return; + + // Check which hotspot is the closest + THotSpot hs; + other->getClosestHotSpot( this, hs ); + + // Get the hotspot coordinates + sint32 x, y, ox, oy; + getHSCoords( hs, x, y ); + other->getHSCoords( hs, ox, oy ); + + // Calculate the difference between the hotspot we found and our current position, + sint32 dx = ox - x; + sint32 dy = oy - y; + + // This difference is our offset, so we remain in the same position + setX( -1 * dx ); + setY( -1 * dy ); + + setPosRef( hs ); + setParentPosRef( hs ); + + invalidateCoords(); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 65c3e101e..ec22798fb 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - e->setName( "==MARKED==" ); + e->alignTo( g ); + //e->setName( "==MARKED==" ); draggedElement = NULL; From 3e209147b078c149a8de5a0599127da0c2e4afea Mon Sep 17 00:00:00 2001 From: nimetu Date: Tue, 30 Sep 2014 11:16:28 +0000 Subject: [PATCH 189/240] static libxml2 under linux requires lzma (tested on fedora/debian) --HG-- branch : nimetu/static-libxml2-under-linux-requires-lzma-1412075714030 --- code/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 071554e06..e0f3fe7ba 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -110,6 +110,10 @@ FIND_PACKAGE(Jpeg) IF(WITH_STATIC_LIBXML2) SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) + IF(NOT WIN32 AND NOT APPLE) + FIND_PACKAGE(LibLZMA REQUIRED) + SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) + ENDIF(NOT WIN32 AND NOT APPLE) ENDIF(WITH_STATIC_LIBXML2) IF(WITH_STATIC) From dcf2906b94555b4e6d74b3a824d7a5239ec0248f Mon Sep 17 00:00:00 2001 From: nimetu Date: Tue, 30 Sep 2014 11:23:16 +0000 Subject: [PATCH 190/240] find lua version for luabind under fedora --HG-- branch : nimetu/find-lua-version-for-luabind-under-fedor-1412076128442 --- code/CMakeModules/FindLuabind.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/CMakeModules/FindLuabind.cmake b/code/CMakeModules/FindLuabind.cmake index f61885be8..14f67ce44 100644 --- a/code/CMakeModules/FindLuabind.cmake +++ b/code/CMakeModules/FindLuabind.cmake @@ -11,6 +11,12 @@ MACRO(FIND_CORRECT_LUA_VERSION) SET(LUA52_LIBRARY "liblua5.2") CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA52_LIBRARY LUALIB_FOUND) + + IF(NOT LUALIB_FOUND) + # fedora (v20) + SET(LUA52_LIBRARY "liblua-5.2") + CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA52_LIBRARY LUALIB_FOUND) + ENDIF(NOT LUALIB_FOUND) IF(LUALIB_FOUND) MESSAGE(STATUS "Luabind is using Lua 5.2") From 65b902970a5a0e6547adad1cdf45c41f5c75d779 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Fri, 26 Sep 2014 22:30:56 +0200 Subject: [PATCH 191/240] ref #206 : rolling back to include a crypt(3) implementation and adding sha512 support --HG-- branch : sha512-auth --- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/common/src/game_share/ccrypt.cpp | 30 - code/ryzom/common/src/game_share/crypt.cpp | 985 ++++++++++++++++++ .../src/game_share/{ccrypt.h => crypt.h} | 0 .../common/src/game_share/crypt_sha512.cpp | 371 +++++++ .../src/monitor_service/service_main.cpp | 2 +- 6 files changed, 1358 insertions(+), 32 deletions(-) delete mode 100644 code/ryzom/common/src/game_share/ccrypt.cpp create mode 100644 code/ryzom/common/src/game_share/crypt.cpp rename code/ryzom/common/src/game_share/{ccrypt.h => crypt.h} (100%) create mode 100644 code/ryzom/common/src/game_share/crypt_sha512.cpp diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 673a5b5f4..091e24a80 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -57,7 +57,7 @@ #include "release.h" #include "bg_downloader_access.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "game_share/bg_downloader_msg.h" #include "misc.h" diff --git a/code/ryzom/common/src/game_share/ccrypt.cpp b/code/ryzom/common/src/game_share/ccrypt.cpp deleted file mode 100644 index ea67cf7d6..000000000 --- a/code/ryzom/common/src/game_share/ccrypt.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" - -#include "ccrypt.h" - -#define _GNU_SOURCE 1 -#include - -// Crypts password using salt -std::string CCrypt::crypt(const std::string& password, const std::string& salt) -{ - std::string result = ::crypt(password.c_str(), salt.c_str()); - - return result; -} diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp new file mode 100644 index 000000000..881b42f1e --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -0,0 +1,985 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdpch.h" + +#include "crypt.h" + +char * rz_crypt(register const char *key, register const char *setting); +char *__crypt_sha512(const char *key, const char *setting, char *output); + + +// Crypts password using salt +std::string CCrypt::crypt(const std::string& password, const std::string& salt) +{ + std::string result = ::rz_crypt(password.c_str(), salt.c_str()); + + return result; +} + + + + + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Tom Truscott. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rz_sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* #include */ +#include +#include +#define RZ__PASSWORD_EFMT1 '-' + +#if DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows); +#endif + +/* + * UNIX password, and DES, encryption. + * By Tom Truscott, trt@rti.rti.org, + * from algorithms by Robert W. Baldwin and James Gillogly. + * + * References: + * "Mathematical Cryptology for Computer Scientists and Mathematicians," + * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. + * + * "Password Security: A Case History," R. Morris and Ken Thompson, + * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. + * + * "DES will be Totally Insecure within Ten Years," M.E. Hellman, + * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. + */ + +/* ===== Configuration ==================== */ + +/* + * define "MUST_ALIGN" if your compiler cannot load/store + * long integers at arbitrary (e.g. odd) memory locations. + * (Either that or never pass unaligned addresses to des_cipher!) + */ +#if !defined(vax) +#define MUST_ALIGN +#endif + +#ifdef CHAR_BITS +#if CHAR_BITS != 8 + #error C_block structure assumes 8 bit characters +#endif +#endif + +/* + * define "LONG_IS_32_BITS" only if sizeof(long)==4. + * This avoids use of bit fields (your compiler may be sloppy with them). + */ +#if !defined(cray) && !defined(__LP64__) && !defined(_LP64) +#define LONG_IS_32_BITS +#endif + +/* + * define "B64" to be the declaration for a 64 bit integer. + * XXX this feature is currently unused, see "endian" comment below. + */ +#if defined(cray) || defined(__LP64__) || defined(_LP64) +#define B64 long +#endif +#if defined(convex) +#define B64 long long +#endif + +/* + * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes + * of lookup tables. This speeds up des_setkey() and des_cipher(), but has + * little effect on crypt(). + */ +#if defined(notdef) +#define LARGEDATA +#endif + +/* ==================================== */ + +/* + * Cipher-block representation (Bob Baldwin): + * + * DES operates on groups of 64 bits, numbered 1..64 (sigh). One + * representation is to store one bit per byte in an array of bytes. Bit N of + * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. + * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the + * first byte, 9..16 in the second, and so on. The DES spec apparently has + * bit 1 in the MSB of the first byte, but that is particularly noxious so we + * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is + * the MSB of the first byte. Specifically, the 64-bit input data and key are + * converted to LSB format, and the output 64-bit block is converted back into + * MSB format. + * + * DES operates internally on groups of 32 bits which are expanded to 48 bits + * by permutation E and shrunk back to 32 bits by the S boxes. To speed up + * the computation, the expansion is applied only once, the expanded + * representation is maintained during the encryption, and a compression + * permutation is applied only at the end. To speed up the S-box lookups, + * the 48 bits are maintained as eight 6 bit groups, one per byte, which + * directly feed the eight S-boxes. Within each byte, the 6 bits are the + * most significant ones. The low two bits of each byte are zero. (Thus, + * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the + * first byte in the eight byte representation, bit 2 of the 48 bit value is + * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is + * used, in which the output is the 64 bit result of an S-box lookup which + * has been permuted by P and expanded by E, and is ready for use in the next + * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this + * lookup. Since each byte in the 48 bit path is a multiple of four, indexed + * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and + * "salt" are also converted to this 8*(6+2) format. The SPE table size is + * 8*64*8 = 4K bytes. + * + * To speed up bit-parallel operations (such as XOR), the 8 byte + * representation is "union"ed with 32 bit values "i0" and "i1", and, on + * machines which support it, a 64 bit value "b64". This data structure, + * "C_block", has two problems. First, alignment restrictions must be + * honored. Second, the byte-order (e.g. little-endian or big-endian) of + * the architecture becomes visible. + * + * The byte-order problem is unfortunate, since on the one hand it is good + * to have a machine-independent C_block representation (bits 1..8 in the + * first byte, etc.), and on the other hand it is good for the LSB of the + * first byte to be the LSB of i0. We cannot have both these things, so we + * currently use the "little-endian" representation and avoid any multi-byte + * operations that depend on byte order. This largely precludes use of the + * 64-bit datatype since the relative order of i0 and i1 are unknown. It + * also inhibits grouping the SPE table to look up 12 bits at a time. (The + * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 + * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the + * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup + * requires a 128 kilobyte table, so perhaps this is not a big loss. + * + * Permutation representation (Jim Gillogly): + * + * A transformation is defined by its effect on each of the 8 bytes of the + * 64-bit input. For each byte we give a 64-bit output that has the bits in + * the input distributed appropriately. The transformation is then the OR + * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for + * each transformation. Unless LARGEDATA is defined, however, a more compact + * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. + * The smaller table uses 16*16*8 = 2K bytes for each transformation. This + * is slower but tolerable, particularly for password encryption in which + * the SPE transformation is iterated many times. The small tables total 9K + * bytes, the large tables total 72K bytes. + * + * The transformations used are: + * IE3264: MSB->LSB conversion, initial permutation, and expansion. + * This is done by collecting the 32 even-numbered bits and applying + * a 32->64 bit transformation, and then collecting the 32 odd-numbered + * bits and applying the same transformation. Since there are only + * 32 input bits, the IE3264 transformation table is half the size of + * the usual table. + * CF6464: Compression, final permutation, and LSB->MSB conversion. + * This is done by two trivial 48->32 bit compressions to obtain + * a 64-bit block (the bit numbering is given in the "CIFP" table) + * followed by a 64->64 bit "cleanup" transformation. (It would + * be possible to group the bits in the 64-bit block so that 2 + * identical 32->32 bit transformations could be used instead, + * saving a factor of 4 in space and possibly 2 in time, but + * byte-ordering and other complications rear their ugly head. + * Similar opportunities/problems arise in the key schedule + * transforms.) + * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. + * This admittedly baroque 64->64 bit transformation is used to + * produce the first code (in 8*(6+2) format) of the key schedule. + * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. + * It would be possible to define 15 more transformations, each + * with a different rotation, to generate the entire key schedule. + * To save space, however, we instead permute each code into the + * next by using a transformation that "undoes" the PC2 permutation, + * rotates the code, and then applies PC2. Unfortunately, PC2 + * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not + * invertible. We get around that problem by using a modified PC2 + * which retains the 8 otherwise-lost bits in the unused low-order + * bits of each byte. The low-order bits are cleared when the + * codes are stored into the key schedule. + * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. + * This is faster than applying PC2ROT[0] twice, + * + * The Bell Labs "salt" (Bob Baldwin): + * + * The salting is a simple permutation applied to the 48-bit result of E. + * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and + * i+24 of the result are swapped. The salt is thus a 24 bit number, with + * 16777216 possible values. (The original salt was 12 bits and could not + * swap bits 13..24 with 36..48.) + * + * It is possible, but ugly, to warp the SPE table to account for the salt + * permutation. Fortunately, the conditional bit swapping requires only + * about four machine instructions and can be done on-the-fly with about an + * 8% performance penalty. + */ + +typedef union { + unsigned char b[8]; + struct { +#if defined(LONG_IS_32_BITS) + /* long is often faster than a 32-bit bit field */ + long i0; + long i1; +#else + long i0: 32; + long i1: 32; +#endif + } b32; +#if defined(B64) + B64 b64; +#endif +} C_block; + +/* + * Convert twenty-four-bit long in host-order + * to six bits (and 2 low-order zeroes) per char little-endian format. + */ +#define TO_SIX_BIT(rslt, src) { \ + C_block cvt; \ + cvt.b[0] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[1] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[2] = (unsigned char) (src&0xFF); src >>= 6; \ + cvt.b[3] = (unsigned char) (src&0xFF); \ + rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ + } + +/* + * These macros may someday permit efficient use of 64-bit integers. + */ +#define ZERO(d,d0,d1) d0 = 0, d1 = 0 +#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 +#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 +#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 +#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 +#define DCL_BLOCK(d,d0,d1) long d0, d1 + +#if defined(LARGEDATA) + /* Waste memory like crazy. Also, do permutations in line */ +#define LGCHUNKBITS 3 +#define CHUNKBITS (1<>4]; OR(D,D0,D1,*tp); p += (1< 0); + STORE(D,D0,D1,*out); +} +#endif /* LARGEDATA */ + + +/* ===== (mostly) Standard DES Tables ==================== */ + +static unsigned char IP[] = { /* initial permutation */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* The final permutation is the inverse of IP - no table is necessary */ + +static unsigned char ExpandTr[] = { /* expansion operation */ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +static unsigned char PC1[] = { /* permuted choice table 1 */ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +static unsigned char Rotates[] = { /* PC1 rotation schedule */ + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* note: each "row" of PC2 is left-padded with bits that make it invertible */ +static unsigned char PC2[] = { /* permuted choice table 2 */ + 9, 18, 14, 17, 11, 24, 1, 5, + 22, 25, 3, 28, 15, 6, 21, 10, + 35, 38, 23, 19, 12, 4, 26, 8, + 43, 54, 16, 7, 27, 20, 13, 2, + + 0, 0, 41, 52, 31, 37, 47, 55, + 0, 0, 30, 40, 51, 45, 33, 48, + 0, 0, 44, 49, 39, 56, 34, 53, + 0, 0, 46, 42, 50, 36, 29, 32, +}; + +static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ + /* S[1] */ + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + /* S[2] */ + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + /* S[3] */ + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + /* S[4] */ + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + /* S[5] */ + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + /* S[6] */ + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + /* S[7] */ + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + /* S[8] */ + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} +}; + +static unsigned char P32Tr[] = { /* 32-bit permutation function */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +static unsigned char CIFP[] = { /* compressed/interleaved permutation */ + 1, 2, 3, 4, 17, 18, 19, 20, + 5, 6, 7, 8, 21, 22, 23, 24, + 9, 10, 11, 12, 25, 26, 27, 28, + 13, 14, 15, 16, 29, 30, 31, 32, + + 33, 34, 35, 36, 49, 50, 51, 52, + 37, 38, 39, 40, 53, 54, 55, 56, + 41, 42, 43, 44, 57, 58, 59, 60, + 45, 46, 47, 48, 61, 62, 63, 64, +}; + +static unsigned char itoa64[] = /* 0..63 => ascii-64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + +/* ===== Tables that are initialized at run time ==================== */ + + +static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ + +/* Initial key schedule permutation */ +static C_block PC1ROT[64/CHUNKBITS][1< final permutation table */ +static C_block CF6464[64/CHUNKBITS][1<= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + num_iter = (num_iter<<6) | a64toi[t]; + } + setting += 4; + encp += 4; + salt_size = 4; + break; + default: + num_iter = 25; + salt_size = 2; + } + + salt = 0; + for (i = salt_size; --i >= 0; ) { + if ((t = (unsigned char)setting[i]) == '\0') + t = '.'; + encp[i] = t; + salt = (salt<<6) | a64toi[t]; + } + encp += salt_size; + if (rz_des_cipher((char *)&constdatablock, (char *)&rsltblock, + salt, num_iter)) + return (NULL); + + /* + * Encode the 64 cipher bits as 11 ascii characters. + */ + i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; + encp[3] = itoa64[i&0x3f]; i >>= 6; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; encp += 4; + i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; + encp[2] = itoa64[i&0x3f]; i >>= 6; + encp[1] = itoa64[i&0x3f]; i >>= 6; + encp[0] = itoa64[i]; + + encp[3] = 0; + + return (cryptresult); +} + + +/* + * The Key Schedule, filled in by des_setkey() or setkey(). + */ +#define KS_SIZE 16 +static C_block KS[KS_SIZE]; + +/* + * Set up the key schedule from the key. + */ +int rz_des_setkey(register const char *key) { + register DCL_BLOCK(K, K0, K1); + register C_block *ptabp; + register int i; + static int des_ready = 0; + + if (!des_ready) { + rz_init_des(); + des_ready = 1; + } + + PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); + key = (char *)&KS[0]; + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + for (i = 1; i < 16; i++) { + key += sizeof(C_block); + STORE(K,K0,K1,*(C_block *)key); + ptabp = (C_block *)PC2ROT[Rotates[i]-1]; + PERM6464(K,K0,K1,(unsigned char *)key,ptabp); + STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); + } + return (0); +} + +/* + * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) + * iterations of DES, using the given 24-bit salt and the pre-computed key + * schedule, and store the resulting 8 chars at "out" (in == out is permitted). + * + * NOTE: the performance of this routine is critically dependent on your + * compiler and machine architecture. + */ +int rz_des_cipher(const char *in, char *out, long salt, int num_iter) { + /* variables that we want in registers, most important first */ +#if defined(pdp11) + register int j; +#endif + register long L0, L1, R0, R1, k; + register C_block *kp; + register int ks_inc, loop_count; + C_block B; + + L0 = salt; + TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ + +#if defined(vax) || defined(pdp11) + salt = ~salt; /* "x &~ y" is faster than "x & y". */ +#define SALT (~salt) +#else +#define SALT salt +#endif + +#if defined(MUST_ALIGN) + B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; + B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; + LOAD(L,L0,L1,B); +#else + LOAD(L,L0,L1,*(C_block *)in); +#endif + LOADREG(R,R0,R1,L,L0,L1); + L0 &= 0x55555555L; + L1 &= 0x55555555L; + L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ + R0 &= 0xaaaaaaaaL; + R1 = (R1 >> 1) & 0x55555555L; + L1 = R0 | R1; /* L1 is the odd-numbered input bits */ + STORE(L,L0,L1,B); + PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ + PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ + + if (num_iter >= 0) + { /* encryption */ + kp = &KS[0]; + ks_inc = sizeof(*kp); + } + else + { /* decryption */ + num_iter = -num_iter; + kp = &KS[KS_SIZE-1]; + ks_inc = -((int) sizeof(*kp)); + } + + while (--num_iter >= 0) { + loop_count = 8; + do { + +#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) +#if defined(gould) + /* use this if B.b[i] is evaluated just once ... */ +#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); +#else +#if defined(pdp11) + /* use this if your "long" int indexing is slow */ +#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); +#else + /* use this if "k" is allocated to a register ... */ +#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); +#endif +#endif + +#define CRUNCH(p0, p1, q0, q1) \ + k = (q0 ^ q1) & SALT; \ + B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ + B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ + kp = (C_block *)((char *)kp+ks_inc); \ + \ + DOXOR(p0, p1, 0); \ + DOXOR(p0, p1, 1); \ + DOXOR(p0, p1, 2); \ + DOXOR(p0, p1, 3); \ + DOXOR(p0, p1, 4); \ + DOXOR(p0, p1, 5); \ + DOXOR(p0, p1, 6); \ + DOXOR(p0, p1, 7); + + CRUNCH(L0, L1, R0, R1); + CRUNCH(R0, R1, L0, L1); + } while (--loop_count != 0); + kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); + + + /* swap L and R */ + L0 ^= R0; L1 ^= R1; + R0 ^= L0; R1 ^= L1; + L0 ^= R0; L1 ^= R1; + } + + /* store the encrypted (or decrypted) result */ + L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); + L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); + STORE(L,L0,L1,B); + PERM6464(L,L0,L1,B.b, (C_block *)CF6464); +#if defined(MUST_ALIGN) + STORE(L,L0,L1,B); + out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; + out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; +#else + STORE(L,L0,L1,*(C_block *)out); +#endif + return (0); +} + + +/* + * Initialize various tables. This need only be done once. It could even be + * done at compile time, if the compiler were capable of that sort of thing. + */ +/* STATIC */void rz_init_des() { + register int i, j; + register long k; + register int tableno; + static unsigned char perm[64], tmp32[32]; /* "static" for speed */ + + /* + * table that converts chars "./0-9A-Za-z"to integers 0-63. + */ + for (i = 0; i < 64; i++) + a64toi[itoa64[i]] = i; + + /* + * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. + */ + for (i = 0; i < 64; i++) + perm[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += Rotates[0]-1; + if ((k%28) < Rotates[0]) k -= 28; + k = PC1[k]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i] = (unsigned char) k; + } +#ifdef DEBUG_CRYPT + prtab("pc1tab", perm, 8); +#endif + rz_init_perm(PC1ROT, perm, 8, 8); + + /* + * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. + */ + for (j = 0; j < 2; j++) { + unsigned char pc2inv[64]; + for (i = 0; i < 64; i++) + perm[i] = pc2inv[i] = 0; + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + pc2inv[k-1] = i+1; + } + for (i = 0; i < 64; i++) { + if ((k = PC2[i]) == 0) + continue; + k += j; + if ((k%28) <= j) k -= 28; + perm[i] = pc2inv[k]; + } +#ifdef DEBUG_CRYPT + prtab("pc2tab", perm, 8); +#endif + rz_init_perm(PC2ROT[j], perm, 8, 8); + } + + /* + * Bit reverse, then initial permutation, then expansion. + */ + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; + if (k > 32) + k -= 32; + else if (k > 0) + k--; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[i*8+j] = (unsigned char) k; + } + } +#ifdef DEBUG_CRYPT + prtab("ietab", perm, 8); +#endif + rz_init_perm(IE3264, perm, 4, 8); + + /* + * Compression, then final permutation, then bit reverse. + */ + for (i = 0; i < 64; i++) { + k = IP[CIFP[i]-1]; + if (k > 0) { + k--; + k = (k|07) - (k&07); + k++; + } + perm[k-1] = i+1; + } +#ifdef DEBUG_CRYPT + prtab("cftab", perm, 8); +#endif + rz_init_perm(CF6464, perm, 8, 8); + + /* + * SPE table + */ + for (i = 0; i < 48; i++) + perm[i] = P32Tr[ExpandTr[i]-1]; + for (tableno = 0; tableno < 8; tableno++) { + for (j = 0; j < 64; j++) { + k = (((j >> 0) &01) << 5)| + (((j >> 1) &01) << 3)| + (((j >> 2) &01) << 2)| + (((j >> 3) &01) << 1)| + (((j >> 4) &01) << 0)| + (((j >> 5) &01) << 4); + k = S[tableno][k]; + k = (((k >> 3)&01) << 0)| + (((k >> 2)&01) << 1)| + (((k >> 1)&01) << 2)| + (((k >> 0)&01) << 3); + for (i = 0; i < 32; i++) + tmp32[i] = 0; + for (i = 0; i < 4; i++) + tmp32[4 * tableno + i] = (unsigned char)((k >> i) & 01); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i]-1]; + TO_SIX_BIT(SPE[0][tableno][j], k); + k = 0; + for (i = 24; --i >= 0; ) + k = (k<<1) | tmp32[perm[i+24]-1]; + TO_SIX_BIT(SPE[1][tableno][j], k); + } + } +} + +/* + * Initialize "perm" to represent transformation "p", which rearranges + * (perhaps with expansion and/or contraction) one packed array of bits + * (of size "chars_in" characters) into another array (of size "chars_out" + * characters). + * + * "perm" must be all-zeroes on entry to this routine. + */ +/* STATIC */void rz_init_perm(C_block perm[64/CHUNKBITS][1<>LGCHUNKBITS; /* which chunk this bit comes from */ + l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ + for (j = 0; j < (1<>3] |= 1<<(k&07); + } + } +} + +/* + * "setkey" routine (for backwards compatibility) + */ +int rz_setkey(register const char *key) { + register int i, j, k; + C_block keyblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*key++; + } + keyblock.b[i] = k; + } + return (rz_des_setkey((char *)keyblock.b)); +} + +/* + * "encrypt" routine (for backwards compatibility) + */ +int rz_encrypt(register char *block, int flag) { + register int i, j, k; + C_block cblock; + + for (i = 0; i < 8; i++) { + k = 0; + for (j = 0; j < 8; j++) { + k <<= 1; + k |= (unsigned char)*block++; + } + cblock.b[i] = k; + } + if (rz_des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) + return (1); + for (i = 7; i >= 0; i--) { + k = cblock.b[i]; + for (j = 7; j >= 0; j--) { + *--block = k&01; + k >>= 1; + } + } + return (0); +} + +#ifdef DEBUG_CRYPT +void prtab(char *s, unsigned char *t, int num_rows) +{ + register int i, j; + + (void)printf("%s:\n", s); + for (i = 0; i < num_rows; i++) { + for (j = 0; j < 8; j++) { + (void)printf("%3d", t[i*8+j]); + } + (void)printf("\n"); + } + (void)printf("\n"); +} +#endif diff --git a/code/ryzom/common/src/game_share/ccrypt.h b/code/ryzom/common/src/game_share/crypt.h similarity index 100% rename from code/ryzom/common/src/game_share/ccrypt.h rename to code/ryzom/common/src/game_share/crypt.h diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp new file mode 100644 index 000000000..c12359485 --- /dev/null +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -0,0 +1,371 @@ +/* + * public domain sha512 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha512 implementation based on fips180-3 */ +/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ + +struct sha512 { + uint64_t len; /* processed message length */ + uint64_t h[8]; /* hash state */ + uint8_t buf[128]; /* message block buffer */ +}; + +static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) +#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) +#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) +#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) + +static const uint64_t K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +static void processblock(struct sha512 *s, const uint8_t *buf) +{ + uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint64_t)buf[8*i]<<56; + W[i] |= (uint64_t)buf[8*i+1]<<48; + W[i] |= (uint64_t)buf[8*i+2]<<40; + W[i] |= (uint64_t)buf[8*i+3]<<32; + W[i] |= (uint64_t)buf[8*i+4]<<24; + W[i] |= (uint64_t)buf[8*i+5]<<16; + W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] |= buf[8*i+7]; + } + for (; i < 80; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 80; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha512 *s) +{ + unsigned r = s->len % 128; + + s->buf[r++] = 0x80; + if (r > 112) { + memset(s->buf + r, 0, 128 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 120 - r); + s->len *= 8; + s->buf[120] = s->len >> 56; + s->buf[121] = s->len >> 48; + s->buf[122] = s->len >> 40; + s->buf[123] = s->len >> 32; + s->buf[124] = s->len >> 24; + s->buf[125] = s->len >> 16; + s->buf[126] = s->len >> 8; + s->buf[127] = s->len; + processblock(s, s->buf); +} + +static void sha512_init(struct sha512 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667f3bcc908ULL; + s->h[1] = 0xbb67ae8584caa73bULL; + s->h[2] = 0x3c6ef372fe94f82bULL; + s->h[3] = 0xa54ff53a5f1d36f1ULL; + s->h[4] = 0x510e527fade682d1ULL; + s->h[5] = 0x9b05688c2b3e6c1fULL; + s->h[6] = 0x1f83d9abfb41bd6bULL; + s->h[7] = 0x5be0cd19137e2179ULL; +} + +static void sha512_sum(struct sha512 *s, uint8_t *md) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[8*i] = s->h[i] >> 56; + md[8*i+1] = s->h[i] >> 48; + md[8*i+2] = s->h[i] >> 40; + md[8*i+3] = s->h[i] >> 32; + md[8*i+4] = s->h[i] >> 24; + md[8*i+5] = s->h[i] >> 16; + md[8*i+6] = s->h[i] >> 8; + md[8*i+7] = s->h[i]; + } +} + +static void sha512_update(struct sha512 *s, const void *m, unsigned long len) +{ + const uint8_t *p = (uint8_t *)m; + unsigned r = s->len % 128; + + s->len += len; + if (r) { + if (len < 128 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 128 - r); + len -= 128 - r; + p += 128 - r; + processblock(s, s->buf); + } + for (; len >= 128; len -= 128, p += 128) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static const unsigned char b64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 9999999 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha512 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 64; i -= 64) + sha512_update(s, md, 64); + sha512_update(s, md, i); +} + +static char *sha512crypt(const char *key, const char *setting, char *output) +{ + struct sha512 ctx; + unsigned char md[64], kmd[64], smd[64]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + for (i = 0; i <= KEY_MAX && key[i]; i++); + if (i > KEY_MAX) + return 0; + klen = i; + + /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$6$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha512_update(&ctx, md, sizeof md); + else + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha512_init(&ctx); + for (i = 0; i < klen; i++) + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha512_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha512_update(&ctx, salt, slen); + sha512_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha512_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha512_update(&ctx, md, sizeof md); + if (i % 3) + sha512_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha512_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha512_sum(&ctx, md); + } + + /* output is $6$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); +#if 1 + static const unsigned char perm[][3] = { + 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, + 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, + 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, + 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, + 62,20,41 }; + for (i=0; i<21; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); +#else + p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); + p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); + p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); + p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); + p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); + p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); + p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); + p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); + p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); + p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); + p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); + p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); + p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); + p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); + p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); + p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); + p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); + p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); + p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); + p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); + p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); +#endif + p = to64(p, md[63], 2); + *p = 0; + return output; +} + +char *__crypt_sha512(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; + static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; + char testbuf[128]; + char *p, *q; + + p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha512crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/code/ryzom/server/src/monitor_service/service_main.cpp b/code/ryzom/server/src/monitor_service/service_main.cpp index aa559b78d..84bbcbe86 100644 --- a/code/ryzom/server/src/monitor_service/service_main.cpp +++ b/code/ryzom/server/src/monitor_service/service_main.cpp @@ -20,7 +20,7 @@ #include "game_share/tick_event_handler.h" #include "game_share/ryzom_version.h" -#include "game_share/ccrypt.h" +#include "game_share/crypt.h" #include "nel/misc/time_nl.h" #include "client.h" From bb9d0d91d3979dc859210a1ac697820a39f0b34d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 1 Oct 2014 23:24:56 +0200 Subject: [PATCH 192/240] Fix #207, FXAA orientation under D3D --HG-- branch : develop --- code/nel/src/3d/fxaa.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/fxaa.cpp b/code/nel/src/3d/fxaa.cpp index f19bcd8b4..89d1c59cd 100644 --- a/code/nel/src/3d/fxaa.cpp +++ b/code/nel/src/3d/fxaa.cpp @@ -148,7 +148,7 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); - if (drv->textureCoordinateAlternativeMode()) + /*if (drv->textureCoordinateAlternativeMode()) { m_QuadUV.Uv0 = CUV(0.f, 1.f); m_QuadUV.Uv1 = CUV(1.f, 1.f); @@ -156,12 +156,12 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_QuadUV.Uv3 = CUV(0.f, 0.f); } else - { + {*/ m_QuadUV.Uv0 = CUV(0.f, 0.f); m_QuadUV.Uv1 = CUV(1.f, 0.f); m_QuadUV.Uv2 = CUV(1.f, 1.f); m_QuadUV.Uv3 = CUV(0.f, 1.f); - } + /*}*/ /*CVertexBuffer &vb = m_VB; vb.clearValueEx(); From 81d5294fc391fa0d8e0c774b0ac89d2e891a6940 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Thu, 2 Oct 2014 18:21:56 +0200 Subject: [PATCH 193/240] ref #206 : removing unused crypt lib reference --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/CMakeLists.txt b/code/ryzom/common/src/game_share/CMakeLists.txt index cbccfd6dd..2648416ec 100644 --- a/code/ryzom/common/src/game_share/CMakeLists.txt +++ b/code/ryzom/common/src/game_share/CMakeLists.txt @@ -30,7 +30,7 @@ NL_TARGET_LIB(ryzom_gameshare ${PRIV_H} ${SRC} ${R2}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${NEL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges crypt ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) +TARGET_LINK_LIBRARIES(ryzom_gameshare nelmisc nelnet nelligo nelgeorges ${LIBXML2_LIBRARIES} ${ZLIB_LIBRARIES}) NL_DEFAULT_PROPS(ryzom_gameshare "Ryzom, Library: Game Share") NL_ADD_RUNTIME_FLAGS(ryzom_gameshare) NL_ADD_LIB_SUFFIX(ryzom_gameshare) From 4c2be7ea1f4452d26bd5dadb4697d222382e7333 Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Thu, 2 Oct 2014 19:14:25 +0200 Subject: [PATCH 194/240] ref #206 : hacking the types so it may compile on windows --HG-- branch : sha512-auth --- .../common/src/game_share/crypt_sha512.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index c12359485..fef7465de 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -11,18 +11,18 @@ #include #include #include -#include +#include /* public domain sha512 implementation based on fips180-3 */ /* >=2^64 bits messages are not supported (about 2000 peta bytes) */ struct sha512 { - uint64_t len; /* processed message length */ - uint64_t h[8]; /* hash state */ + uint64 len; /* processed message length */ + uint64 h[8]; /* hash state */ uint8_t buf[128]; /* message block buffer */ }; -static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +static uint64 ror(uint64 n, int k) { return (n >> k) | (n << (64-k)); } #define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Maj(x,y,z) ((x & y) | (z & (x | y))) #define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) @@ -30,7 +30,7 @@ static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } #define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) #define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) -static const uint64_t K[80] = { +static const uint64 K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, @@ -55,17 +55,17 @@ static const uint64_t K[80] = { static void processblock(struct sha512 *s, const uint8_t *buf) { - uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + uint64 W[80], t1, t2, a, b, c, d, e, f, g, h; int i; for (i = 0; i < 16; i++) { - W[i] = (uint64_t)buf[8*i]<<56; - W[i] |= (uint64_t)buf[8*i+1]<<48; - W[i] |= (uint64_t)buf[8*i+2]<<40; - W[i] |= (uint64_t)buf[8*i+3]<<32; - W[i] |= (uint64_t)buf[8*i+4]<<24; - W[i] |= (uint64_t)buf[8*i+5]<<16; - W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] = (uint64)buf[8*i]<<56; + W[i] |= (uint64)buf[8*i+1]<<48; + W[i] |= (uint64)buf[8*i+2]<<40; + W[i] |= (uint64)buf[8*i+3]<<32; + W[i] |= (uint64)buf[8*i+4]<<24; + W[i] |= (uint64)buf[8*i+5]<<16; + W[i] |= (uint64)buf[8*i+6]<<8; W[i] |= buf[8*i+7]; } for (; i < 80; i++) From 25f1aa62472ef71e9420aea3477f3ec0904c2d66 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 4 Oct 2014 01:43:13 +0200 Subject: [PATCH 195/240] Fix a bad copy paste in NLGUI --HG-- branch : develop --- code/nel/src/gui/group_container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index c3a7834c5..aace7b0be 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2856,7 +2856,7 @@ namespace NLGUI else rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col); // Right - if (pLayer->Tile_T == 0) // Tiling ? + if (pLayer->Tile_R == 0) // Tiling ? rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, col); else rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col); From 88a9a809a9f5b63f5762f45d9ede00fb39dbbe19 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 4 Oct 2014 01:43:27 +0200 Subject: [PATCH 196/240] Add inset_t parameter to layer options, allows putting header graphics in top texture --HG-- branch : develop --- code/nel/include/nel/gui/interface_options.h | 3 ++- code/nel/src/gui/group_container.cpp | 20 ++++++++++---------- code/nel/src/gui/interface_options.cpp | 1 + 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/gui/interface_options.h b/code/nel/include/nel/gui/interface_options.h index f52b9479a..6501cd2b0 100644 --- a/code/nel/include/nel/gui/interface_options.h +++ b/code/nel/include/nel/gui/interface_options.h @@ -159,7 +159,8 @@ namespace NLGUI sint32 TxId_B_HighLight; sint32 TxId_BR_HighLight; - sint32 HeaderH; + sint32 HeaderH; + sint32 InsetT; // Offset height of top texture }; // *************************************************************************** diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index aace7b0be..80c561f2e 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2373,7 +2373,7 @@ namespace NLGUI { setMaxH(_PopupMaxH); // _W is given by scripter-man - newH = pLayer->H_T; + newH = (pLayer->H_T - pLayer->InsetT); } else { @@ -2382,7 +2382,7 @@ namespace NLGUI _W = _Parent->getW(); } setMaxH (16384); // No scrollbar for container of layer > 0 - newH = pLayer->H_T; + newH = (pLayer->H_T - pLayer->InsetT); } if (_Opened) @@ -2396,11 +2396,11 @@ namespace NLGUI _HeaderOpened->setY (- newH); _HeaderOpened->setW (_W-(pLayer->W_L+pLayer->W_R)); _HeaderOpened->updateCoords(); - newH += max (_HeaderOpened->getHReal(), pLayer->getValSInt32 ("header_h")); + newH += max (_HeaderOpened->getHReal(), pLayer->HeaderH); } else { - newH += pLayer->getValSInt32 ("header_h"); + newH += pLayer->HeaderH; } newH -= (sint32) _ContentYOffset; @@ -2448,12 +2448,12 @@ namespace NLGUI if (_LayerSetup == 0) { // zeH is the height to substract to total height of the container to obtain height of the list - sint32 zeH = pLayer->H_T + pLayer->H_B_Open + pLayer->H_EM_Open; + sint32 zeH = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open + pLayer->H_EM_Open; if (_HeaderOpened != NULL) - zeH += max (_HeaderOpened->getHReal(), pLayer->getValSInt32 ("header_h")); + zeH += max (_HeaderOpened->getHReal(), pLayer->HeaderH); else - zeH += pLayer->getValSInt32 ("header_h"); + zeH += pLayer->HeaderH; if (_Content != NULL) zeH += _Content->getHReal(); @@ -2513,11 +2513,11 @@ namespace NLGUI _HeaderClosed->setY (-newH); _HeaderClosed->setW (_W-(pLayer->W_L+pLayer->W_R)); _HeaderClosed->updateCoords(); - newH += max (_HeaderClosed->getHReal(), pLayer->getValSInt32 ("header_h")); + newH += max (_HeaderClosed->getHReal(), pLayer->HeaderH); } else { - newH += pLayer->getValSInt32 ("header_h"); + newH += pLayer->HeaderH; } newH += pLayer->H_B; @@ -2731,7 +2731,7 @@ namespace NLGUI // h is the size of what is on top of the child list sint32 x, y, w, h; - h = pLayer->H_T + pLayer->H_B_Open; + h = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open; if (_Opened) { diff --git a/code/nel/src/gui/interface_options.cpp b/code/nel/src/gui/interface_options.cpp index 9f70ceeff..70141e0a3 100644 --- a/code/nel/src/gui/interface_options.cpp +++ b/code/nel/src/gui/interface_options.cpp @@ -281,6 +281,7 @@ namespace NLGUI // HeaderH = getValSInt32("header_h"); + InsetT = getValSInt32("inset_t"); return true; } From b98c6f6a5993cb806b96223329fe29abffa59b39 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 01:14:03 +0200 Subject: [PATCH 197/240] Set version --HG-- branch : develop --- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index 2dfdca48e..1c13b7ed1 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "RYZOM CORE" +#define RYZOM_VERSION "ryzomcore/v0.10.0-dev" #endif // RYZOM_VERSION_H From 650dba5c5175b2c487d46b8c3d887fed3ac319c8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 01:20:57 +0200 Subject: [PATCH 198/240] Require setup upgrade --HG-- branch : sha512-auth --- code/web/public_php/setup/version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/web/public_php/setup/version.php b/code/web/public_php/setup/version.php index 476c514f0..baffede3f 100644 --- a/code/web/public_php/setup/version.php +++ b/code/web/public_php/setup/version.php @@ -1,6 +1,6 @@ Date: Tue, 7 Oct 2014 01:44:43 +0200 Subject: [PATCH 199/240] Compile fixes --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/crypt_sha512.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index fef7465de..f3ebc5997 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -7,11 +7,13 @@ * in the salt and rounds= setting must contain a valid iteration count, * on error "*" is returned. */ + +#include + #include #include #include #include -#include /* public domain sha512 implementation based on fips180-3 */ /* >=2^64 bits messages are not supported (about 2000 peta bytes) */ @@ -19,7 +21,7 @@ struct sha512 { uint64 len; /* processed message length */ uint64 h[8]; /* hash state */ - uint8_t buf[128]; /* message block buffer */ + uint8 buf[128]; /* message block buffer */ }; static uint64 ror(uint64 n, int k) { return (n >> k) | (n << (64-k)); } @@ -53,7 +55,7 @@ static const uint64 K[80] = { 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; -static void processblock(struct sha512 *s, const uint8_t *buf) +static void processblock(struct sha512 *s, const uint8 *buf) { uint64 W[80], t1, t2, a, b, c, d, e, f, g, h; int i; @@ -136,7 +138,7 @@ static void sha512_init(struct sha512 *s) s->h[7] = 0x5be0cd19137e2179ULL; } -static void sha512_sum(struct sha512 *s, uint8_t *md) +static void sha512_sum(struct sha512 *s, uint8 *md) { int i; @@ -155,7 +157,7 @@ static void sha512_sum(struct sha512 *s, uint8_t *md) static void sha512_update(struct sha512 *s, const void *m, unsigned long len) { - const uint8_t *p = (uint8_t *)m; + const uint8 *p = (uint8 *)m; unsigned r = s->len % 128; s->len += len; From 025d7b6260177cc8e53f50421e2a5677c472d2f1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 7 Oct 2014 03:00:34 +0200 Subject: [PATCH 200/240] Fix crypt --HG-- branch : sha512-auth --- code/ryzom/common/src/game_share/crypt.cpp | 16 +++++++--------- code/ryzom/common/src/game_share/crypt.h | 2 +- .../ryzom/common/src/game_share/crypt_sha512.cpp | 4 +++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/ryzom/common/src/game_share/crypt.cpp b/code/ryzom/common/src/game_share/crypt.cpp index 881b42f1e..9a46281f7 100644 --- a/code/ryzom/common/src/game_share/crypt.cpp +++ b/code/ryzom/common/src/game_share/crypt.cpp @@ -18,16 +18,15 @@ #include "crypt.h" -char * rz_crypt(register const char *key, register const char *setting); +char * rz_crypt(register const char *key, register const char *setting, char *buf); char *__crypt_sha512(const char *key, const char *setting, char *output); // Crypts password using salt std::string CCrypt::crypt(const std::string& password, const std::string& salt) { - std::string result = ::rz_crypt(password.c_str(), salt.c_str()); - - return result; + char buf[128]; + return ::rz_crypt(password.c_str(), salt.c_str(), buf); } @@ -506,7 +505,7 @@ static char cryptresult[1+4+4+11+1]; /* encrypted result */ * Return a pointer to static data consisting of the "setting" * followed by an encryption produced by the "key" and "setting". */ -char * rz_crypt(register const char *key, register const char *setting) { +char * rz_crypt(register const char *key, register const char *setting, char *buf) { register char *encp; register long i; register int t; @@ -521,10 +520,9 @@ char * rz_crypt(register const char *key, register const char *setting) { return buff; #endif - static char buf[128]; - if (key[0] == '$' && key[1] == '6') { - return __crypt_sha512(key, setting, buf); - } + if (setting[0] == '$' && setting[1] == '6') { + return __crypt_sha512(key, setting, buf); + } for (i = 0; i < 8; i++) { if ((t = 2*(unsigned char)(*key)) != 0) diff --git a/code/ryzom/common/src/game_share/crypt.h b/code/ryzom/common/src/game_share/crypt.h index ea479d74f..b9fa8556b 100644 --- a/code/ryzom/common/src/game_share/crypt.h +++ b/code/ryzom/common/src/game_share/crypt.h @@ -32,7 +32,7 @@ class CCrypt public: /// Crypts password using salt - static std::string crypt(const std::string& password, const std::string& salt); + static std::string crypt(const std::string& password, const std::string& salt); }; diff --git a/code/ryzom/common/src/game_share/crypt_sha512.cpp b/code/ryzom/common/src/game_share/crypt_sha512.cpp index f3ebc5997..4d151880d 100644 --- a/code/ryzom/common/src/game_share/crypt_sha512.cpp +++ b/code/ryzom/common/src/game_share/crypt_sha512.cpp @@ -365,9 +365,11 @@ char *__crypt_sha512(const char *key, const char *setting, char *output) char *p, *q; p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ q = sha512crypt(testkey, testsetting, testbuf); - if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof(testhash))) return "*"; + return p; } From ec6ea26323396499e09d1b3d751ca252bdf61294 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:30:59 +0200 Subject: [PATCH 201/240] Fix when tx_b and tx_b_open have different heights --HG-- branch : develop --- code/nel/src/gui/group_container.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index 80c561f2e..c7d3227e8 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2731,7 +2731,8 @@ namespace NLGUI // h is the size of what is on top of the child list sint32 x, y, w, h; - h = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open; + bool bHasChild = (_List->getNbElement() > 0); + h = (pLayer->H_T - pLayer->InsetT) + (((!_Opened) || (!bHasChild)) ? pLayer->H_B : pLayer->H_B_Open); if (_Opened) { @@ -2749,7 +2750,6 @@ namespace NLGUI { h = _HReal; } - bool bHasChild = (_List->getNbElement() > 0); x = _XReal; y = _YReal+_HReal-h; @@ -2767,7 +2767,7 @@ namespace NLGUI // Top Right rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col); - if ((!_Opened) || (_Opened && !bHasChild)) + if ((!_Opened) || (!bHasChild)) { // Not opened // Left if (pLayer->Tile_L == 0) // Tiling ? @@ -2817,9 +2817,9 @@ namespace NLGUI rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR_Open, y, pLayer->W_BR_Open, pLayer->H_BR_Open, 0, false, pLayer->TxId_BR_Open, col); // Content if (pLayer->Tile_Blank == 0) // Tiling ? - rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col); + rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col); else - rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col); + rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col); // ScrollBar Placement if (pLayer->Tile_M_Open == 0) // Tiling ? rVR.drawRotFlipBitmap (rl, x, _YReal+pLayer->H_EL_Open, pLayer->W_M_Open, _HReal-h-pLayer->H_EL_Open, 0, false, pLayer->TxId_M_Open, col); @@ -2848,7 +2848,7 @@ namespace NLGUI // Top Right rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col); - if ((!_Opened) || (_Opened && !bHasChild)) + if ((!_Opened) || (!bHasChild)) { // Left if (pLayer->Tile_L == 0) // Tiling ? From ec68d2c317ee8724e3c2418cc59f385fddb95850 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:31:13 +0200 Subject: [PATCH 202/240] Fix rendering of specially sized window highlights --HG-- branch : develop --- code/nel/include/nel/gui/interface_options.h | 16 ++++++++-------- code/nel/src/gui/group_container.cpp | 18 ++++++++---------- code/nel/src/gui/interface_options.cpp | 8 ++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/code/nel/include/nel/gui/interface_options.h b/code/nel/include/nel/gui/interface_options.h index 6501cd2b0..da0ea7de8 100644 --- a/code/nel/include/nel/gui/interface_options.h +++ b/code/nel/include/nel/gui/interface_options.h @@ -150,14 +150,14 @@ namespace NLGUI sint32 TxId_E_Open, W_E_Open, H_E_Open; sint32 TxId_M_Open, W_M_Open, H_M_Open; - sint32 TxId_TL_HighLight; - sint32 TxId_T_HighLight; - sint32 TxId_TR_HighLight; - sint32 TxId_L_HighLight; - sint32 TxId_R_HighLight; - sint32 TxId_BL_HighLight; - sint32 TxId_B_HighLight; - sint32 TxId_BR_HighLight; + sint32 TxId_TL_HighLight, W_TL_HighLight, H_TL_HighLight; + sint32 TxId_T_HighLight, W_T_HighLight, H_T_HighLight; + sint32 TxId_TR_HighLight, W_TR_HighLight, H_TR_HighLight; + sint32 TxId_L_HighLight, W_L_HighLight, H_L_HighLight; + sint32 TxId_R_HighLight, W_R_HighLight, H_R_HighLight; + sint32 TxId_BL_HighLight, W_BL_HighLight, H_BL_HighLight; + sint32 TxId_B_HighLight, W_B_HighLight, H_B_HighLight; + sint32 TxId_BR_HighLight, W_BR_HighLight, H_BR_HighLight; sint32 HeaderH; sint32 InsetT; // Offset height of top texture diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index c7d3227e8..5c3a29e8b 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -3003,18 +3003,16 @@ namespace NLGUI col.A = nInverted; else col.A = max(_HighLightedAlpha, nInverted); - sint32 hw, hh; // size of highlight texture - rVR.getTextureSizeFromId(pLayer->TxId_TL_HighLight, hw, hh); // corners - rVR.drawRotFlipBitmap (_RenderLayer, x, y + h - hh, hw, hh, 0, false, pLayer->TxId_TL_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, y + h - hh, hw, hh, 0, false, pLayer->TxId_TR_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal, hw, hh, 0, false, pLayer->TxId_BL_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, _YReal, hw, hh, 0, false, pLayer->TxId_BR_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, y + h - pLayer->H_T_HighLight, pLayer->W_TL_HighLight, pLayer->H_TL_HighLight, 0, false, pLayer->TxId_TL_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_TR_HighLight, y + h - pLayer->H_T_HighLight, pLayer->W_TR_HighLight, pLayer->H_TR_HighLight, 0, false, pLayer->TxId_TR_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal, pLayer->W_BL_HighLight, pLayer->H_BL_HighLight, 0, false, pLayer->TxId_BL_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_BR_HighLight, _YReal, pLayer->W_BR_HighLight, pLayer->H_BR_HighLight, 0, false, pLayer->TxId_BR_HighLight, col); // border - rVR.drawRotFlipBitmap (_RenderLayer, x + hw, y + h - hh, _WReal - 2 * hw, hh, 0, false, pLayer->TxId_T_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + hw, _YReal, _WReal - 2 * hw, hh, 0, false, pLayer->TxId_B_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal + hh, hw, _HReal - 2 * hh, 0, false, pLayer->TxId_L_HighLight, col); - rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - hw, _YReal + hh, hw, _HReal - 2 * hh, 0, false, pLayer->TxId_R_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_TL_HighLight, y + h - pLayer->H_T_HighLight, _WReal - pLayer->W_TL_HighLight - pLayer->W_TR_HighLight, pLayer->H_T_HighLight, 0, false, pLayer->TxId_T_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_BL_HighLight, _YReal, _WReal - pLayer->W_BL_HighLight - pLayer->W_BR_HighLight, pLayer->H_B_HighLight, 0, false, pLayer->TxId_B_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal + pLayer->H_B_HighLight, pLayer->W_L_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_L_HighLight, col); + rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_R_HighLight, _YReal + pLayer->H_B_HighLight, pLayer->W_R_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_R_HighLight, col); } diff --git a/code/nel/src/gui/interface_options.cpp b/code/nel/src/gui/interface_options.cpp index 70141e0a3..3de015d65 100644 --- a/code/nel/src/gui/interface_options.cpp +++ b/code/nel/src/gui/interface_options.cpp @@ -271,13 +271,21 @@ namespace NLGUI // TxId_TL_HighLight = rVR.getTextureIdFromName (getValStr("tx_tl_highlight")); + rVR.getTextureSizeFromId(TxId_TL_HighLight, W_TL_HighLight, H_TL_HighLight); TxId_T_HighLight = rVR.getTextureIdFromName (getValStr("tx_t_highlight")); + rVR.getTextureSizeFromId(TxId_T_HighLight, W_T_HighLight, H_T_HighLight); TxId_TR_HighLight = rVR.getTextureIdFromName (getValStr("tx_tr_highlight")); + rVR.getTextureSizeFromId(TxId_TR_HighLight, W_TR_HighLight, H_TR_HighLight); TxId_L_HighLight = rVR.getTextureIdFromName (getValStr("tx_l_highlight")); + rVR.getTextureSizeFromId(TxId_L_HighLight, W_L_HighLight, H_L_HighLight); TxId_R_HighLight = rVR.getTextureIdFromName (getValStr("tx_r_highlight")); + rVR.getTextureSizeFromId(TxId_R_HighLight, W_R_HighLight, H_R_HighLight); TxId_BL_HighLight = rVR.getTextureIdFromName (getValStr("tx_bl_highlight")); + rVR.getTextureSizeFromId(TxId_BL_HighLight, W_BL_HighLight, H_BL_HighLight); TxId_B_HighLight = rVR.getTextureIdFromName (getValStr("tx_b_highlight")); + rVR.getTextureSizeFromId(TxId_B_HighLight, W_B_HighLight, H_B_HighLight); TxId_BR_HighLight = rVR.getTextureIdFromName (getValStr("tx_br_highlight")); + rVR.getTextureSizeFromId(TxId_BR_HighLight, W_BR_HighLight, H_BR_HighLight); // HeaderH = getValSInt32("header_h"); From dc3238b11102e47e71b869b0fc89ae383e07d176 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 09:31:45 +0200 Subject: [PATCH 203/240] Disable dumb loading strings --HG-- branch : develop --- code/ryzom/client/client_default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index 2846713fc..55e56b012 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -419,7 +419,7 @@ PrintfCommandsFreeTrial = { DisplayMissingAnimFile = 0; -LoadingStringCount = 54; +LoadingStringCount = 0; // Some R2 parameters ... From 97ddd3573d3ede76420775e282889546389a22ba Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:37:05 +0200 Subject: [PATCH 204/240] Select groups first. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 35 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index ec22798fb..734547512 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2400,21 +2400,34 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) + { + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + { + _CapturedView = g; + captured = true; + break; + } + } - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + if( !captured ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } From 5d5bf860d4729b1114308efa28d015bcfca2fcfe Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:42:18 +0200 Subject: [PATCH 205/240] Reparent items in widget hierarchy instead of deleting and creating a new item... --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/widget_hierarchy.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 5605d6439..1439fea9e 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -269,21 +269,16 @@ namespace GUIEditor if( ( newParent == NULL ) || ( item == NULL ) ) return; - // Remove old item + // Remove item from old parent QTreeWidgetItem *p = item->parent(); if( p != NULL ) p->setExpanded( false ); - id = item->data( 0, Qt::DisplayRole ).toString(); - delete item; - item = NULL; + p->removeChild( item ); // Remove reference to old item widgetHierarchyMap.erase( oldid ); - // Add new item - item = new QTreeWidgetItem(); - item->setData( 0, Qt::DisplayRole, id ); - item->setSelected( true ); + // Add item to new parent newParent->addChild( item ); // Add reference to new item From 64571abd478d9956bf2da10760302b03e83674a8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:52:56 +0200 Subject: [PATCH 206/240] When moving a group draw it's children too. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 2 ++ code/nel/src/gui/interface_group.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index daf6d2d53..62e61373e 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -328,6 +328,8 @@ namespace NLGUI void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 05f210568..ac6b57fb0 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2544,5 +2544,16 @@ namespace NLGUI for( std::vector< CInterfaceGroup* >::iterator itr = _ChildrenGroups.begin(); itr != _ChildrenGroups.end(); ++itr ) (*itr)->onWidgetDeleted( e ); } + + void CInterfaceGroup::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->updateCoords(); + } + } } From ad9e9839fbc7b544e65b26777a7cc581e2402838 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:59:39 +0200 Subject: [PATCH 207/240] Don't try to handle the right mouse button actions in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 734547512..950306750 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2302,6 +2302,14 @@ namespace NLGUI eventDesc.setX( _Pointer->getX() ); eventDesc.setY( _Pointer->getY() ); + if( CInterfaceElement::getEditorMode() ) + { + // Let's pretend we've handled the event... or actually we have! + if( ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) || + ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) ) + return true; + } + if( isMouseHandlingEnabled() ) { // First thing to do : Capture handling From 08b6675b3db7f2fe2030259bd74c261db5f1b295 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:00:54 +0200 Subject: [PATCH 208/240] Only select a group first in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 950306750..f0fbe1b1a 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,14 +2408,17 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) + if( CInterfaceElement::getEditorMode() ) { - CInterfaceGroup *g = _GroupsUnderPointer[ i ]; - if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { - _CapturedView = g; - captured = true; - break; + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + { + _CapturedView = g; + captured = true; + break; + } } } From d7d62e690c0700195bde583f6206e2b920179f54 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:45:17 +0200 Subject: [PATCH 209/240] Make group selection optional. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 +++ code/nel/src/gui/widget_manager.cpp | 3 ++- .../plugins/gui_editor/editor_message_processor.cpp | 5 +++++ .../src/plugins/gui_editor/editor_message_processor.h | 1 + .../src/plugins/gui_editor/gui_editor_window.cpp | 10 ++++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 89023c445..8790fc272 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -516,6 +516,8 @@ namespace NLGUI void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); + + void setGroupSelection( bool b ){ groupSelection = b; } private: CWidgetManager(); @@ -610,6 +612,7 @@ namespace NLGUI std::string currentEditorSelection; + bool groupSelection; }; } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index f0fbe1b1a..c6068b363 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + if( CInterfaceElement::getEditorMode() && groupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3516,6 +3516,7 @@ namespace NLGUI setScreenWH( 0, 0 ); currentEditorSelection = ""; + groupSelection = false; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 691dbdead..e834aa21f 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -130,5 +130,10 @@ namespace GUIEditor e->setActive( false ); e->setActive( true ); } + + void CEditorMessageProcessor::onSetGroupSelection( bool b ) + { + CWidgetManager::getInstance()->setGroupSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5c19a03c2..5d4098272 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -38,6 +38,7 @@ namespace GUIEditor public Q_SLOTS: void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); + void onSetGroupSelection( bool b ); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 9f6568936..3a4f982aa 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,16 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + + // ---------------------------------------------------------------------------------- + m->addSeparator(); + + a = new QAction( "Select groups", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } From 3ffe56b862850eafe088f5abee6df32486943cd3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 20:36:16 +0200 Subject: [PATCH 210/240] Added support for ungrouping. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 3 ++ code/nel/include/nel/gui/widget_manager.h | 1 + code/nel/src/gui/interface_group.cpp | 40 +++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 34 ++++++++++++++++ .../gui_editor/editor_message_processor.cpp | 12 ++++++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 95 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index 62e61373e..cdfd182e7 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -330,6 +330,9 @@ namespace NLGUI void moveBy( sint32 x, sint32 y ); + // Blows up the group, moves it's children to it's parent + bool explode(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8790fc272..917a0e9ba 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -518,6 +518,7 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); void setGroupSelection( bool b ){ groupSelection = b; } + bool unGroupSelection(); private: CWidgetManager(); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index ac6b57fb0..35b493ecb 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2555,5 +2555,45 @@ namespace NLGUI v->updateCoords(); } } + + bool CInterfaceGroup::explode() + { + CInterfaceGroup *p = getParent(); + if( p == NULL ) + return false; + + std::string oldId; + + // Reparent children + for( sint32 i = 0; i < _EltOrder.size(); i++ ) + { + CInterfaceElement *e = _EltOrder[ i ]; + + oldId = e->getId(); + + e->setParent( p ); + + if( e->getParentPos() == this ) + e->setParentPos( p ); + + if( e->getParentSize() == this ) + e->setParentSize( p ); + + if( e->getParentPos() == p ) + e->alignTo( p ); + + p->addElement( e ); + e->setIdRecurse( e->getShortId() ); + + CWidgetManager::getInstance()->onWidgetMoved( oldId, e->getId() ); + } + + _EltOrder.clear(); + _Views.clear(); + _Controls.clear(); + _ChildrenGroups.clear(); + + return true; + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c6068b363..21c9bd53d 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -3477,6 +3477,40 @@ namespace NLGUI return v; } + bool CWidgetManager::unGroupSelection() + { + if( currentEditorSelection.empty() ) + return false; + + // Does the element exist? + CInterfaceElement *e = getElementFromId( currentEditorSelection ); + if( e == NULL ) + return false; + + // Is the element a group? + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( e ); + if( g == NULL ) + return false; + + // Can't blow up a root group :( + CInterfaceGroup *p = g->getParent(); + if( p == NULL ) + return false; + + // KABOOM! + bool ok = g->explode(); + if( !ok ) + return false; + + p->delElement( g ); + + setCurrentEditorSelection( "" ); + + p->updateCoords(); + + return true; + } + CWidgetManager::CWidgetManager() { diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index e834aa21f..4c48a4fa4 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -135,5 +135,17 @@ namespace GUIEditor { CWidgetManager::getInstance()->setGroupSelection( b ); } + + void CEditorMessageProcessor::onUngroup() + { + bool ok = CWidgetManager::getInstance()->unGroupSelection(); + + if( !ok ) + { + QMessageBox::critical( NULL, + tr( "Ungrouping widgets" ), + tr( "Couldn't ungroup widgets." ) ); + } + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5d4098272..9e6d3cf89 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onUngroup(); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 3a4f982aa..01433bf9e 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Ungroup", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); + m->addAction( a ); + // ---------------------------------------------------------------------------------- m->addSeparator(); From bec078af25601d743ae3f35b5da8931c42fe73ea Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:00:56 +0200 Subject: [PATCH 211/240] Sizes should remain the same when ungrouping. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_group.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 35b493ecb..516a2f6aa 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2571,16 +2571,15 @@ namespace NLGUI oldId = e->getId(); + e->setW( e->getWReal() ); + e->setH( e->getHReal() ); + e->setSizeRef( "" ); + e->setParent( p ); - if( e->getParentPos() == this ) - e->setParentPos( p ); - - if( e->getParentSize() == this ) - e->setParentSize( p ); - - if( e->getParentPos() == p ) - e->alignTo( p ); + e->setParentPos( p ); + e->setParentSize( p ); + e->alignTo( p ); p->addElement( e ); e->setIdRecurse( e->getShortId() ); From a1e2c5667a03436f9dcb6ecaa7bfc46db7059626 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:28:20 +0200 Subject: [PATCH 212/240] A little crash fix. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 2 +- code/nel/src/gui/interface_element.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 3b095ac85..0be4c02e3 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -508,7 +508,7 @@ namespace NLGUI /// Called when the widget is deleted, /// so other widgets in the group can check if it belongs to them - virtual void onWidgetDeleted( CInterfaceElement *e ){} + virtual void onWidgetDeleted( CInterfaceElement *e ); /// Move the element by x in the X direction and y in the Y direction // Uses real coordinates diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 75fee53f2..c9b480516 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1685,6 +1685,14 @@ namespace NLGUI invalidateCoords(); } + void CInterfaceElement::onWidgetDeleted( CInterfaceElement *e ) + { + if( e == getParentPos() ) + setParentPos( NULL ); + if( e == getParentSize() ) + setParentSize( NULL ); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; From 3edfd56c75af371081b7db326a2efbaf724474a2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:34 +0200 Subject: [PATCH 213/240] Implement text shade outline --HG-- branch : develop --- code/nel/include/nel/3d/text_context.h | 65 ++++++++++++++++----- code/nel/include/nel/3d/text_context_user.h | 28 ++++----- code/nel/include/nel/3d/u_text_context.h | 9 +++ code/nel/src/3d/text_context.cpp | 1 + code/nel/src/3d/text_context_user.cpp | 12 ++++ 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/code/nel/include/nel/3d/text_context.h b/code/nel/include/nel/3d/text_context.h index 203e2b3c3..064a0ef64 100644 --- a/code/nel/include/nel/3d/text_context.h +++ b/code/nel/include/nel/3d/text_context.h @@ -82,6 +82,8 @@ public: void setShaded (bool b) { _Shaded = b; } + void setShadeOutline (bool b) { _ShadeOutline = b; } + void setShadeExtent (float shext) { _ShadeExtent = shext; } /// The alpha of the shade is multiplied at each draw with the alpha of the color. Default: (0,0,0,255) @@ -107,6 +109,8 @@ public: bool getShaded() const { return _Shaded; } + bool getShadeOutline() const { return _ShadeOutline; } + bool getKeep800x600Ratio() const {return _Keep800x600Ratio;} NLMISC::CRGBA getShadeColor () const { return _ShadeColor; } @@ -138,15 +142,21 @@ public: { nlassert (index < _CacheStrings.size()); CComputedString &rCS = _CacheStrings[index]; - if(_Shaded) + if (_Shaded) { - CRGBA bkup = rCS.Color; + CRGBA bkup = rCS.Color; rCS.Color = _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - rCS.render2D (*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + if (_ShadeOutline) + { + rCS.render2D(*_Driver, x-_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x-_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x+_ShadeExtent, z+_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ); + } rCS.Color= bkup; } - rCS.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + rCS.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /** Clip and print a string that is in the cache (it leaves the string in the cache) @@ -162,6 +172,12 @@ public: rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); + if (_ShadeOutline) + { + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z+_ShadeExtent, xmin, ymin, xmax, ymax); + } rCS.Color= bkup; } rCS.render2DClip (*_Driver, rdrBuffer, x, z, xmin, ymin, xmax, ymax); @@ -174,12 +190,18 @@ public: { nlassert (index < _CacheStrings.size()); CComputedString &rCS = _CacheStrings[index]; - if(_Shaded) + if (_Shaded) { CRGBA bkup = rCS.Color; rCS.Color= _ShadeColor; rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + if (_ShadeOutline) + { + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax); + } rCS.Color= bkup; } rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y, depth, xmin, ymin, xmax, ymax); @@ -194,17 +216,23 @@ public: _FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); // draw shaded - if(_Shaded) + if (_Shaded) { CRGBA bkup = _TempString.Color; - _TempString.Color= _ShadeColor; + _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D (*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.Color= bkup; + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + if (_ShadeOutline) + { + _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + _TempString.Color = bkup; } // draw - _TempString.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + _TempString.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /// Directly print a string @@ -218,17 +246,23 @@ public: _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); // draw shaded - if(_Shaded) + if (_Shaded) { CRGBA bkup = _TempString.Color; _TempString.Color = _ShadeColor; _TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8); - _TempString.render2D (*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); - _TempString.Color= bkup; + _TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + if (_ShadeOutline) + { + _TempString.render2D(*_Driver,x-_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x-_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + _TempString.render2D(*_Driver,x+_ShadeExtent,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ); + } + _TempString.Color = bkup; } // draw - _TempString.render2D (*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); + _TempString.render2D(*_Driver, x, z, _HotSpot, _ScaleX, _ScaleZ); } /// Get computed string from index @@ -317,6 +351,9 @@ private: /// true if text is shaded bool _Shaded; + /// true if shade appears as an outline + bool _ShadeOutline; + /// shade's extent (shadow size) float _ShadeExtent; diff --git a/code/nel/include/nel/3d/text_context_user.h b/code/nel/include/nel/3d/text_context_user.h index a95fb2ca1..8e14dc878 100644 --- a/code/nel/include/nel/3d/text_context_user.h +++ b/code/nel/include/nel/3d/text_context_user.h @@ -64,19 +64,21 @@ public: /// \name Text look. // @{ void setColor(NLMISC::CRGBA color); - void setFontSize(uint32 fontSize) ; - uint32 getFontSize() const ; - void setHotSpot(THotSpot hotSpot) ; - THotSpot getHotSpot() const ; - void setScaleX(float scaleX) ; - void setScaleY(float scaleY) ; - float getScaleX() const ; - float getScaleY() const ; - void setShaded(bool b) ; - bool getShaded() const ; - void setShadeExtent(float shext) ; - void setShadeColor (NLMISC::CRGBA sc); - NLMISC::CRGBA getShadeColor () const; + void setFontSize(uint32 fontSize); + uint32 getFontSize() const; + void setHotSpot(THotSpot hotSpot); + THotSpot getHotSpot() const; + void setScaleX(float scaleX); + void setScaleY(float scaleY); + float getScaleX() const; + float getScaleY() const; + void setShaded(bool b); + bool getShaded() const; + void setShadeOutline(bool b); + bool getShadeOutline() const; + void setShadeExtent(float shext) ; + void setShadeColor (NLMISC::CRGBA sc); + NLMISC::CRGBA getShadeColor () const; void setKeep800x600Ratio(bool keep); bool getKeep800x600Ratio() const; // @} diff --git a/code/nel/include/nel/3d/u_text_context.h b/code/nel/include/nel/3d/u_text_context.h index dcaa1949a..1056d3839 100644 --- a/code/nel/include/nel/3d/u_text_context.h +++ b/code/nel/include/nel/3d/u_text_context.h @@ -174,6 +174,15 @@ public: * \return the shade state */ virtual bool getShaded () const = 0; + /** + * set the shade states + * \param the shade state + */ + virtual void setShadeOutline (bool b) = 0; + /** + * \return the shade state + */ + virtual bool getShadeOutline () const = 0; /** * set the shadow's size * \param the shade extent diff --git a/code/nel/src/3d/text_context.cpp b/code/nel/src/3d/text_context.cpp index 4b6e46c85..456ab77a6 100644 --- a/code/nel/src/3d/text_context.cpp +++ b/code/nel/src/3d/text_context.cpp @@ -40,6 +40,7 @@ CTextContext::CTextContext() _ScaleZ = 1.0f; _Shaded = false; + _ShadeOutline = false; _ShadeExtent = 0.001f; _ShadeColor = NLMISC::CRGBA(0,0,0); diff --git a/code/nel/src/3d/text_context_user.cpp b/code/nel/src/3d/text_context_user.cpp index 570c879f9..6ee880d91 100644 --- a/code/nel/src/3d/text_context_user.cpp +++ b/code/nel/src/3d/text_context_user.cpp @@ -148,6 +148,18 @@ bool CTextContextUser::getShaded() const return _TextContext.getShaded(); } +void CTextContextUser::setShadeOutline(bool b) +{ + H_AUTO2; + + _TextContext.setShadeOutline(b); +} +bool CTextContextUser::getShadeOutline() const +{ + H_AUTO2; + + return _TextContext.getShadeOutline(); +} void CTextContextUser::setShadeExtent(float shext) { H_AUTO2; From 74827a1808678ed78e4d7b413006e7c0aa340735 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:35 +0200 Subject: [PATCH 214/240] Handle shadow outline in gui --HG-- branch : develop --- code/nel/include/nel/gui/group_menu.h | 1 + code/nel/include/nel/gui/view_text.h | 5 ++- code/nel/src/gui/group_container.cpp | 2 ++ code/nel/src/gui/group_menu.cpp | 22 +++++++++++++ code/nel/src/gui/view_text.cpp | 45 +++++++++++++++++++++++++-- code/nel/src/gui/widget_manager.cpp | 1 + 6 files changed, 72 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/group_menu.h b/code/nel/include/nel/gui/group_menu.h index 56b9fb0e3..420967347 100644 --- a/code/nel/include/nel/gui/group_menu.h +++ b/code/nel/include/nel/gui/group_menu.h @@ -381,6 +381,7 @@ namespace NLGUI bool _CloseSubMenuUsingPopModal; bool _Shadow; + bool _ShadowOutline; bool _Formatted; uint8 _Space; sint32 _FontSize; diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index df3cf27e3..a14713dcc 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -48,7 +48,7 @@ namespace NLGUI /// Constructor CViewText (const std::string& id, const std::string Text="", sint FontSize=12, - NLMISC::CRGBA Color=NLMISC::CRGBA(255,255,255), bool Shadow=false); + NLMISC::CRGBA Color=NLMISC::CRGBA(255,255,255), bool Shadow=false, bool ShadowOutline=false); virtual ~CViewText(); @@ -83,6 +83,7 @@ namespace NLGUI void setFontSize (sint nFontSize); void setColor (const NLMISC::CRGBA &color); void setShadow (bool bShadow); + void setShadowOutline (bool bShadowOutline); void setShadowColor (const NLMISC::CRGBA &color); void setLineMaxW (sint nMaxW, bool invalidate=true); void setMultiLine (bool bMultiLine); @@ -102,6 +103,7 @@ namespace NLGUI sint getFontSize() const; NLMISC::CRGBA getColor() { return _Color; } bool getShadow() { return _Shadow; } + bool getShadowOutline() { return _ShadowOutline; } NLMISC::CRGBA getShadowColor() { return _ShadowColor; } sint getLineMaxW() const { return _LineMaxW; } bool getMultiLine() const { return _MultiLine; } @@ -225,6 +227,7 @@ namespace NLGUI NLMISC::CRGBA _Color; /// the shadow mode bool _Shadow; + bool _ShadowOutline; /// the case mode TCaseMode _CaseMode; /// the text shadow color diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index 5c3a29e8b..18a65bc5f 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -3713,6 +3713,7 @@ namespace NLGUI _TitleOpened->setParentPosRef (Hotspot_TL); _TitleOpened->setPosRef (Hotspot_TL); _TitleOpened->setShadow (true); + _TitleOpened->setShadowOutline (false); _TitleOpened->setColor (CRGBA(255,255,255,255)); _TitleOpened->setModulateGlobalColor(getModulateGlobalColor()); _TitleOpened->setOverExtendViewText(_TitleOverExtendViewText); @@ -3764,6 +3765,7 @@ namespace NLGUI _TitleClosed->setParentPosRef (Hotspot_TL); _TitleClosed->setPosRef (Hotspot_TL); _TitleClosed->setShadow (true); + _TitleClosed->setShadowOutline (false); _TitleClosed->setColor (CRGBA(255,255,255,255)); _TitleClosed->setModulateGlobalColor(getModulateGlobalColor()); _TitleClosed->setOverExtendViewText(_TitleOverExtendViewText); diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp index 85ed1959e..08f887e9e 100644 --- a/code/nel/src/gui/group_menu.cpp +++ b/code/nel/src/gui/group_menu.cpp @@ -1203,6 +1203,7 @@ namespace NLGUI pV->setColor (_GroupMenu->_Color); pV->setFontSize (_GroupMenu->_FontSize); pV->setShadow (_GroupMenu->_Shadow); + pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); pV->setChecked(checked); pV->setModulateGlobalColor(_GroupMenu->_ModulateGlobalColor); @@ -1282,6 +1283,7 @@ namespace NLGUI pV->setColor (_GroupMenu->_Color); pV->setFontSize (_GroupMenu->_FontSize); pV->setShadow (_GroupMenu->_Shadow); + pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); pV->setChecked(checked); pV->setModulateGlobalColor(_GroupMenu->_ModulateGlobalColor); @@ -1922,6 +1924,7 @@ namespace NLGUI _HighLightOver.set(128, 0, 0, 255); _FontSize = 12; _Shadow = false; + _ShadowOutline = false; _ResizeFromChildH = _ResizeFromChildW = true; _DisplayFrame = false; _RootMenu = NULL; @@ -1998,6 +2001,11 @@ namespace NLGUI return toString( _Shadow ); } else + if( name == "shadow_outline" ) + { + return toString( _ShadowOutline ); + } + else if( name == "formatted" ) { return toString( _Formatted ); @@ -2110,6 +2118,14 @@ namespace NLGUI return; } else + if( name == "shadow_outline" ) + { + bool b; + if( fromString( value, b ) ) + _ShadowOutline = b; + return; + } + else if( name == "formatted" ) { bool b; @@ -2152,6 +2168,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "space", BAD_CAST toString( _Space ).c_str() ); xmlSetProp( node, BAD_CAST "fontsize", BAD_CAST toString( _FontSize ).c_str() ); xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() ); + xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() ); xmlSetProp( node, BAD_CAST "formatted", BAD_CAST toString( _Formatted ).c_str() ); if( _RootMenu == NULL ) @@ -2197,6 +2214,7 @@ namespace NLGUI _Color = gm->_Color; _ShadowColor = gm->_ShadowColor; _Shadow = gm->_Shadow; + _ShadowOutline = gm->_ShadowOutline; _FontSize = gm->_FontSize; _ColorOver = gm->_ColorOver; _ShadowColorOver = gm->_ShadowColorOver; @@ -2266,6 +2284,10 @@ namespace NLGUI if (prop) _Shadow = convertBool(prop); + prop = (char*) xmlGetProp( in, (xmlChar*)"shadow_outline" ); + if (prop) + _ShadowOutline = convertBool(prop); + prop = (char*) xmlGetProp( in, (xmlChar*)"formatted" ); if (prop) _Formatted = convertBool(prop); diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6ff1930af..0186938f7 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -62,6 +62,7 @@ namespace NLGUI CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32(); _Color = CRGBA(255,255,255,255); _Shadow = false; + _ShadowOutline = false; _ShadowColor = CRGBA(0,0,0,255); _MultiLine = false; @@ -111,7 +112,7 @@ namespace NLGUI ///constructor // *************************************************************************** CViewText:: CViewText (const std::string& id, const std::string Text, sint FontSize, - NLMISC::CRGBA Color, bool Shadow) + NLMISC::CRGBA Color, bool Shadow, bool ShadowOutline) :CViewBase(TCtorParam()) { _Id = id; @@ -120,6 +121,7 @@ namespace NLGUI _FontSize = FontSize + CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32(); _Color = Color; _Shadow = Shadow; + _ShadowOutline = ShadowOutline; setText(Text); computeFontSize (); } @@ -159,6 +161,7 @@ namespace NLGUI _FontSize = vt._FontSize; _Color = vt._Color; _Shadow = vt._Shadow; + _ShadowOutline = vt._ShadowOutline; _ShadowColor = vt._ShadowColor; _MultiLine = false; @@ -225,6 +228,11 @@ namespace NLGUI return toString( _Shadow ); } else + if( name == "shadow_outline" ) + { + return toString( _ShadowOutline ); + } + else if( name == "shadow_color" ) { return toString( _ShadowColor ); @@ -360,6 +368,14 @@ namespace NLGUI return true; } else + if( name == "shadow_outline" ) + { + bool b; + if( fromString( value, b ) ) + _ShadowOutline = b; + return true; + } + else if( name == "shadow_color" ) { CRGBA c; @@ -520,6 +536,7 @@ namespace NLGUI ).c_str() ); xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() ); + xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() ); xmlSetProp( node, BAD_CAST "shadow_color", BAD_CAST toString( _ShadowColor ).c_str() ); xmlSetProp( node, BAD_CAST "multi_line", BAD_CAST toString( _MultiLine ).c_str() ); @@ -604,6 +621,11 @@ namespace NLGUI if (prop) _Shadow = convertBool(prop); + prop = (char*) xmlGetProp( cur, (xmlChar*)"shadow_outline" ); + _ShadowOutline = false; + if (prop) + _ShadowOutline = convertBool(prop); + prop= (char*) xmlGetProp( cur, (xmlChar*)"shadow_color" ); _ShadowColor = CRGBA(0,0,0,255); if (prop) @@ -864,6 +886,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); @@ -978,6 +1001,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); @@ -1146,6 +1170,14 @@ namespace NLGUI invalidateContent(); } + // *************************************************************************** + void CViewText::setShadowOutline (bool bShadowOutline) + { + _ShadowOutline = bShadowOutline; + computeFontSize (); + invalidateContent(); + } + // *************************************************************************** void CViewText::setShadowColor(const NLMISC::CRGBA & color) { @@ -1647,6 +1679,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // default state @@ -1958,6 +1991,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // CViewRenderer &rVR = *CViewRenderer::getInstance(); height = getFontHeight(); @@ -2089,6 +2123,7 @@ namespace NLGUI // setup the text context TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // find the line where the character is // CViewRenderer &rVR = *CViewRenderer::getInstance(); @@ -2363,6 +2398,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); TCharPos linePos = 0; @@ -2447,6 +2483,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // Current position in text @@ -2498,12 +2535,13 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); + TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); // Letter size UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext - _FontHeight = (uint) si.StringHeight + (_Shadow?1:0); - _FontLegHeight = (uint) si.StringLine + (_Shadow?1:0); + _FontHeight = (uint) si.StringHeight + (_Shadow?(_ShadowOutline?2:1):0); + _FontLegHeight = (uint) si.StringLine + (_Shadow?(_ShadowOutline?2:1):0); // Space width si = TextContext->getStringInfo(ucstring(" ")); @@ -2960,6 +2998,7 @@ namespace NLGUI f.serial(_SpaceWidth); f.serial(_Color); f.serial(_Shadow); + f.serial(_ShadowOutline); f.serialEnum(_CaseMode); f.serial(_ShadowColor); f.serial(_LineMaxW); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index a448603c0..9b9a74e77 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1186,6 +1186,7 @@ namespace NLGUI vtDst->setColor (vtSrc->getColor()); vtDst->setModulateGlobalColor(vtSrc->getModulateGlobalColor()); vtDst->setShadow(vtSrc->getShadow()); + vtDst->setShadowOutline(vtSrc->getShadowOutline()); vtDst->setShadowColor(vtSrc->getShadowColor()); vtDst->setCaseMode(vtSrc->getCaseMode()); vtDst->setUnderlined(vtSrc->getUnderlined()); From 5fd4f96a597a197ac58847efed15a5aa9521a195 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 8 Oct 2014 23:20:35 +0200 Subject: [PATCH 215/240] Configure shadow outline in applications --HG-- branch : develop --- code/ryzom/client/src/debug_client.cpp | 3 +++ code/ryzom/client/src/graph.cpp | 1 + code/ryzom/client/src/ground_fx_manager.cpp | 1 + code/ryzom/client/src/interface_v3/chat_text_manager.cpp | 1 + .../client/src/interface_v3/dbgroup_list_sheet_text.cpp | 1 + .../dbgroup_list_sheet_text_brick_composition.cpp | 1 + .../src/interface_v3/dbgroup_list_sheet_text_share.cpp | 2 ++ code/ryzom/client/src/interface_v3/group_map.cpp | 1 + code/ryzom/client/src/main_loop.cpp | 2 ++ code/ryzom/client/src/main_loop_debug.cpp | 6 ++++++ code/ryzom/client/src/r2/editor.cpp | 1 + code/ryzom/client/src/timed_fx_manager.cpp | 1 + .../tools/leveldesign/world_editor/world_editor/display.cpp | 1 + code/snowballs2/client/src/snowballs_client.cpp | 1 + 14 files changed, 23 insertions(+) diff --git a/code/ryzom/client/src/debug_client.cpp b/code/ryzom/client/src/debug_client.cpp index 8800384ba..0af4207ae 100644 --- a/code/ryzom/client/src/debug_client.cpp +++ b/code/ryzom/client/src/debug_client.cpp @@ -345,6 +345,7 @@ void displayStreamingDebug () //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -390,6 +391,7 @@ void displayStreamingDebug () // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); } } @@ -567,6 +569,7 @@ void displayNetDebug () //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color diff --git a/code/ryzom/client/src/graph.cpp b/code/ryzom/client/src/graph.cpp index 1bf370db0..8270762fb 100644 --- a/code/ryzom/client/src/graph.cpp +++ b/code/ryzom/client/src/graph.cpp @@ -134,6 +134,7 @@ void CGraph::renderGraph () if (TextContext != NULL) { TextContext->setShaded (false); + TextContext->setShadeOutline(false); TextContext->setHotSpot (UTextContext::MiddleLeft); TextContext->setColor (frontCol); TextContext->setFontSize (10); diff --git a/code/ryzom/client/src/ground_fx_manager.cpp b/code/ryzom/client/src/ground_fx_manager.cpp index dc064415f..f13309183 100644 --- a/code/ryzom/client/src/ground_fx_manager.cpp +++ b/code/ryzom/client/src/ground_fx_manager.cpp @@ -807,6 +807,7 @@ void CTestGroundFX::displayFXBoxes() const Driver->setFrustum(fr); TextContext->setColor(CRGBA::Green); TextContext->setShaded(false); + TextContext->setShadeOutline(false); TextContext->setFontSize(12); // float size = 0.4f; diff --git a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp index 10fd2d29c..faaf86092 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -157,6 +157,7 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA CViewText *vt = new CViewText(CViewText::TCtorParam()); // get parameters from config.xml vt->setShadow(isTextShadowed()); + vt->setShadowOutline(false); vt->setFontSize(getTextFontSize()); vt->setMultiLine(true); vt->setTextMode(justified ? CViewText::Justified : CViewText::DontClipWord); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp index a05d1e4aa..772f99418 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp @@ -880,6 +880,7 @@ void CDBGroupListSheetText::setup() text->setFontSize(_TextTemplate.getFontSize()); text->setColor(_TextTemplate.getColor()); text->setShadow(_TextTemplate.getShadow()); + text->setShadowOutline(_TextTemplate.getShadowOutline()); text->setLineMaxW(_TextTemplate.getLineMaxW()); text->setMultiLine(_TextTemplate.getMultiLine()); if(text->getMultiLine()) diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp index 67079ba55..c67e69660 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_brick_composition.cpp @@ -95,6 +95,7 @@ void CDBGroupListSheetTextBrickComposition::CSheetChildBrick::init(CDBGroupListS text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp index 35cd90a7e..fcef370e0 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text_share.cpp @@ -121,6 +121,7 @@ void CDBGroupListSheetTextShare::CSheetChildShare::init(CDBGroupListSheetText *p text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); // Add it to the scrolled list. @@ -139,6 +140,7 @@ void CDBGroupListSheetTextShare::CSheetChildShare::init(CDBGroupListSheetText *p text->setFontSize(compoList->getTextTemplate().getFontSize()); text->setColor(compoList->getTextTemplate().getColor()); text->setShadow(compoList->getTextTemplate().getShadow()); + text->setShadowOutline(compoList->getTextTemplate().getShadowOutline()); text->setMultiLine(false); text->setModulateGlobalColor(compoList->getTextTemplate().getModulateGlobalColor()); // Add it to the scrolled list. diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 31d70d0d7..558ab960c 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -2333,6 +2333,7 @@ void CGroupMap::createLMWidgets(const std::vector &lms) pNewText->setColor(CRGBA(255,255,255,255)); pNewText->setShadow(true); + pNewText->setShadowOutline(false); pNewText->setShadowColor(CRGBA(0,0,0,255)); pNewText->setModulateGlobalColor(false); pNewText->Type = rCLM.Type; diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 1ac6a4a0c..f6d921ff8 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1924,6 +1924,7 @@ bool mainLoop() // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(10); // Set the text color @@ -2586,6 +2587,7 @@ void displaySpecialTextProgress(const char *text) { // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(12); // Set the text color diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp index 8b224f27f..19ea38414 100644 --- a/code/ryzom/client/src/main_loop_debug.cpp +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -80,6 +80,7 @@ void displayDebug() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -470,6 +471,7 @@ void displayDebug() // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); }// displayDebug // // ******************************************************************** @@ -491,6 +493,7 @@ void displayDebugFps() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); // Set the text color @@ -533,6 +536,7 @@ void displayDebugUIUnderMouse() //----------------// // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.DebugFontSize); @@ -707,6 +711,7 @@ void displayHelp() // Create a shadow when displaying a text. TextContext->setShaded(true); + TextContext->setShadeOutline(false); // Set the font size. TextContext->setFontSize(ClientCfg.HelpFontSize); // Set the text color @@ -763,6 +768,7 @@ void displayHelp() // No more shadow when displaying a text. TextContext->setShaded(false); + TextContext->setShadeOutline(false); }// displayHelp // // ******************************************************************** diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp index bb09bec52..2bceb4200 100644 --- a/code/ryzom/client/src/r2/editor.cpp +++ b/code/ryzom/client/src/r2/editor.cpp @@ -1789,6 +1789,7 @@ void CEditor::waitScenarioScreen() if (!waitScreen) { TextContext->setShaded(true); + TextContext->setShadeOutline(false); TextContext->setFontSize(40); TextContext->setColor(CRGBA::White); diff --git a/code/ryzom/client/src/timed_fx_manager.cpp b/code/ryzom/client/src/timed_fx_manager.cpp index 9f7f40caf..d37ab782f 100644 --- a/code/ryzom/client/src/timed_fx_manager.cpp +++ b/code/ryzom/client/src/timed_fx_manager.cpp @@ -829,6 +829,7 @@ void CTimedFXManager::displayFXBoxes(TDebugDisplayMode displayMode) const Driver->setFrustum(fr); TextContext->setColor(CRGBA::Blue); TextContext->setShaded(false); + TextContext->setShadeOutline(false); TextContext->setFontSize(10); // float size = 0.4f; diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp index dd2a17d82..09763d27c 100644 --- a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp +++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp @@ -309,6 +309,7 @@ void CDisplay::init (CMainFrame *pMF) _TextContext->setFontGenerator(NLMISC::CPath::getWindowsDirectory() + "Fonts\\arial.ttf"); _TextContext->setKeep800x600Ratio(true); _TextContext->setShaded(true); + _TextContext->setShadeOutline(false); _TextContext->setShadeColor(NLMISC::CRGBA::Black); } catch(...) diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 68cdc47fa..7e019412b 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -327,6 +327,7 @@ void initCore() ConfigFile->getVar("ScreenFull").asInt()==0)); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext->setShaded(true); + TextContext->setShadeOutline(false); TextContext->setKeep800x600Ratio(false); // You can't call displayLoadingState() before init the loading state system displayLoadingState("Initialize Loading"); From aaa044203e1e1e27a6febd3f47dd32799fd3ab35 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 10 Oct 2014 13:07:54 +0200 Subject: [PATCH 216/240] Fix some warnings --HG-- branch : develop --- code/nel/src/misc/config_file/cf_bison.simple | 2 +- code/nel/src/misc/config_file/cf_flex.skl | 2 +- code/nel/src/misc/config_file/cf_lexical.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/nel/src/misc/config_file/cf_bison.simple b/code/nel/src/misc/config_file/cf_bison.simple index 3ab0e5b1a..64e930f27 100644 --- a/code/nel/src/misc/config_file/cf_bison.simple +++ b/code/nel/src/misc/config_file/cf_bison.simple @@ -328,7 +328,7 @@ yynewstate: #endif /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; + int size = (int)(yyssp - yyss + 1); #ifdef yyoverflow /* Each stack pointer address is followed by the size of diff --git a/code/nel/src/misc/config_file/cf_flex.skl b/code/nel/src/misc/config_file/cf_flex.skl index 5da2aa3f6..b69bed057 100644 --- a/code/nel/src/misc/config_file/cf_flex.skl +++ b/code/nel/src/misc/config_file/cf_flex.skl @@ -1000,7 +1000,7 @@ int yyFlexLexer::yyinput() else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; + int offset = (int)(yy_c_buf_p - yytext_ptr); ++yy_c_buf_p; switch ( yy_get_next_buffer() ) diff --git a/code/nel/src/misc/config_file/cf_lexical.cpp b/code/nel/src/misc/config_file/cf_lexical.cpp index f47696ff9..80fd4fd36 100644 --- a/code/nel/src/misc/config_file/cf_lexical.cpp +++ b/code/nel/src/misc/config_file/cf_lexical.cpp @@ -2773,7 +2773,7 @@ static int input() else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; + int offset = (int)(yy_c_buf_p - yytext_ptr); ++yy_c_buf_p; switch ( yy_get_next_buffer() ) From e34ba83f266f8ddf4d7e38c1318ece251858d277 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 10 Oct 2014 13:08:14 +0200 Subject: [PATCH 217/240] Minor changes --HG-- branch : develop --- code/CMakeModules/FindDirectXSDK.cmake | 6 ------ code/nel/include/nel/3d/anim_detail_trav.h | 2 +- code/nel/tools/misc/data_mirror/StdAfx.h | 3 --- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/code/CMakeModules/FindDirectXSDK.cmake b/code/CMakeModules/FindDirectXSDK.cmake index 3cf91ec3c..b64fca6ea 100644 --- a/code/CMakeModules/FindDirectXSDK.cmake +++ b/code/CMakeModules/FindDirectXSDK.cmake @@ -52,12 +52,6 @@ IF(DXSDK_DIR) FIND_DXSDK_LIBRARY(DXSDK_XAUDIO_LIBRARY x3daudio) FIND_DXSDK_LIBRARY(DXSDK_D3DX9_LIBRARY d3dx9) FIND_DXSDK_LIBRARY(DXSDK_D3D9_LIBRARY d3d9) - - #FIND_DXSDK_LIBRARY(DXSDK_MESH_LIBRARY mesh) - #FIND_DXSDK_LIBRARY(DXSDK_MAXUTIL_LIBRARY maxutil) - #FIND_DXSDK_LIBRARY(DXSDK_MAXSCRIPT_LIBRARY maxscrpt) - #FIND_DXSDK_LIBRARY(DXSDK_PARAMBLK2_LIBRARY paramblk2) - #FIND_DXSDK_LIBRARY(DXSDK_BMM_LIBRARY bmm) ENDIF(DXSDK_DIR) # Handle the QUIETLY and REQUIRED arguments and set DXSDK_FOUND to TRUE if diff --git a/code/nel/include/nel/3d/anim_detail_trav.h b/code/nel/include/nel/3d/anim_detail_trav.h index 7b51afe84..0a94fe376 100644 --- a/code/nel/include/nel/3d/anim_detail_trav.h +++ b/code/nel/include/nel/3d/anim_detail_trav.h @@ -71,7 +71,7 @@ public: // For clipTrav. cleared at beginning of CClipTrav::traverse void clearVisibleList(); - // For ClipTrav only. NB: list is cleared at begininng of traverse(). NB: only CTransform are supported + // For ClipTrav only. NB: list is cleared at beginning of traverse(). NB: only CTransform are supported void addVisibleModel(CTransform *model) { _VisibleList[_CurrentNumVisibleModels]= model; diff --git a/code/nel/tools/misc/data_mirror/StdAfx.h b/code/nel/tools/misc/data_mirror/StdAfx.h index 90fe14511..a065be4ed 100644 --- a/code/nel/tools/misc/data_mirror/StdAfx.h +++ b/code/nel/tools/misc/data_mirror/StdAfx.h @@ -10,9 +10,6 @@ #pragma once #endif // _MSC_VER > 1000 -#include "nel/misc/types_nl.h" -#include "nel/misc/file.h" - #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include // MFC core and standard components From 8cec8de3a068f856d6c97bd16b0bf3063e7a70ef Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 17:33:57 +0200 Subject: [PATCH 218/240] Unselect selection when clicking 'nothing'. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 21c9bd53d..c26a23231 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2475,6 +2475,11 @@ namespace NLGUI // handle the capture _CapturedView->handleEvent( evnt ); } + else + { + if( CInterfaceElement::getEditorMode() ) + setCurrentEditorSelection( "" ); + } } // Manage RightClick From aac2fd41a16f871c7cfccd84aac8597bf98289f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 20:25:25 +0200 Subject: [PATCH 219/240] Allow multiselection. --HG-- branch : dfighter-tools --- .../nel/gui/editor_selection_watcher.h | 3 +- code/nel/include/nel/gui/widget_manager.h | 16 +++-- code/nel/src/gui/view_base.cpp | 2 +- code/nel/src/gui/widget_manager.cpp | 68 +++++++++++++------ .../gui_editor/editor_message_processor.cpp | 42 +++++++----- .../gui_editor/editor_message_processor.h | 1 + .../gui_editor/editor_selection_watcher.cpp | 4 +- .../gui_editor/editor_selection_watcher.h | 4 +- .../plugins/gui_editor/gui_editor_window.cpp | 14 ++-- .../gui_editor/property_browser_ctrl.cpp | 12 +++- .../gui_editor/property_browser_ctrl.h | 2 +- .../plugins/gui_editor/widget_hierarchy.cpp | 19 ++++-- .../src/plugins/gui_editor/widget_hierarchy.h | 2 +- 13 files changed, 130 insertions(+), 59 deletions(-) diff --git a/code/nel/include/nel/gui/editor_selection_watcher.h b/code/nel/include/nel/gui/editor_selection_watcher.h index 415f4f9db..7e262bdf1 100644 --- a/code/nel/include/nel/gui/editor_selection_watcher.h +++ b/code/nel/include/nel/gui/editor_selection_watcher.h @@ -15,6 +15,7 @@ // along with this program. If not, see . #include +#include namespace NLGUI { @@ -24,7 +25,7 @@ namespace NLGUI public: /// Notifies the watcher about the change - virtual void selectionChanged( std::string &newSelection ) = 0; + virtual void selectionChanged() = 0; }; } diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 917a0e9ba..243847ad7 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -503,8 +503,15 @@ namespace NLGUI IParser* getParser() const{ return parser; } - std::string& getCurrentEditorSelection(){ return currentEditorSelection; } - void setCurrentEditorSelection( const std::string &name ); + /// Retrieves the Id of the currently selected widgets + void getEditorSelection( std::vector< std::string > &selection ); + + /// Adds the widget with the specified Id to the selected widgets + void selectWidget( const std::string &name ); + + /// Clears the selection + void clearEditorSelection(); + void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); @@ -519,6 +526,7 @@ namespace NLGUI void setGroupSelection( bool b ){ groupSelection = b; } bool unGroupSelection(); + void setMultiSelection( bool b ){ multiSelection = b; } private: CWidgetManager(); @@ -611,9 +619,9 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* > selectionWatchers; std::vector< IWidgetWatcher* > widgetWatchers; - - std::string currentEditorSelection; + std::vector< std::string > editorSelection; bool groupSelection; + bool multiSelection; }; } diff --git a/code/nel/src/gui/view_base.cpp b/code/nel/src/gui/view_base.cpp index 05d958d3e..2b09061a9 100644 --- a/code/nel/src/gui/view_base.cpp +++ b/code/nel/src/gui/view_base.cpp @@ -57,7 +57,7 @@ namespace NLGUI { if( editorMode ) { - CWidgetManager::getInstance()->setCurrentEditorSelection( getId() ); + CWidgetManager::getInstance()->selectWidget( getId() ); return true; } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c26a23231..6ee1588c3 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2077,9 +2077,9 @@ namespace NLGUI if( CInterfaceElement::getEditorMode() ) { - if( !currentEditorSelection.empty() ) + for( int i = 0; i < editorSelection.size(); i++ ) { - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); if( e != NULL ) e->drawHighlight(); } @@ -2478,7 +2478,7 @@ namespace NLGUI else { if( CInterfaceElement::getEditorMode() ) - setCurrentEditorSelection( "" ); + clearEditorSelection(); } } @@ -3349,25 +3349,53 @@ namespace NLGUI } } + void CWidgetManager::getEditorSelection( std::vector< std::string > &selection ) + { + selection.clear(); + for( int i = 0; i < editorSelection.size(); i++ ) + selection.push_back( editorSelection[ i ] ); + } - void CWidgetManager::setCurrentEditorSelection( const std::string &name ) + void CWidgetManager::selectWidget( const std::string &name ) { + std::vector< std::string >::iterator itr + = std::find( editorSelection.begin(), editorSelection.end(), name ); + CInterfaceElement *e = getElementFromId( name ); - if( e != NULL ) + + if( itr != editorSelection.end() ) { - if( !currentEditorSelection.empty() ) + // If multiselection is on unselect if already selected + if( multiSelection ) { - CInterfaceElement *prev = getElementFromId( currentEditorSelection ); - if( prev != NULL ) - prev->setEditorSelected( false ); + editorSelection.erase( itr ); + if( e != NULL ) + e->setEditorSelected( false ); } - e->setEditorSelected( true ); } else - if( !name.empty() ) - return; - - currentEditorSelection = name; + { + // Select if not yet selected + if( e != NULL ) + { + // If multiselection is off, we can only have 1 widget selected + if( !multiSelection ) + { + editorSelection.clear(); + } + + e->setEditorSelected( true ); + editorSelection.push_back( name ); + } + + } + + notifySelectionWatchers(); + } + + void CWidgetManager::clearEditorSelection() + { + editorSelection.clear(); notifySelectionWatchers(); } @@ -3376,7 +3404,7 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* >::iterator itr = selectionWatchers.begin(); while( itr != selectionWatchers.end() ) { - (*itr)->selectionChanged( currentEditorSelection ); + (*itr)->selectionChanged(); ++itr; } } @@ -3484,11 +3512,11 @@ namespace NLGUI bool CWidgetManager::unGroupSelection() { - if( currentEditorSelection.empty() ) + if( editorSelection.size() != 1 ) return false; // Does the element exist? - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ 0 ] ); if( e == NULL ) return false; @@ -3509,7 +3537,7 @@ namespace NLGUI p->delElement( g ); - setCurrentEditorSelection( "" ); + clearEditorSelection(); p->updateCoords(); @@ -3554,8 +3582,8 @@ namespace NLGUI setScreenWH( 0, 0 ); - currentEditorSelection = ""; groupSelection = false; + multiSelection = false; } CWidgetManager::~CWidgetManager() @@ -3569,6 +3597,8 @@ namespace NLGUI curContextHelp = NULL; CStringShared::deleteStringMapper(); + + editorSelection.clear(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 4c48a4fa4..a818cf174 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -25,35 +25,40 @@ namespace GUIEditor { void CEditorMessageProcessor::onDelete() { - std::string selection = CWidgetManager::getInstance()->getCurrentEditorSelection(); + std::vector< std::string > selection; + + CWidgetManager::getInstance()->getEditorSelection( selection ); if( selection.empty() ) return; QMessageBox::StandardButton r = QMessageBox::question( NULL, tr( "Deleting widget" ), - tr( "Are you sure you want to delete %1?" ).arg( selection.c_str() ), + tr( "Are you sure you want to delete these?" ), QMessageBox::Yes | QMessageBox::No ); if( r != QMessageBox::Yes ) return; - CInterfaceElement *e = - CWidgetManager::getInstance()->getElementFromId( selection ); - if( e == NULL ) - return; + for( int i = 0; i < selection.size(); i++ ) + { + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ i ] ); + if( e == NULL ) + continue; - CInterfaceElement *p = e->getParent(); - if( p == NULL ) - return; - - CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); - if( g == NULL ) - return; + CInterfaceElement *p = e->getParent(); + if( p == NULL ) + continue; + + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); + if( g == NULL ) + continue; + + g->delElement( e ); - if( g->delElement( e ) ) - { - CWidgetManager::getInstance()->setCurrentEditorSelection( "" ); } + + + CWidgetManager::getInstance()->clearEditorSelection(); } void CEditorMessageProcessor::onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ) @@ -147,5 +152,10 @@ namespace GUIEditor tr( "Couldn't ungroup widgets." ) ); } } + + void CEditorMessageProcessor::onSetMultiSelection( bool b ) + { + CWidgetManager::getInstance()->setMultiSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 9e6d3cf89..c3483e2ef 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -40,6 +40,7 @@ namespace GUIEditor void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); void onUngroup(); + void onSetMultiSelection( bool b ); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp index ee3a079ad..7647c8abb 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp @@ -18,9 +18,9 @@ namespace GUIEditor { - void CEditorSelectionWatcher::selectionChanged( std::string &newSelection ) + void CEditorSelectionWatcher::selectionChanged() { - Q_EMIT sgnSelectionChanged( newSelection ); + Q_EMIT sgnSelectionChanged(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h index 61218c0cd..2eab68310 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h @@ -27,10 +27,10 @@ namespace GUIEditor public: CEditorSelectionWatcher() : QObject( NULL ){} - void selectionChanged( std::string &newSelection ); + void selectionChanged(); Q_SIGNALS: - void sgnSelectionChanged( std::string &id ); + void sgnSelectionChanged(); }; } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 01433bf9e..6cc072ce8 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -283,8 +283,8 @@ namespace GUIEditor CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); projectFiles.clearAll(); projectWindow->clear(); @@ -322,8 +322,8 @@ namespace GUIEditor linkList->onGUILoaded(); CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); } void GUIEditorWindow::onAddWidgetClicked() @@ -413,6 +413,12 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); m->addAction( a ); + a = new QAction( "Multiselect", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetMultiSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index c005f80e5..84302bcf0 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -436,7 +436,7 @@ namespace GUIEditor browser->clear(); } - void CPropBrowserCtrl::onSelectionChanged( std::string &id ) + void CPropBrowserCtrl::onSelectionChanged() { if( browser == NULL ) return; @@ -444,14 +444,20 @@ namespace GUIEditor disablePropertyWatchers(); browser->clear(); - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( id ); + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { enablePropertyWatchers(); return; } - currentElement = id; + currentElement = selection[ 0 ]; std::string n = e->getClassName(); diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h index abf80d7de..3d72d92ba 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h @@ -59,7 +59,7 @@ namespace GUIEditor void clear(); public Q_SLOTS: - void onSelectionChanged( std::string &id ); + void onSelectionChanged(); private Q_SLOTS: void onPropertyChanged( QtProperty *prop, const QVariant &v ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 1439fea9e..343d8efd8 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -304,14 +304,15 @@ namespace GUIEditor void WidgetHierarchy::getCurrentGroup( QString &g ) { - std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); - if( s.empty() ) + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + if( selection.size() != 1 ) { g = ""; return; } - NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( s ); + NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { g = ""; @@ -342,8 +343,16 @@ namespace GUIEditor currentSelection.clear(); } - void WidgetHierarchy::onSelectionChanged( std::string &newSelection ) + void WidgetHierarchy::onSelectionChanged() { + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + std::string newSelection = selection[ 0 ]; + if( newSelection == currentSelection ) return; @@ -376,6 +385,6 @@ namespace GUIEditor std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); - CWidgetManager::getInstance()->setCurrentEditorSelection( currentSelection ); + CWidgetManager::getInstance()->selectWidget( currentSelection ); } } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 27218715d..cdfc9a741 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -56,7 +56,7 @@ namespace GUIEditor public Q_SLOTS: void onGUILoaded(); - void onSelectionChanged( std::string &newSelection ); + void onSelectionChanged(); private Q_SLOTS: void onItemDblClicked( QTreeWidgetItem *item ); From 7b45a05562ac762d5022104d5741fc59ae8f434d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 00:42:43 +0200 Subject: [PATCH 220/240] Added support for grouping widgets. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 6 ++ code/nel/include/nel/gui/widget_manager.h | 6 +- code/nel/src/gui/interface_group.cpp | 46 ++++++++++++++ code/nel/src/gui/widget_manager.cpp | 63 ++++++++++++++++++- .../gui_editor/editor_message_processor.cpp | 5 ++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index cdfd182e7..b9efd3357 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -333,6 +333,12 @@ namespace NLGUI // Blows up the group, moves it's children to it's parent bool explode(); + /// Adjusts the group's size so that all elements are fully inside the borders + void spanElements(); + + /// Aligns the elements - used for forming groups + void alignElements(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 243847ad7..d722a9165 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -524,7 +524,8 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); - void setGroupSelection( bool b ){ groupSelection = b; } + void setGroupSelection( bool b ){ _GroupSelection = b; } + bool groupSelection(); bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } @@ -620,8 +621,9 @@ namespace NLGUI std::vector< IWidgetWatcher* > widgetWatchers; std::vector< std::string > editorSelection; - bool groupSelection; + bool _GroupSelection; bool multiSelection; + uint32 _WidgetCount; }; } diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 516a2f6aa..29ad75f8c 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2594,5 +2594,51 @@ namespace NLGUI return true; } + + void CInterfaceGroup::spanElements() + { + sint32 minx = std::numeric_limits< sint32 >::max(); + sint32 miny = std::numeric_limits< sint32 >::max(); + sint32 maxx = std::numeric_limits< sint32 >::min(); + sint32 maxy = std::numeric_limits< sint32 >::min(); + + sint32 tlx,tly,brx,bry; + + // Find the min and max coordinates of the elements + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + + v->getHSCoords( Hotspot_TL, tlx, tly ); + v->getHSCoords( Hotspot_BR, brx, bry ); + + if( tlx < minx ) + minx = tlx; + if( brx > maxx ) + maxx = brx; + if( bry < miny ) + miny = bry; + if( tly > maxy ) + maxy = tly; + } + + // Set the position and the width and height based on these coords + setW( maxx - minx ); + setH( maxy - miny ); + _WReal = getW(); + _HReal = getH(); + _XReal = minx; + _YReal = miny; + } + + void CInterfaceGroup::alignElements() + { + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->alignTo( this ); + } + } + } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 6ee1588c3..e2689f5a0 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() && groupSelection ) + if( CInterfaceElement::getEditorMode() && _GroupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3510,6 +3510,64 @@ namespace NLGUI return v; } + bool CWidgetManager::groupSelection() + { + std::vector< CInterfaceElement* > elms; + + // Resolve the widget names + for( int i = 0; i < editorSelection.size(); i++ ) + { + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); + if( e != NULL ) + elms.push_back( e ); + } + + editorSelection.clear(); + + if( elms.empty() ) + return false; + + // Create the group as the subgroup of the top window + CInterfaceGroup *g = static_cast< CInterfaceGroup* >( getParser()->createClass( "interface_group" ) ); + getTopWindow()->addGroup( g ); + g->setParent( getTopWindow() ); + g->setIdRecurse( std::string( "group" ) + NLMISC::toString( _WidgetCount ) ); + _WidgetCount++; + onWidgetAdded( g->getId() ); + + std::string oldId; + + // Reparent the widgets to the new group + for( int i = 0; i < elms.size(); i++ ) + { + CInterfaceElement *e = elms[ i ]; + oldId = e->getId(); + CInterfaceGroup *p = e->getParent(); + if( p != NULL ) + p->takeElement( e ); + + g->addElement( e ); + e->setParent( g ); + e->setParentPos( g ); + e->setParentSize( g ); + e->setIdRecurse( e->getShortId() ); + + onWidgetMoved( oldId, e->getId() ); + } + elms.clear(); + + // Make sure widgets aren't clipped because the group isn't big enough + g->spanElements(); + // Make sure widgets are aligned + g->alignElements(); + // Align the new group to the top window + g->alignTo( getTopWindow() ); + + g->setActive( true ); + + return true; + } + bool CWidgetManager::unGroupSelection() { if( editorSelection.size() != 1 ) @@ -3582,8 +3640,9 @@ namespace NLGUI setScreenWH( 0, 0 ); - groupSelection = false; + _GroupSelection = false; multiSelection = false; + _WidgetCount = 0; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index a818cf174..ef99c87fc 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -141,6 +141,11 @@ namespace GUIEditor CWidgetManager::getInstance()->setGroupSelection( b ); } + void CEditorMessageProcessor::onGroup() + { + CWidgetManager::getInstance()->groupSelection(); + } + void CEditorMessageProcessor::onUngroup() { bool ok = CWidgetManager::getInstance()->unGroupSelection(); diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index c3483e2ef..ee55fcda7 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onGroup(); void onUngroup(); void onSetMultiSelection( bool b ); diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 6cc072ce8..ca5e240e7 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Group", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onGroup() ) ); + m->addAction( a ); + a = new QAction( "Ungroup", this ); connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); m->addAction( a ); From fe89e8f77cf197ce39689c1385203b8581cbbd0b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 13:04:03 +0200 Subject: [PATCH 221/240] Added limits to pch, should fix Linux build. --HG-- branch : dfighter-tools --- code/nel/src/gui/group_editbox.cpp | 1 - code/nel/src/gui/stdpch.h | 1 + code/nel/src/gui/view_text.cpp | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index ba65a07c4..92ae46703 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -28,7 +28,6 @@ #include "nel/gui/view_renderer.h" #include "nel/gui/db_manager.h" #include "nel/gui/interface_factory.h" -#include using namespace std; using namespace NLMISC; diff --git a/code/nel/src/gui/stdpch.h b/code/nel/src/gui/stdpch.h index bb983f77c..3270e6482 100644 --- a/code/nel/src/gui/stdpch.h +++ b/code/nel/src/gui/stdpch.h @@ -18,6 +18,7 @@ #define NELGUI_H #include +#include #include "nel/misc/types_nl.h" #include "nel/misc/algo.h" diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 743ba4ce7..815007723 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -28,8 +28,6 @@ #include "nel/gui/lua_ihm.h" #include "nel/gui/view_pointer_base.h" -#include - using namespace std; using namespace NLMISC; using namespace NL3D; From 2de4315027376e15b00075ac076c3370313d536f Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 12 Oct 2014 17:43:18 +0300 Subject: [PATCH 222/240] Fix table cellpadding --HG-- branch : html-table-rendering --- code/nel/src/gui/group_table.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 2fdd7e364..ffebca4ea 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -937,10 +937,10 @@ namespace NLGUI } } - cell->setX(currentX); - cell->setW(_Columns[column].Width); + cell->setX(currentX - CellPadding); + cell->setW(_Columns[column].Width + CellPadding*2); - cell->Group->setX(alignmentX+cell->LeftMargin); + cell->Group->setX(alignmentX + cell->LeftMargin + CellPadding); cell->Group->setW(_Columns[column].Width - widthReduceX); cell->Group->CInterfaceElement::updateCoords(); @@ -989,9 +989,9 @@ namespace NLGUI } } - cell->setY(currentY); - cell->setH (_Rows[row].Height); - cell->Group->setY(-alignmentY); + cell->setY(currentY + CellPadding); + cell->setH (_Rows[row].Height + 2*CellPadding); + cell->Group->setY(-(alignmentY + CellPadding)); } // Resize the table @@ -1179,7 +1179,7 @@ namespace NLGUI if (!_Columns.empty() && !_Rows.empty() && BgColor.A) { - sint32 border = Border + CellSpacing + CellPadding; + sint32 border = Border + CellSpacing; if (border) { CRGBA finalColor; @@ -1197,20 +1197,20 @@ namespace NLGUI rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-border, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); // Draw the inside borders - sint32 insideWidth = 2*CellPadding + CellSpacing; + sint32 insideWidth = CellSpacing; if (insideWidth) { // Draw the inside verticals uint i; - sint32 x = _XReal + _Columns[0].Width + border; + sint32 x = _XReal + border + _Columns[0].Width + 2*CellPadding; for (i=1; i<_Columns.size(); i++) { rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal+border, insideWidth, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[i].Width + insideWidth; + x += _Columns[i].Width + 2*CellPadding + insideWidth; } // Draw the inside horizontals - sint32 y = _YReal + _HReal - border - _Rows[0].Height; + sint32 y = _YReal + _HReal - border - _Rows[0].Height - 2*CellPadding; if (_Rows[0].Height != 0) { y -= insideWidth; @@ -1223,10 +1223,10 @@ namespace NLGUI { for (j=0; j<_Columns.size(); j++) { - rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[j].Width + insideWidth; + rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width + 2*CellPadding, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); + x += _Columns[j].Width + 2*CellPadding + insideWidth; } - y -= _Rows[i].Height+ insideWidth; + y -= _Rows[i].Height + insideWidth + 2*CellPadding; } } } From 283cbe8092cd04343db4155c1d1e97332853f3f8 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 13 Oct 2014 01:10:46 +0300 Subject: [PATCH 223/240] Add bordercolor attribute to table tag --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 1 + code/nel/include/nel/gui/libwww.h | 1 + code/nel/src/gui/group_html.cpp | 2 ++ code/nel/src/gui/group_table.cpp | 21 +++++++++++++++++++++ code/nel/src/gui/libwww.cpp | 1 + 5 files changed, 26 insertions(+) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index 60d3d9e63..f41b1c074 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -142,6 +142,7 @@ namespace NLGUI // Table borders sint32 Border; + NLMISC::CRGBA BorderColor; sint32 CellPadding; sint32 CellSpacing; diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index ec23cafd2..6a744b8c0 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -79,6 +79,7 @@ namespace NLGUI HTML_ATTR(TABLE,ALIGN) = 0, HTML_ATTR(TABLE,BGCOLOR), HTML_ATTR(TABLE,BORDER), + HTML_ATTR(TABLE,BORDERCOLOR), HTML_ATTR(TABLE,CELLPADDING), HTML_ATTR(TABLE,CELLSPACING), HTML_ATTR(TABLE,CLASS), diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 1a2ae5b4b..56398a10a 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1453,6 +1453,8 @@ namespace NLGUI getPercentage (table->ForceWidthMin, table->TableRatio, value[MY_HTML_TABLE_WIDTH]); if (present[MY_HTML_TABLE_BORDER] && value[MY_HTML_TABLE_BORDER]) fromString(value[MY_HTML_TABLE_BORDER], table->Border); + if (present[MY_HTML_TABLE_BORDERCOLOR] && value[MY_HTML_TABLE_BORDERCOLOR]) + table->BorderColor = getColor (value[MY_HTML_TABLE_BORDERCOLOR]); if (present[MY_HTML_TABLE_CELLSPACING] && value[MY_HTML_TABLE_CELLSPACING]) fromString(value[MY_HTML_TABLE_CELLSPACING], table->CellSpacing); if (present[MY_HTML_TABLE_CELLPADDING] && value[MY_HTML_TABLE_CELLPADDING]) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index ffebca4ea..d7933b934 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -559,6 +559,7 @@ namespace NLGUI TableRatio = 0.f; ForceWidthMin = 0; Border=0; + BorderColor = CRGBA(127, 127, 127, 255); CellPadding=0; CellSpacing=0; ContinuousUpdate = false; @@ -1243,6 +1244,11 @@ namespace NLGUI return toString( Border ); } else + if( name == "bordercolor" ) + { + return toString( BorderColor ); + } + else if( name == "cellpadding" ) { return toString( CellPadding ); @@ -1279,6 +1285,14 @@ namespace NLGUI return; } else + if( name == "bordercolor" ) + { + CRGBA c; + if( fromString( value, c ) ) + BorderColor = c; + return; + } + else if( name == "cellpadding" ) { sint32 i; @@ -1321,6 +1335,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "type", BAD_CAST "table" ); xmlSetProp( node, BAD_CAST "border", BAD_CAST toString( Border ).c_str() ); + xmlSetProp( node, BAD_CAST "bordercolor", BAD_CAST toString( BorderColor ).c_str() ); xmlSetProp( node, BAD_CAST "cellpadding", BAD_CAST toString( CellPadding ).c_str() ); xmlSetProp( node, BAD_CAST "cellspacing", BAD_CAST toString( CellSpacing ).c_str() ); xmlSetProp( node, BAD_CAST "bgcolor", BAD_CAST toString( BgColor ).c_str() ); @@ -1345,6 +1360,12 @@ namespace NLGUI fromString((const char*)ptr, Border); } // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"bordercolor" ); + if (ptr) + { + BorderColor = convertColor((const char*)ptr); + } + // ptr = (char*) xmlGetProp( cur, (xmlChar*)"cellpadding" ); if (ptr) { diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp index 0b759a7aa..b17d1cccb 100644 --- a/code/nel/src/gui/libwww.cpp +++ b/code/nel/src/gui/libwww.cpp @@ -86,6 +86,7 @@ namespace NLGUI HTML_ATTR(TABLE,ALIGN), HTML_ATTR(TABLE,BGCOLOR), HTML_ATTR(TABLE,BORDER), + HTML_ATTR(TABLE,BORDERCOLOR), HTML_ATTR(TABLE,CELLPADDING), HTML_ATTR(TABLE,CELLSPACING), HTML_ATTR(TABLE,CLASS), From 11927cca93289628c6b9d5e77e3804900670c141 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 13 Oct 2014 01:59:20 +0300 Subject: [PATCH 224/240] Render table and cell borders --HG-- branch : html-table-rendering --- code/nel/src/gui/group_table.cpp | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index d7933b934..7c6a95b24 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -499,6 +499,29 @@ namespace NLGUI } } + // Get the parent table + if (getParent ()) + { + CGroupTable *table = static_cast (getParent ()); + if (table->Border) { + CRGBA lighter = blend(table->BorderColor, CRGBA::White, 0.5f); + + CRGBA borderColorTL; + borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); + borderColorTL.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorTL.A) >> 8); + + CRGBA borderColorBR; + borderColorBR.modulateFromColor (table->BorderColor, CWidgetManager::getInstance()->getGlobalColor()); + borderColorBR.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorBR.A) >> 8); + + CViewRenderer &rVR = *CViewRenderer::getInstance(); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorTL ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorBR ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_HReal-1, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorBR ); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-1, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorTL ); + } + } + CInterfaceGroup::draw (); } @@ -1178,10 +1201,10 @@ namespace NLGUI if (gr == NULL) CurrentAlpha = 255; - if (!_Columns.empty() && !_Rows.empty() && BgColor.A) + if (!_Columns.empty() && !_Rows.empty()) { sint32 border = Border + CellSpacing; - if (border) + if (border && BgColor.A) { CRGBA finalColor; finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); @@ -1232,6 +1255,29 @@ namespace NLGUI } } } + + if (Border) { + CViewRenderer &rVR = *CViewRenderer::getInstance(); + + CRGBA borderColorTL; + CRGBA lighter = blend(BorderColor, CRGBA::White, 0.5f); + borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); + borderColorTL.A = CurrentAlpha; + + CRGBA borderColorBR; + borderColorBR.modulateFromColor (BorderColor, CWidgetManager::getInstance()->getGlobalColor()); + borderColorBR.A = CurrentAlpha; + + // beveled table border + for (sint32 i=0; i Date: Tue, 14 Oct 2014 15:26:14 +0300 Subject: [PATCH 225/240] Add rowspan and colspan attributes --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 2 ++ code/nel/src/gui/group_html.cpp | 8 ++++++ code/nel/src/gui/group_table.cpp | 36 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index f41b1c074..f161c04f9 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -78,6 +78,8 @@ namespace NLGUI // The Width you want in pixel. This is the parameter sint32 WidthWanted; + sint32 ColSpan; + sint32 RowSpan; // The min height of the cell sint32 Height; diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 56398a10a..6266ea769 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1519,11 +1519,19 @@ namespace NLGUI } } } + + if (present[MY_HTML_TD_COLSPAN] && value[MY_HTML_TD_COLSPAN]) + fromString(value[MY_HTML_TD_COLSPAN], _Cells.back()->ColSpan); + if (present[MY_HTML_TD_ROWSPAN] && value[MY_HTML_TD_ROWSPAN]) + fromString(value[MY_HTML_TD_ROWSPAN], _Cells.back()->RowSpan); + _Cells.back()->BgColor = _CellParams.back().BgColor; _Cells.back()->Align = _CellParams.back().Align; _Cells.back()->VAlign = _CellParams.back().VAlign; _Cells.back()->LeftMargin = _CellParams.back().LeftMargin; _Cells.back()->NoWrap = _CellParams.back().NoWrap; + _Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan); + _Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan); float temp; if (present[MY_HTML_TD_WIDTH] && value[MY_HTML_TD_WIDTH]) diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 7c6a95b24..677260dbb 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -44,6 +44,8 @@ namespace NLGUI TableRatio = 0.f; WidthWanted = 0; Height = 0; + ColSpan = 1; + RowSpan = 1; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; VAlign = Top; @@ -249,6 +251,22 @@ namespace NLGUI AddChildW = b; return; } + else + if (name == "colspan" ) + { + sint32 i; + if (fromString( value, i ) ) + ColSpan = std::max(1, i); + return; + } + else + if (name == "rowspan" ) + { + sint32 i; + if (fromString( value, i ) ) + RowSpan = std::max(1, i); + return; + } else CInterfaceGroup::setProperty( name, value ); } @@ -310,6 +328,8 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "ignore_max_width", BAD_CAST toString( IgnoreMaxWidth ).c_str() ); xmlSetProp( node, BAD_CAST "ignore_min_width", BAD_CAST toString( IgnoreMinWidth ).c_str() ); xmlSetProp( node, BAD_CAST "add_child_w", BAD_CAST toString( AddChildW ).c_str() ); + xmlSetProp( node, BAD_CAST "colspan", BAD_CAST toString( ColSpan ).c_str() ); + xmlSetProp( node, BAD_CAST "rowspan", BAD_CAST toString( RowSpan ).c_str() ); return node; } @@ -422,6 +442,22 @@ namespace NLGUI { AddChildW = convertBool(ptr); } + // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"colspan" ); + if (ptr) + { + sint32 i; + if (fromString((const char*)ptr, i)) + ColSpan = std::max(1, i); + } + // + ptr = (char*) xmlGetProp( cur, (xmlChar*)"rowspan" ); + if (ptr) + { + sint32 i; + if (fromString((const char*)ptr, i)) + RowSpan = std::max(1, i); + } return true; } From 799705b7edec693fcf295fc8731338ab2798da2b Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 14 Oct 2014 15:29:06 +0300 Subject: [PATCH 226/240] Render table with rowspan, colspan. Borders, if enabled, adds +1 to cell padding. --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_table.h | 4 +- code/nel/src/gui/group_table.cpp | 203 ++++++++++++++++--------- 2 files changed, 135 insertions(+), 72 deletions(-) diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index f161c04f9..746078908 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -80,6 +80,7 @@ namespace NLGUI sint32 ColSpan; sint32 RowSpan; + sint32 TableColumnIndex; // The min height of the cell sint32 Height; @@ -194,13 +195,14 @@ namespace NLGUI WidthMax = 0; WidthWanted = 0; TableRatio = 0; - Height = 0; + RowSpan = 1; } sint32 Width; sint32 Height; sint32 WidthWanted; sint32 WidthMax; float TableRatio; + sint32 RowSpan; }; // Table row diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 677260dbb..386cbacbd 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -46,6 +46,7 @@ namespace NLGUI Height = 0; ColSpan = 1; RowSpan = 1; + TableColumnIndex = 0; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; VAlign = Top; @@ -618,7 +619,7 @@ namespace NLGUI TableRatio = 0.f; ForceWidthMin = 0; Border=0; - BorderColor = CRGBA(127, 127, 127, 255); + BorderColor = CRGBA(32, 32, 32, 255); CellPadding=0; CellSpacing=0; ContinuousUpdate = false; @@ -752,35 +753,75 @@ namespace NLGUI // New cell ? if (cell->NewLine) + { + while (column < _Columns.size()) + { + if (_Columns[column].RowSpan > 1) + _Columns[column].RowSpan--; + column++; + } column = 0; + } // Resize the array if (column>=_Columns.size()) _Columns.resize(column+1); + // Handle rowspan from previous row + while (_Columns[column].RowSpan > 1) + { + _Columns[column].RowSpan--; + column++; + // if previous row had less elements, then we missing columns + if (column>=_Columns.size()) + _Columns.resize(column+1); + } + + // remember column index for later use + cell->TableColumnIndex = column; + + // new column, set rowspan from current + _Columns[column].RowSpan = cell->RowSpan; + float colspan = 1.f / cell->ColSpan; + float rowspan = 1.f / cell->RowSpan; + // Update sizes - if (cellWidth > _Columns[column].Width) - _Columns[column].Width = cellWidth; - if (cell->WidthMax > _Columns[column].WidthMax) - _Columns[column].WidthMax = cell->WidthMax; - if (cell->TableRatio > _Columns[column].TableRatio) - _Columns[column].TableRatio = cell->TableRatio; - if (cell->WidthWanted + additionnalWidth > _Columns[column].WidthWanted) - _Columns[column].WidthWanted = cell->WidthWanted + additionnalWidth; - if (cell->Height > _Columns[column].Height) - _Columns[column].Height = cell->Height; + if (cellWidth*colspan > _Columns[column].Width) + _Columns[column].Width = cellWidth*colspan; + if (cell->WidthMax*colspan > _Columns[column].WidthMax) + _Columns[column].WidthMax = cell->WidthMax*colspan; + if (cell->TableRatio*colspan > _Columns[column].TableRatio) + _Columns[column].TableRatio = cell->TableRatio*colspan; + if (cell->WidthWanted*colspan + additionnalWidth > _Columns[column].WidthWanted) + _Columns[column].WidthWanted = (sint32)(cell->WidthWanted*colspan) + additionnalWidth; if (_Columns[column].WidthWanted + additionnalWidth) _Columns[column].WidthMax = _Columns[column].WidthWanted + additionnalWidth; if (_Columns[column].WidthWanted > _Columns[column].Width) _Columns[column].Width = _Columns[column].WidthWanted; + if (cell->ColSpan > 1) { + // copy this info to all spanned columns, create new columns as needed + uint newsize = column + cell->ColSpan - 1; + if (newsize >= _Columns.size()) + _Columns.resize(newsize+1); + for(uint span = 0; span < cell->ColSpan -1; span++){ + column++; + _Columns[column].Width = _Columns[column-1].Width; + _Columns[column].WidthMax = _Columns[column-1].WidthMax; + _Columns[column].TableRatio = _Columns[column-1].TableRatio; + _Columns[column].WidthWanted = _Columns[column-1].WidthWanted; + _Columns[column].RowSpan = _Columns[column-1].RowSpan; + } + } + // Next column column++; } // Width of cells and table borders - sint32 borderWidth = 2*Border + ((sint32)_Columns.size()+1) * CellSpacing + ((sint32)_Columns.size()*2) * CellPadding; + sint32 padding = CellPadding + (Border ? 1 : 0); + sint32 borderWidth = 2*Border + ((sint32)_Columns.size()+1) * CellSpacing + ((sint32)_Columns.size()*2) * padding; // Get the width sint32 tableWidthMax = ForceWidthMin?ForceWidthMin:_LastParentW; // getWReal(); @@ -862,7 +903,6 @@ namespace NLGUI // Some space ? space = finalWidth - tableWidth; - if (space > 0) { // Then add in wanted Width cells @@ -952,6 +992,18 @@ namespace NLGUI } } } + + // If there is still space left, then sum up column widths + // and add all the remaining space to final column. + if (space > 0) + { + sint32 innerWidth = 0; + for(i=0;i<_Columns.size();i++) + innerWidth += _Columns[i].Width; + + if (innerWidth > 0 && finalWidth > innerWidth) + _Columns[_Columns.size()-1].Width += finalWidth - innerWidth; + } } } } @@ -962,7 +1014,8 @@ namespace NLGUI column = 0; sint32 row = 0; - sint32 currentX = Border + CellSpacing + CellPadding; + sint32 currentX = Border + CellSpacing + padding; + _Rows.clear (); for (i=0; i<_Cells.size(); i++) { @@ -971,25 +1024,41 @@ namespace NLGUI if (cell->NewLine) { column = 0; - currentX = Border + CellSpacing + CellPadding; + currentX = Border + CellSpacing + padding; + _Rows.push_back(CRow()); } + if (cell->TableColumnIndex > 0) + { + // we have active rowspan, must add up 'skipped' columns + for( ; columnTableColumnIndex; column++) + currentX += _Columns[column].Width + padding*2 + CellSpacing; + } + // Set the x and width // Check align sint32 alignmentX = 0; sint32 widthReduceX = 0; - if (cell->WidthMax < _Columns[column].Width) + sint32 columnWidth = _Columns[column].Width; + if (cell->ColSpan > 1) + { + // scan ahead and add up column widths as they might be different + for(int j = 1; jColSpan; j++) + columnWidth += CellSpacing + padding*2 + _Columns[column+j].Width; + } + + if (cell->WidthMax < columnWidth) { switch (cell->Align) { case CGroupCell::Center: - alignmentX = (_Columns[column].Width - cell->WidthMax) / 2; + alignmentX = (columnWidth - cell->WidthMax) / 2; widthReduceX = alignmentX * 2; break; case CGroupCell::Right: - alignmentX = _Columns[column].Width - cell->WidthMax; + alignmentX = columnWidth - cell->WidthMax; widthReduceX = alignmentX; break; default: @@ -997,11 +1066,11 @@ namespace NLGUI } } - cell->setX(currentX - CellPadding); - cell->setW(_Columns[column].Width + CellPadding*2); + cell->setX(currentX - padding); + cell->setW(columnWidth + padding*2); - cell->Group->setX(alignmentX + cell->LeftMargin + CellPadding); - cell->Group->setW(_Columns[column].Width - widthReduceX); + cell->Group->setX(alignmentX + cell->LeftMargin + padding); + cell->Group->setW(columnWidth - widthReduceX); cell->Group->CInterfaceElement::updateCoords(); // Update coords to get H @@ -1009,16 +1078,17 @@ namespace NLGUI cell->Group->updateCoords(); // Resize the row array - _Rows.back().Height = std::max(cell->Height, std::max(_Rows.back().Height, (sint32)cell->Group->getH())); + float rowspan = 1 / cell->RowSpan; + _Rows.back().Height = std::max((sint32)(cell->Height*rowspan), std::max(_Rows.back().Height, (sint32)(cell->Group->getH()*rowspan))); // Next column - currentX += _Columns[column].Width + 2*CellPadding + CellSpacing; - column ++; + currentX += columnWidth + 2*padding + CellSpacing; + column += cell->ColSpan; } // Set cell Y row = 0; - sint32 currentY = -(Border + CellSpacing + CellPadding); + sint32 currentY = -(Border + CellSpacing + padding); for (i=0; i<_Cells.size(); i++) { // New cell ? @@ -1027,37 +1097,45 @@ namespace NLGUI { if (_Rows[row].Height != 0) { - currentY -= _Rows[row].Height + 2*CellPadding + CellSpacing; + currentY -= _Rows[row].Height + 2*padding + CellSpacing; } row++; } // Check align sint32 alignmentY = 0; - if ((sint32)cell->Group->getH() < _Rows[row].Height) + sint32 rowHeight = _Rows[row].Height; + if (cell->RowSpan > 1) + { + // we need to scan down and add up row heights + int k = std::min((sint32)_Rows.size(), row + cell->RowSpan); + for(int j=row+1; jGroup->getH() < rowHeight) { switch (cell->VAlign) { case CGroupCell::Middle: - alignmentY = (_Rows[row].Height - (sint32)cell->Group->getH()) / 2; + alignmentY = (rowHeight - (sint32)cell->Group->getH()) / 2; break; case CGroupCell::Bottom: - alignmentY = _Rows[row].Height - (sint32)cell->Group->getH(); + alignmentY = rowHeight - (sint32)cell->Group->getH(); break; default: break; } } - cell->setY(currentY + CellPadding); - cell->setH (_Rows[row].Height + 2*CellPadding); - cell->Group->setY(-(alignmentY + CellPadding)); + cell->setY(currentY + padding); + cell->setH (rowHeight + 2*padding); + cell->Group->setY(-(alignmentY + padding)); } // Resize the table setW(finalWidth+borderWidth-_LastParentW); if (!_Rows.empty()) - currentY -= _Rows[row].Height + CellPadding + CellSpacing + Border; + currentY -= _Rows[row].Height + padding + CellSpacing + Border; setH(-currentY); // All done @@ -1246,53 +1324,35 @@ namespace NLGUI finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); finalColor.A = CurrentAlpha; - // Draw the top and bottom lines + // Draw the top line CViewRenderer &rVR = *CViewRenderer::getInstance(); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, border, 0, false, rVR.getBlankTextureId(), finalColor); rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal-border+_HReal, _WReal, border, 0, false, rVR.getBlankTextureId(), finalColor); - // Draw the left and right lines - sint32 insideHeight = std::max((sint32)0, (sint32)_HReal - (sint32)2*border); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-border, _YReal+border, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); + // Draw the left line + sint32 insideHeight = std::max((sint32)0, (sint32)_HReal - (sint32)border); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); // Draw the inside borders - sint32 insideWidth = CellSpacing; - if (insideWidth) + if (CellSpacing) { - // Draw the inside verticals uint i; - sint32 x = _XReal + border + _Columns[0].Width + 2*CellPadding; - for (i=1; i<_Columns.size(); i++) - { - rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal+border, insideWidth, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[i].Width + 2*CellPadding + insideWidth; - } - - // Draw the inside horizontals - sint32 y = _YReal + _HReal - border - _Rows[0].Height - 2*CellPadding; - if (_Rows[0].Height != 0) + sint32 x, y; + for (i=0; i<_Cells.size(); i++) { - y -= insideWidth; - } - for (i=1; i<_Rows.size(); i++) - { - uint j; - x = _XReal + border; - if (_Rows[i].Height != 0) - { - for (j=0; j<_Columns.size(); j++) - { - rVR.drawRotFlipBitmap (_RenderLayer, x, y, _Columns[j].Width + 2*CellPadding, insideWidth, 0, false, rVR.getBlankTextureId(), finalColor); - x += _Columns[j].Width + 2*CellPadding + insideWidth; - } - y -= _Rows[i].Height + insideWidth + 2*CellPadding; - } + CGroupCell *cell = _Cells[i]; + + x = cell->getXReal(); + y = cell->getYReal() - CellSpacing; + // right + rVR.drawRotFlipBitmap (_RenderLayer, x + cell->getW(), y, CellSpacing, cell->getH() + CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); + // bottom + rVR.drawRotFlipBitmap (_RenderLayer, x, y, cell->getW(), CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); } } - } - if (Border) { + } + if (Border) + { CViewRenderer &rVR = *CViewRenderer::getInstance(); CRGBA borderColorTL; @@ -1305,7 +1365,8 @@ namespace NLGUI borderColorBR.A = CurrentAlpha; // beveled table border - for (sint32 i=0; i Date: Wed, 15 Oct 2014 00:02:38 +0300 Subject: [PATCH 227/240] Change table defaults valign=middle, cellpadding=1, cellspacing=2 --HG-- branch : html-table-rendering --- code/nel/include/nel/gui/group_html.h | 2 +- code/nel/src/gui/group_table.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index ba34af2dd..21d609af3 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -528,7 +528,7 @@ namespace NLGUI CCellParams () : BgColor(0,0,0,0) { Align = CGroupCell::Left; - VAlign = CGroupCell::Top; + VAlign = CGroupCell::Middle; LeftMargin = 0; NoWrap = false; } diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 386cbacbd..65ed2d93d 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -49,7 +49,7 @@ namespace NLGUI TableColumnIndex = 0; Group = new CInterfaceGroup(CViewBase::TCtorParam()); Align = Left; - VAlign = Top; + VAlign = Middle; LeftMargin = 0; NoWrap = false; IgnoreMaxWidth = false; @@ -620,8 +620,8 @@ namespace NLGUI ForceWidthMin = 0; Border=0; BorderColor = CRGBA(32, 32, 32, 255); - CellPadding=0; - CellSpacing=0; + CellPadding=1; + CellSpacing=2; ContinuousUpdate = false; } From 48b346fed8fe4c26d5f5f6cd48f363e26cfcb925 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 18 Oct 2014 00:15:51 +0300 Subject: [PATCH 228/240] Fix crash when using textarea without form --HG-- branch : develop --- code/nel/src/gui/group_html.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 1a2ae5b4b..d42e1fed3 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1681,21 +1681,19 @@ namespace NLGUI break; case HTML_TEXTAREA: { - // Add the editbox - // nlinfo("textarea temp '%s'", _TextAreaTemplate.c_str()); - // nlinfo("textarea name '%s'", _TextAreaName.c_str()); - // nlinfo("textarea %d %d", _TextAreaRow, _TextAreaCols); - // nlinfo("textarea content '%s'", _TextAreaContent.toUtf8().c_str()); - CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); - if (textArea) + _TextArea = false; + if (!(_Forms.empty())) { - // Add the text area to the form - CGroupHTML::CForm::CEntry entry; - entry.Name = _TextAreaName; - entry.TextArea = textArea; - _Forms.back().Entries.push_back (entry); + CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength); + if (textArea) + { + // Add the text area to the form + CGroupHTML::CForm::CEntry entry; + entry.Name = _TextAreaName; + entry.TextArea = textArea; + _Forms.back().Entries.push_back (entry); + } } - _TextArea = false; } break; case HTML_TITLE: From 78e1bb6147b176b8bff9dd999daa0c5bad47a853 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 18 Oct 2014 01:20:56 +0300 Subject: [PATCH 229/240] Fix html img not showing on some cases, clean up addImage method --HG-- branch : develop --- code/nel/src/gui/group_html.cpp | 132 ++++++++++---------------------- 1 file changed, 39 insertions(+), 93 deletions(-) diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index d42e1fed3..7de0ab96b 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -3153,111 +3153,57 @@ namespace NLGUI void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg) { // In a paragraph ? - if (_Paragraph) + if (!_Paragraph) { - string finalUrl; + newParagraph (0); + paragraphChange (); + } + + string finalUrl; + // No more text in this text view + _CurrentViewLink = NULL; + + // Not added ? + CViewBitmap *newImage = new CViewBitmap (TCtorParam()); + + // + // 1/ try to load the image with the old system (local files in bnp) + // + string image = CFile::getPath(img) + CFile::getFilenameWithoutExtension(img) + ".tga"; + if (lookupLocalFile (finalUrl, image.c_str(), false)) + { + newImage->setRenderLayer(getRenderLayer()+1); + image = finalUrl; + } + else + { // - // 1/ try to load the image with the old system (local files in bnp) + // 2/ if it doesn't work, try to load the image in cache // - string image = CFile::getPath(img) + CFile::getFilenameWithoutExtension(img) + ".tga"; - if (lookupLocalFile (finalUrl, image.c_str(), false)) + image = localImageName(img); + if (!reloadImg && lookupLocalFile (finalUrl, image.c_str(), false)) { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - newImage->setRenderLayer(getRenderLayer()+1); - newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); + // don't display image that are not power of 2 + uint32 w, h; + CBitmap::loadSize (image, w, h); + if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) + image.clear(); } else { // - // 2/ if it doesn't work, try to load the image in cache + // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache // - image = localImageName(img); - if (!reloadImg && lookupLocalFile (finalUrl, image.c_str(), false)) - { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - - // don't display image that are not power of 2 - uint32 w, h; - CBitmap::loadSize (image, w, h); - if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) - image.clear(); - - newImage->setTexture (image); - // newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); - } - else - { - - // - // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache - // - image = "web_del.tga"; - if (lookupLocalFile (finalUrl, image.c_str(), false)) - { - // No more text in this text view - _CurrentViewLink = NULL; - - // Not added ? - CViewBitmap *newImage = new CViewBitmap (TCtorParam()); - /* todo link in image - if (getA()) - { - newImage->Link = getLink(); - newImage->setHTMLView (this); - }*/ - newImage->setTexture (image); - // newImage->setTexture (finalUrl); - newImage->setModulateGlobalColor(globalColor); - - addImageDownload(img, newImage); - - /* todo link in image - if (getA()) - getParagraph()->addChildLink(newImage); - else*/ - getParagraph()->addChild(newImage); - paragraphChange (); - } - } + image = "web_del.tga"; + addImageDownload(img, newImage); } } + newImage->setTexture (image); + newImage->setModulateGlobalColor(globalColor); + + getParagraph()->addChild(newImage); + paragraphChange (); } // *************************************************************************** From 933420690b1aedb07f489c51c617c884eb5c7cee Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:02:50 +0100 Subject: [PATCH 230/240] Change patchman example domain --HG-- branch : develop --- .../patchman_cfg/admin_install/bin/startup | 4 +- .../admin_install/bin/sync_rrd_graphs.sh | 2 +- .../admin_executor_service_default.mini01.cfg | 2 +- .../admin_executor_service_default.std01.cfg | 2 +- .../admin_install/patchman/patchman_list | 42 ++++---- .../patchman/patchman_service.default.cfg | 4 +- .../patchman/patchman_service.mini01.cfg | 4 +- .../patchman_service.mini01_bridge.cfg | 2 +- .../patchman/patchman_service.std01.cfg | 4 +- .../patchman/special_patchman_list | 6 +- .../admin_install/patchman_service_local.cfg | 2 +- .../server/patchman_cfg/shard_ctrl_mini01.txt | 30 +++--- .../server/patchman_cfg/shard_ctrl_std01.txt | 96 +++++++++---------- .../terminal_mini01/patchman_service.cfg | 4 +- 14 files changed, 102 insertions(+), 102 deletions(-) diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/startup b/code/ryzom/server/patchman_cfg/admin_install/bin/startup index 16bf59fd3..a63c6a3f7 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/startup +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/startup @@ -4,8 +4,8 @@ cd /srv/core rm */*.state */*/*.launch_ctrl */*/*.state /bin/bash /srv/core/bin/admin start -# special case for the "ep1.std01.ryzomcore.org" machine - start the admin tool graph sync script -if [ $(hostname) = "ep1.std01.ryzomcore.org" ] +# special case for the "ep1.std01.ryzomcore.local" machine - start the admin tool graph sync script +if [ $(hostname) = "ep1.std01.ryzomcore.local" ] then nohup /bin/sh /srv/core/bin/sync_rrd_graphs.sh & fi diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh b/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh index b23fc285b..cc78fbaf1 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/sync_rrd_graphs.sh @@ -4,7 +4,7 @@ echo Launched: $(date) while true do # retrieve ATS files from ATS admin tool machine - rsync -t ep1.std01.ryzomcore.org:ats/graph_datas/* /srv/core/mini01/rrd_graphs/ + rsync -t ep1.std01.ryzomcore.local:ats/graph_datas/* /srv/core/mini01/rrd_graphs/ # deal with live files - duplicate files that correspond to unique services to aid with graphing of su & co cd /srv/core/std01/rrd_graphs/ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg index bc7be84e9..0e8af6ed9 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.mini01.cfg @@ -10,7 +10,7 @@ AESAliasName= "aes"; DontUseStdIn = 0; // Adress ofthe admin service (default port is 49996) -ASHost = "ep1.mini01.ryzomcore.org"; +ASHost = "ep1.mini01.ryzomcore.local"; // Config for AES AESPort = "46712"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg index 7bfb80b27..7a4176b93 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/admin_executor_service_default.std01.cfg @@ -10,7 +10,7 @@ AESAliasName= "aes"; DontUseStdIn = 0; // Adress ofthe admin service (default port is 49996) -ASHost = "ep1.std01.ryzomcore.org"; +ASHost = "ep1.std01.ryzomcore.local"; // Config for AES AESPort = "46702"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list index e90230704..9a9341e9a 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_list @@ -1,23 +1,23 @@ // default values for different sites -mini01 ep1.mini01.ryzomcore.org -std01 ep1.std01.ryzomcore.org -std01 su1.std01.ryzomcore.org -std01 pd1.std01.ryzomcore.org -std01 pd2.std01.ryzomcore.org -std01 pd3.std01.ryzomcore.org -std01 pd4.std01.ryzomcore.org -std01 mla1.std01.ryzomcore.org -std01 mla2.std01.ryzomcore.org -std01 mla3.std01.ryzomcore.org -std01 mla4.std01.ryzomcore.org -std01 mla5.std01.ryzomcore.org -std01 mlb1.std01.ryzomcore.org -std01 mlb2.std01.ryzomcore.org -std01 mlb3.std01.ryzomcore.org -std01 mlb4.std01.ryzomcore.org -std01 mlb5.std01.ryzomcore.org -std01 rra1.std01.ryzomcore.org -std01 rra2.std01.ryzomcore.org -std01 rrb1.std01.ryzomcore.org -std01 rrb2.std01.ryzomcore.org +mini01 ep1.mini01.ryzomcore.local +std01 ep1.std01.ryzomcore.local +std01 su1.std01.ryzomcore.local +std01 pd1.std01.ryzomcore.local +std01 pd2.std01.ryzomcore.local +std01 pd3.std01.ryzomcore.local +std01 pd4.std01.ryzomcore.local +std01 mla1.std01.ryzomcore.local +std01 mla2.std01.ryzomcore.local +std01 mla3.std01.ryzomcore.local +std01 mla4.std01.ryzomcore.local +std01 mla5.std01.ryzomcore.local +std01 mlb1.std01.ryzomcore.local +std01 mlb2.std01.ryzomcore.local +std01 mlb3.std01.ryzomcore.local +std01 mlb4.std01.ryzomcore.local +std01 mlb5.std01.ryzomcore.local +std01 rra1.std01.ryzomcore.local +std01 rra2.std01.ryzomcore.local +std01 rrb1.std01.ryzomcore.local +std01 rrb2.std01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg index 981654046..184fca55a 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44752)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44752)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg index 41c283b63..0bd04c5eb 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg index 32166d6bf..737177202 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01_bridge.cfg @@ -43,7 +43,7 @@ StartCommands += // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "spm_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg index e8c2d5787..8fc5a64c9 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg @@ -10,7 +10,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway bridge_gw", "bridge_gw.transportAdd L3Client l3client", - "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44749)", + "bridge_gw.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44749)", //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ StartCommands = // Create a gateway module on layer 3 transport and open it "moduleManager.createModule StandardGateway spm_gw", "spm_gw.transportAdd L3Client l3client", - "spm_gw.transportCmd l3client(connect addr=ep1.std01.ryzomcore.org:44752)", + "spm_gw.transportCmd l3client(connect addr=ep1.std01.ryzomcore.local:44752)", //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list b/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list index b42636e55..bb1114027 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/special_patchman_list @@ -1,10 +1,10 @@ // mini01 - mini manager -mini01_spm ep1.mini01.ryzomcore.org -mini01_bridge ep1.mini01.ryzomcore.org +mini01_spm ep1.mini01.ryzomcore.local +mini01_bridge ep1.mini01.ryzomcore.local // std01 - std manager -std01_spm ep1.std01.ryzomcore.org +std01_spm ep1.std01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg index 45f2afe3f..5b2f35f5f 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman_service_local.cfg @@ -1 +1 @@ -SPAHost = "ep1.mini01.ryzomcore.org"; +SPAHost = "ep1.mini01.ryzomcore.local"; diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt index a17f6f922..e09f106ac 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_mini01.txt @@ -30,15 +30,15 @@ define domain_mini01 // domain hosts cfg AESHost = "localhost"; - cfg SUHost = "ep1.mini01.ryzomcore.org"; - cfg MFSHost = "ep1.mini01.ryzomcore.org"; - cfg BSHost = "ep1.mini01.ryzomcore.org:49990"; - cfg SlaveBSHost= "ep1.mini01.ryzomcore.org:49991"; - cfg MasterLGSHost = "ep1.mini01.ryzomcore.org"; - cfg SlaveLGSHost = "ep1.mini01.ryzomcore.org"; - cfg LGSBSHost = "ep1.mini01.ryzomcore.org"; - cfg DBHost = "localhost"; // FIXME "sql.core.ryzomcore.org"; - cfgAfter WebSrvHost = "http://ep1.mini01.ryzomcore.org:50000/"; + cfg SUHost = "ep1.mini01.ryzomcore.local"; + cfg MFSHost = "ep1.mini01.ryzomcore.local"; + cfg BSHost = "ep1.mini01.ryzomcore.local:49990"; + cfg SlaveBSHost= "ep1.mini01.ryzomcore.local:49991"; + cfg MasterLGSHost = "ep1.mini01.ryzomcore.local"; + cfg SlaveLGSHost = "ep1.mini01.ryzomcore.local"; + cfg LGSBSHost = "ep1.mini01.ryzomcore.local"; + cfg DBHost = "ep1.mini01.ryzomcore.local"; + cfgAfter WebSrvHost = "http://ep1.mini01.ryzomcore.local:50000/"; // initial config files cfgFile ../cfg/00_base.cfg @@ -84,7 +84,7 @@ define shard_mini01_unifier use exe_set_std_lgs_slave use backup_lgs cfg DBPass = DBNelPass; - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local // shard mainland01 ---------------- @@ -95,10 +95,10 @@ define shard_mini01_mainland01 cfg ShardId = 301; cfg BasePort = 52000; cfg SaveFilesDirectory="mini01_mainland01/"; - cfg NSHost = "ep1.mini01.ryzomcore.org"; - cfg FSListenHost = "ep1.mini01.ryzomcore.org"; + cfg NSHost = "ep1.mini01.ryzomcore.local"; + cfg FSListenHost = "ep1.mini01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_mini_mainland.cfg - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local // shard ring01 -------------------- @@ -110,7 +110,7 @@ define shard_mini01_ring01 cfg BasePort = 52400; cfg SaveFilesDirectory="mini01_ring01/"; cfg NSPort = 51100; - cfg NSHost = "ep1.mini01.ryzomcore.org" + 51100; + cfg NSHost = "ep1.mini01.ryzomcore.local" + 51100; cfgFile ../cfg/02_shard_type_std_ring.cfg - host ep1.mini01.ryzomcore.org + host ep1.mini01.ryzomcore.local diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt index 311261110..5492d6af3 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_std01.txt @@ -32,15 +32,15 @@ define domain_std01 // domain hosts cfg AESHost = "localhost"; - cfg SUHost = "su1.std01.ryzomcore.org"; - cfg MFSHost = "su1.std01.ryzomcore.org"; - cfg BSHost = "pd1.std01.ryzomcore.org:49990"; // Backup service host for domain - cfg SlaveBSHost= "pd2.std01.ryzomcore.org:49991"; - cfg MasterLGSHost = "pd3.std01.ryzomcore.org"; - cfg SlaveLGSHost = "pd4.std01.ryzomcore.org"; - cfg LGSBSHost = "csr.core.ryzomcore.org"; // Backup service host for log service - cfg DBHost = "sql.core.ryzomcore.org"; - cfgAfter WebSrvHost = "http://su1.std01.ryzomcore.org:50000/"; + cfg SUHost = "su1.std01.ryzomcore.local"; + cfg MFSHost = "su1.std01.ryzomcore.local"; + cfg BSHost = "pd1.std01.ryzomcore.local:49990"; // Backup service host for domain + cfg SlaveBSHost= "pd2.std01.ryzomcore.local:49991"; + cfg MasterLGSHost = "pd3.std01.ryzomcore.local"; + cfg SlaveLGSHost = "pd4.std01.ryzomcore.local"; + cfg LGSBSHost = "csr.core.ryzomcore.local"; // Backup service host for log service + cfg DBHost = "sql.core.ryzomcore.local"; + cfgAfter WebSrvHost = "http://su1.std01.ryzomcore.local:50000/"; // initial config files cfgFile ../cfg/00_base.cfg @@ -86,11 +86,11 @@ define shard_std01_unifier define shard_exe_set_std01_ras use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local define shard_exe_set_std01_unifier use exe_set_std_unifier - host su1.std01.ryzomcore.org + host su1.std01.ryzomcore.local cfg DBPass = DBNelPass; @@ -106,30 +106,30 @@ define shard_std01_mainland01 cfg ShardId = 101; cfg BasePort = 51000; cfg SaveFilesDirectory="std01_mainland01/"; - cfg NSHost = "mla1.std01.ryzomcore.org"; + cfg NSHost = "mla1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_mainland.cfg define shard_exe_set_std01_mainland01_be01 use exe_set_std_mainland_be01 - host mla1.std01.ryzomcore.org + host mla1.std01.ryzomcore.local define shard_exe_set_std01_mainland01_be02 use exe_set_std_mainland_be02 - host mla2.std01.ryzomcore.org + host mla2.std01.ryzomcore.local define shard_exe_set_std01_mainland01_be03 use exe_set_std_mainland_be03 - host mla3.std01.ryzomcore.org + host mla3.std01.ryzomcore.local define shard_exe_set_std01_mainland01_fe01 use exe_set_std_mainland_fe - host mla4.std01.ryzomcore.org - cfg FSListenHost = "mla4.std01.ryzomcore.org"; + host mla4.std01.ryzomcore.local + cfg FSListenHost = "mla4.std01.ryzomcore.local"; define shard_exe_set_std01_mainland01_fe02 use exe_set_std_mainland_fe - host mla5.std01.ryzomcore.org - cfg FSListenHost = "mla5.std01.ryzomcore.org"; + host mla5.std01.ryzomcore.local + cfg FSListenHost = "mla5.std01.ryzomcore.local"; // shard mainland02 ---------------- @@ -144,30 +144,30 @@ define shard_std01_mainland02 cfg ShardId = 102; cfg BasePort = 51100; cfg SaveFilesDirectory="std01_mainland02/"; - cfg NSHost = "mlb1.std01.ryzomcore.org"; + cfg NSHost = "mlb1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_mainland.cfg define shard_exe_set_std01_mainland02_be01 use exe_set_std_mainland_be01 - host mlb1.std01.ryzomcore.org + host mlb1.std01.ryzomcore.local define shard_exe_set_std01_mainland02_be02 use exe_set_std_mainland_be02 - host mlb2.std01.ryzomcore.org + host mlb2.std01.ryzomcore.local define shard_exe_set_std01_mainland02_be03 use exe_set_std_mainland_be03 - host mlb3.std01.ryzomcore.org + host mlb3.std01.ryzomcore.local define shard_exe_set_std01_mainland02_fe01 use exe_set_std_mainland_fe - host mlb4.std01.ryzomcore.org - cfg FSListenHost = "mlb4.std01.ryzomcore.org"; + host mlb4.std01.ryzomcore.local + cfg FSListenHost = "mlb4.std01.ryzomcore.local"; define shard_exe_set_std01_mainland02_fe02 use exe_set_std_mainland_fe - host mlb5.std01.ryzomcore.org - cfg FSListenHost = "mlb5.std01.ryzomcore.org"; + host mlb5.std01.ryzomcore.local + cfg FSListenHost = "mlb5.std01.ryzomcore.local"; // shard ring01 -------------------- @@ -179,17 +179,17 @@ define shard_std01_ring01 cfg ShardId = 201; cfg BasePort = 51400; cfg SaveFilesDirectory="std01_ring01/"; - cfg NSHost = "rra1.std01.ryzomcore.org"; + cfg NSHost = "rra1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_ring.cfg define shard_exe_set_std01_ring01_be use exe_set_std_ring_be - host rra1.std01.ryzomcore.org + host rra1.std01.ryzomcore.local define shard_exe_set_std01_ring01_fe use exe_set_std_ring_fe - host rra2.std01.ryzomcore.org - cfg FSListenHost = "rra2.std01.ryzomcore.org"; + host rra2.std01.ryzomcore.local + cfg FSListenHost = "rra2.std01.ryzomcore.local"; // shard ring02 -------------------- @@ -201,17 +201,17 @@ define shard_std01_ring02 cfg ShardId = 202; cfg BasePort = 51500; cfg SaveFilesDirectory="std01_ring02/"; - cfg NSHost = "rrb1.std01.ryzomcore.org"; + cfg NSHost = "rrb1.std01.ryzomcore.local"; cfgFile ../cfg/02_shard_type_std_ring.cfg define shard_exe_set_std01_ring02_be use exe_set_std_ring_be - host rrb1.std01.ryzomcore.org + host rrb1.std01.ryzomcore.local define shard_exe_set_std01_ring02_fe use exe_set_std_ring_fe - host rrb2.std01.ryzomcore.org - cfg FSListenHost = "rrb2.std01.ryzomcore.org"; + host rrb2.std01.ryzomcore.local + cfg FSListenHost = "rrb2.std01.ryzomcore.local"; // the std01 backup domain ---------- @@ -260,7 +260,7 @@ define shard_std01_backup_ras shard std01_backup_ras cfg ShardId = 100; use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local // the main backup pair ------------ @@ -273,15 +273,15 @@ define shard_std01_backup define shard_exe_set_std01_backup_master name bs_master use exe_set_std_backup_master - host pd1.std01.ryzomcore.org + host pd1.std01.ryzomcore.local define shard_exe_set_std01_backup_slave name bs_slave // hack to workaround bug in backup service // use exe_set_std_backup_slave use exe_set_std01_backup_slave - host pd2.std01.ryzomcore.org - cfgAfter MasterBSHost = "pd1.std01.ryzomcore.org:49990"; + host pd2.std01.ryzomcore.local + cfgAfter MasterBSHost = "pd1.std01.ryzomcore.local:49990"; // hack to workaround bug in backup service define exe_set_std01_backup_slave @@ -312,27 +312,27 @@ define shard_std01_lgs cfg L3SlaveLGSPort = 49993; cfg LGSBSPort = 49994; cfg L3LGSBSPort = 49995; - cfg MasterLGSHost = "pd3.std01.ryzomcore.org"; - cfg SlaveLGSHost = "pd4.std01.ryzomcore.org"; - cfg LGSBSHost = "csr.core.ryzomcore.org"; + cfg MasterLGSHost = "pd3.std01.ryzomcore.local"; + cfg SlaveLGSHost = "pd4.std01.ryzomcore.local"; + cfg LGSBSHost = "csr.core.ryzomcore.local"; define shard_exe_set_std01_lgs_primary name lgs_primary use raes use exe_set_std_lgs_master - host pd3.std01.ryzomcore.org + host pd3.std01.ryzomcore.local define shard_exe_set_std01_lgs_secondary name lgs_secondary use raes use exe_set_std_lgs_slave - host pd4.std01.ryzomcore.org + host pd4.std01.ryzomcore.local define shard_exe_set_std01_lgs_bs name lgs_bs use raes use backup_lgs - host csr.core.ryzomcore.org + host csr.core.ryzomcore.local // the std01 las domain ------------- @@ -365,7 +365,7 @@ define shard_std01_las_ras shard std01_las_ras cfg ShardId = 100; use ras - host ep1.std01.ryzomcore.org + host ep1.std01.ryzomcore.local // master las ---------------------- @@ -378,7 +378,7 @@ define shard_std01_las_master use las_mainland02 use las_ring01 use las_ring02 - host pd3.std01.ryzomcore.org + host pd3.std01.ryzomcore.local define las_mainland01 cfgAfter StartCommands += {"PDRootDirectory /srv/core/backup01/save_shard_pd/std01_mainland01/pds"}; @@ -415,7 +415,7 @@ define shard_std01_las_slave use las_mainland02_slave use las_ring01_slave use las_ring02_slave - host pd4.std01.ryzomcore.org + host pd4.std01.ryzomcore.local define las_mainland01_slave cfgAfter StartCommands += {"PDRootDirectory /srv/core/backup01/save_shard_pd/std01_mainland01/pds"}; diff --git a/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg b/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg index 351a8614a..c6a336c02 100644 --- a/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg +++ b/code/ryzom/server/patchman_cfg/terminal_mini01/patchman_service.cfg @@ -41,12 +41,12 @@ StartCommands += // bridge gateway // "moduleManager.createModule StandardGateway gw1", // "gw1.transportAdd L3Client l3client", -// "gw1.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44748)", +// "gw1.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44748)", // ats spm gateway "moduleManager.createModule StandardGateway gw2", "gw2.transportAdd L3Client l3client", - "gw2.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.org:44751)", + "gw2.transportCmd l3client(connect addr=ep1.mini01.ryzomcore.local:44751)", //------------------------------------------------------------------------------ From c3cf5c7af420f6d5fff717f21153b5ace330fe74 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:16:45 +0100 Subject: [PATCH 231/240] Update default patchman cfg --HG-- branch : develop --- .../patchman_cfg/default/ai_service.cfg | 24 +++---- .../default/dynamic_scenario_service.cfg | 9 +++ .../default/log_analyser_service.cfg | 5 ++ .../server/patchman_cfg/default/ryzom_as.cfg | 2 +- .../patchman_cfg/shard_ctrl_definitions.txt | 66 +++++++++++-------- 5 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg create mode 100644 code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg diff --git a/code/ryzom/server/patchman_cfg/default/ai_service.cfg b/code/ryzom/server/patchman_cfg/default/ai_service.cfg index 72b278cc0..5f3882759 100644 --- a/code/ryzom/server/patchman_cfg/default/ai_service.cfg +++ b/code/ryzom/server/patchman_cfg/default/ai_service.cfg @@ -322,21 +322,21 @@ StartCommandsWhenMirrorReadyRing = "createDynamicAIInstance 10000", "loadPrimitiveFile dummy.primitive", - "loadContinent r2_forest", - "createDynamicAIInstance 10001", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_forest", +// "createDynamicAIInstance 10001", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_lakes", - "createDynamicAIInstance 10003", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_lakes", +// "createDynamicAIInstance 10003", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_jungle", - "createDynamicAIInstance 10002", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_jungle", +// "createDynamicAIInstance 10002", +// "loadPrimitiveFile dummy.primitive", - "loadContinent r2_roots", - "createDynamicAIInstance 10004", - "loadPrimitiveFile dummy.primitive", +// "loadContinent r2_roots", +// "createDynamicAIInstance 10004", +// "loadPrimitiveFile dummy.primitive", // "spawnInstances", "updateAI", diff --git a/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg b/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg new file mode 100644 index 000000000..e6d5942ac --- /dev/null +++ b/code/ryzom/server/patchman_cfg/default/dynamic_scenario_service.cfg @@ -0,0 +1,9 @@ + +DelayBeforeStartAct = 1; +MaxNpcs = 300; +MaxStaticObjects = 200; + +StartCommands += +{ + "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", +}; diff --git a/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg b/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg new file mode 100644 index 000000000..355984ff5 --- /dev/null +++ b/code/ryzom/server/patchman_cfg/default/log_analyser_service.cfg @@ -0,0 +1,5 @@ + +DontUseNS = 1; + +QueryTimeout = 300; +LinePerPage = 50; diff --git a/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg b/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg index 2755403b7..4227bac69 100644 --- a/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg +++ b/code/ryzom/server/patchman_cfg/default/ryzom_as.cfg @@ -1,7 +1,7 @@ DontUseNS = 1; RRDToolPath = "rrdtool"; -RRDVarPath = "../graph_datas"; +RRDVarPath = "../rrd_graphs"; // Variables required to be defined by other cfgs //AESHost="localhost"; diff --git a/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt b/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt index 87bd0ce4d..8deb9f533 100644 --- a/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt +++ b/code/ryzom/server/patchman_cfg/shard_ctrl_definitions.txt @@ -26,7 +26,7 @@ define exe_set_mini_ring define exe_set_mini_mainland use raes use ms_mini_mainland - use ais_newbyland + use ais_newbieland use egs_mainland use gpms_mainland use ios_mainland @@ -100,7 +100,7 @@ define exe_set_std_mainland_be03 define exe_set_std_mainland_be03_basics // use ais_matis // use ais_tryker - use ais_newbyland + use ais_newbieland // unifier and co ------------------ @@ -170,12 +170,14 @@ define ais_ring cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Ring use ais data data_r2_desert - data data_r2_forest - data data_r2_jungle - data data_r2_lakes - data data_r2_roots + // data data_r2_forest + // data data_r2_jungle + // data data_r2_lakes + // data data_r2_roots define ais_mainland + name ais + cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais data data_mainland_common_primitives data data_newbieland_primitives @@ -188,8 +190,8 @@ define ais_mini_mainland cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais_mainland -define ais_newbyland - name ais_newbyland +define ais_newbieland + name ais_newbieland cmdLine ai_service -C. -L. --nobreak --writepid -mCommon:Indoors:Newbieland:Post use ais data data_mainland_common_primitives @@ -213,36 +215,40 @@ define bms_master use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49990 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49990; cfgAfter L3ListeningPort = 49950; cfgAfter WebPort = 49970; cfgAfter BSReadState = 1; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_master2 use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49994 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49994; cfgAfter L3ListeningPort = 49954; cfgAfter WebPort = 49974; cfgAfter BSReadState = 1; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_slave use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49991 - cfg #include "../live/cfg/backup_module_service_slave.cfg" + //cfg #include "../live/cfg/backup_module_service_slave.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49991; cfgAfter L3ListeningPort = 49951; cfgAfter WebPort = 49971; cfgAfter BSReadState = 0; - cfgAfter SaveShardRoot = "../save_shard/"; + cfgAfter SaveShardRoot = "../save_shard_bs/"; define bms_pd_master use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49992 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49992; cfgAfter L3ListeningPort = 49952; cfgAfter WebPort = 49972; @@ -252,7 +258,8 @@ define bms_pd_master define bms_pd_slave use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49993 - cfg #include "../live/cfg/backup_module_service_slave.cfg" + //cfg #include "../live/cfg/backup_module_service_slave.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49993; cfgAfter L3ListeningPort = 49953; cfgAfter WebPort = 49973; @@ -263,6 +270,7 @@ define backup_lgs use bms cmdLine backup_service -C. -L. --nobreak --writepid -P49994 //cfg #include "../live/cfg/backup_module_service_master.cfg" + cfg #include "../live/service_backup_service/backup_service.cfg" cfgAfter ListeningPort = 49994; cfgAfter L3ListeningPort = 49995; cfgAfter WebPort = 49972; @@ -320,7 +328,7 @@ define dss define dss_ring use dss - cfg #include "../live/cfg/dynamic_scenario_service_ring.cfg" + // cfg #include "../live/cfg/dynamic_scenario_service_ring.cfg" // egs ----------------------------- @@ -374,17 +382,17 @@ define egs_mainland define egs_ring use egs data data_mainland_common_primitives - data data_newbieland_primitives - data data_newbieland - data data_indoors - cfg #include "../live/cfg/entities_game_service_ring.cfg" + // data data_newbieland_primitives + // data data_newbieland + // data data_indoors + //cfg #include "../live/cfg/entities_game_service_ring.cfg" // care cfg UsedContinents = cfg { cfg "r2_desert", "10000", - cfg "r2_forest", "10001", - cfg "r2_jungle", "10002", - cfg "r2_lakes", "10003", - cfg "r2_roots", "10004", + // cfg "r2_forest", "10001", + // cfg "r2_jungle", "10002", + // cfg "r2_lakes", "10003", + // cfg "r2_roots", "10004", cfg }; cfgAfter MaxXPGainPerPlayer = 30.0; cfgAfter DeathXPFactor = 0.0; @@ -460,16 +468,16 @@ define gpms_mainland use gpms data data_newbieland data data_indoors - cfg #include "../live/cfg/gpm_service_mainland.cfg" + //cfg #include "../live/cfg/gpm_service_mainland.cfg" define gpms_ring use gpms data data_r2_desert - data data_r2_forest - data data_r2_jungle - data data_r2_lakes - data data_r2_roots - cfg #include "../live/cfg/gpm_service_ring.cfg" + // data data_r2_forest + // data data_r2_jungle + // data data_r2_lakes + // data data_r2_roots + //cfg #include "../live/cfg/gpm_service_ring.cfg" // pdss ---------------------------- @@ -534,7 +542,7 @@ define ios_mainland define ios_ring use ios - cfg #include "../live/cfg/input_output_service_ring.cfg" + //cfg #include "../live/cfg/input_output_service_ring.cfg" // las ----------------------------- From d30cca34f04ef3eee690a38665f80aff5b1601e1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:17:43 +0100 Subject: [PATCH 232/240] Backed out merge changeset: 361eb082ec5e Does not compile. FindLibLZMA missing on Ubunty 12.04 LTS --HG-- branch : develop --- code/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index e0f3fe7ba..071554e06 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -110,10 +110,6 @@ FIND_PACKAGE(Jpeg) IF(WITH_STATIC_LIBXML2) SET(LIBXML2_DEFINITIONS ${LIBXML2_DEFINITIONS} -DLIBXML_STATIC) - IF(NOT WIN32 AND NOT APPLE) - FIND_PACKAGE(LibLZMA REQUIRED) - SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) - ENDIF(NOT WIN32 AND NOT APPLE) ENDIF(WITH_STATIC_LIBXML2) IF(WITH_STATIC) From ee92cb070212ae8f918be7e23f1dd11233d35bc9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:21:05 +0100 Subject: [PATCH 233/240] Update default path --HG-- branch : develop --- .../server/patchman_cfg/terminal_mini01/terminal_mini01.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat b/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat index 7f61bfa59..90e11d5d6 100644 --- a/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat +++ b/code/ryzom/server/patchman_cfg/terminal_mini01/terminal_mini01.bat @@ -1,2 +1,2 @@ @echo off -start S:\devw_x86\bin\Release\ryzom_patchman_service.exe --nolog -C. -L. \ No newline at end of file +start R:\build\bin\Release\ryzom_patchman_service.exe --nolog -C. -L. \ No newline at end of file From 91ad193104cae85f99865e1f141c5ff50377396f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 19:32:18 +0100 Subject: [PATCH 234/240] Fix patchman scripts --HG-- branch : develop --- .../patchman_cfg/admin_install/bin/admin | 6 +- .../admin_install/bin/run_forever | 2 +- .../admin_install/patchman/loop_patchman.sh | 1 + .../patchman/loop_patchman_once.sh | 8 +- .../patchman/loop_special_patchman.sh | 2 +- .../admin_install/patchman/make_next_live.sh | 4 +- .../patchman/patchman_service.default.cfg | 7 -- .../patchman/patchman_service.mini01.cfg | 7 -- .../patchman/patchman_service.std01.cfg | 7 -- .../patchman/patchman_service_base_linux.cfg | 7 +- .../patchman/service_launcher.sh | 74 ++++++++++--------- .../patchman_cfg/default/ai_service.cfg | 6 +- 12 files changed, 62 insertions(+), 69 deletions(-) diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/admin b/code/ryzom/server/patchman_cfg/admin_install/bin/admin index c7cfa2fb6..f48de0d15 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/admin +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/admin @@ -99,14 +99,14 @@ then for f in $DOMAIN_LIST do # see if we're setup to run this domain - if [ -e /srv/core/${f}.screen.rc ] && [ -e /srv/core/bin/${f} ] + if [ -e /srv/core/${f}.screen.rc ] && [ -e /srv/core/bin/domain_${f} ] then # see whether the domain is alredy running - if [ $( screen -list | grep \( | cut -f2 | cut -d. -f2| grep \^$f\$ | wc -l) == 0 ] + if [ $( screen -list | grep \\\.${f} | wc -w ) = 0 ] then # the domain isn't running yet so start it echo '****' starting domain: $f '****' - /srv/core/bin/$f batchstart + /srv/core/bin/domain_$f batchstart else echo '****' Domain is already running: $f '****' fi diff --git a/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever b/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever index c6f14b074..91a838a02 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever +++ b/code/ryzom/server/patchman_cfg/admin_install/bin/run_forever @@ -3,7 +3,7 @@ while true do -if [ "$2" == "" ] +if [ "$2" = "" ] then echo echo USAGE: $0 sleep_time command_line diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh index 73b151c43..af057f2ae 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman.sh @@ -10,6 +10,7 @@ do chmod 775 bin/ps_services 2> /dev/null chmod 775 bin/run_forever 2> /dev/null chmod 775 bin/shard 2> /dev/null + chmod 775 bin/domain_* 2> /dev/null chmod 775 bin/startup 2> /dev/null chmod 775 bin/*.sh 2> /dev/null chmod 775 patchman/*_service 2> /dev/null diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh index 0dd697aa4..f7152cada 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_patchman_once.sh @@ -3,8 +3,8 @@ CFGFILENAME=patchman_service.${SERVER_TYPE}.cfg echo cfg file: $CFGFILENAME -AESCFGFILENAME=admin_executor_service_default.${SERVER_TYPE}.cfg -echo aes cfg file: $AESCFGFILENAME +#AESCFGFILENAME=admin_executor_service_default.${SERVER_TYPE}.cfg +#echo aes cfg file: $AESCFGFILENAME cd /srv/core/patchman if [ -e $CFGFILENAME ] @@ -15,8 +15,8 @@ if [ -e $CFGFILENAME ] cp $CFGFILENAME patchman_service.cfg # setup the config file for the admin executor service - echo Using aes configuration file: $AESCFGFILENAME - if [ -e $AESCFGFILENAME ] ; then cp $AESCFGFILENAME admin_executor_service_default.cfg ; fi + #echo Using aes configuration file: $AESCFGFILENAME + #if [ -e $AESCFGFILENAME ] ; then cp $AESCFGFILENAME admin_executor_service_default.cfg ; fi # start the patchman service echo Launching patchman... diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh index af1f5b599..6aa9f2ddf 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/loop_special_patchman.sh @@ -1,6 +1,6 @@ #!/bin/sh -if [ "$1" == "" ] +if [ "$1" = "" ] then echo echo USAGE: $0 command_line diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh index fbaca4ac4..394fc971d 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/make_next_live.sh @@ -84,7 +84,7 @@ rm -v */*.*launch_ctrl *.*launch_ctrl 2> /dev/null # initialise the state files for the new services to "xxxxx" and remove directories that are no longer of interest for D in $(ls */log.log | sed "s%/.*%%" | sort -u) do - if [ $(grep \"$D\" admin_executor_service.cfg | wc -l) == 1 ] + if [ $(grep \"$D\" admin_executor_service.cfg | wc -l) = 1 ] then printf "xxxxx" > $D/$D.state else @@ -97,7 +97,7 @@ done printf "1" > ./global.launch_ctrl # create a script for accessing the screen for this shard -SCRIPT_FILE=/srv/core/bin/${DOMAIN} +SCRIPT_FILE=/srv/core/bin/domain_${DOMAIN} echo "#!/bin/sh" > $SCRIPT_FILE echo "cd "$(pwd) >> $SCRIPT_FILE echo '/bin/sh /srv/core/bin/ryzom_domain_screen_wrapper.sh $*' >> $SCRIPT_FILE diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg index 184fca55a..7473aa9a0 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.default.cfg @@ -28,10 +28,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg index 0bd04c5eb..f046815ce 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.mini01.cfg @@ -36,10 +36,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg index 8fc5a64c9..23175c08b 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service.std01.cfg @@ -36,10 +36,3 @@ StartCommands = "pam.plug spm_gw", "pam.plug bridge_gw", }; - -SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; -DeploymentRootDirectory="/srv/core/patchman/"; -MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; -SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; -InstallArchiveDirectory="/srv/core/"; -InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg index 8aea88a5f..74290a228 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/patchman_service_base_linux.cfg @@ -14,4 +14,9 @@ DontUseStdIn = 0; // 4 = nothing UseYieldMethod = 0; - +SpaPreCmdLineText="/bin/sh /srv/core/patchman/service_launcher.sh"; +DeploymentRootDirectory="/srv/core/patchman/"; +MakeInstalledVersionLiveCmdLine="/bin/sh /srv/core/patchman/make_next_live.sh"; +SpaLaunchAESCmdLine="/bin/sh /srv/core/patchman/loop_aes.sh"; +InstallArchiveDirectory="/srv/core/"; +InstallArchiveFileName="admin_install.tgz"; diff --git a/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh b/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh index 091892af7..435c44bc0 100644 --- a/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh +++ b/code/ryzom/server/patchman_cfg/admin_install/patchman/service_launcher.sh @@ -1,25 +1,26 @@ #!/bin/sh -# the object is to make a launcher script that works with a command file to determine when to launch the application that it is responsible for +# the objective is to make a launcher script that works with a command file to determine when to launch the application that it is responsible for DOMAIN=$(pwd |sed "s%/srv/core/%%" | sed "s%/.*%%") NAME_BASE=$(pwd | sed 's/\/srv\/core\///' | sed 's/^.*\///') #if [ _$DOMAIN == _pre_live ] -# then - CTRL_FILE=${NAME_BASE}.launch_ctrl - NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl +# then + CTRL_FILE=${NAME_BASE}.launch_ctrl + NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl #elif [ _$DOMAIN == _pre_pre_live ] -# then -# CTRL_FILE=${NAME_BASE}.launch_ctrl -# NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl +# then +# CTRL_FILE=${NAME_BASE}.launch_ctrl +# NEXT_CTRL_FILE=${NAME_BASE}.deferred_launch_ctrl #else -# CTRL_FILE=${NAME_BASE}_immediate.launch_ctrl -# NEXT_CTRL_FILE=${NAME_BASE}_waiting.launch_ctrl +# CTRL_FILE=${NAME_BASE}_immediate.launch_ctrl +# NEXT_CTRL_FILE=${NAME_BASE}_waiting.launch_ctrl #fi STATE_FILE=${NAME_BASE}.state START_COUNTER_FILE=${NAME_BASE}.start_count CTRL_CMDLINE=$* +CTRL_COMMAND="" echo echo --------------------------------------------------------------------------------- @@ -36,6 +37,13 @@ echo echo 0 > $START_COUNTER_FILE START_COUNTER=0 +# always give ras a first run +if [ "${NAME_BASE}" = "ras" ] +then + echo Force admin service first startup + printf LAUNCH > $CTRL_FILE +fi + echo Press ENTER to launch program while true do @@ -45,37 +53,37 @@ do then # a control file exists so read it's contents - CTRL_COMMAND=_$(cat $CTRL_FILE)_ + CTRL_COMMAND=$(cat $CTRL_FILE) # do we have a 'launch' command? - if [ $CTRL_COMMAND = _LAUNCH_ ] + if [ "$CTRL_COMMAND" = "LAUNCH" ] then - # update the start counter - START_COUNTER=$(( $START_COUNTER + 1 )) - echo $START_COUNTER > $START_COUNTER_FILE + # update the start counter + START_COUNTER=$(( $START_COUNTER + 1 )) + echo $START_COUNTER > $START_COUNTER_FILE - # big nasty hack to deal with the special cases of ryzom_naming_service and ryzom_admin_service who have badly names cfg files - for f in ryzom_*cfg - do - cp $f $(echo $f | sed "s/ryzom_//") - done + # big nasty hack to deal with the special cases of ryzom_naming_service and ryzom_admin_service who have badly names cfg files + for f in ryzom_*cfg + do + cp $f $(echo $f | sed "s/ryzom_//") + done - # we have a launch command so prepare, launch, wait for exit and do the housekeeping - echo ----------------------------------------------------------------------- - echo Launching ... - echo - printf RUNNING > $STATE_FILE + # we have a launch command so prepare, launch, wait for exit and do the housekeeping + echo ----------------------------------------------------------------------- + echo Launching ... + echo + printf RUNNING > $STATE_FILE - $CTRL_CMDLINE + $CTRL_CMDLINE - echo ----------------------------------------------------------------------- - printf STOPPED > $STATE_FILE + echo ----------------------------------------------------------------------- + printf STOPPED > $STATE_FILE - # consume (remove) the control file to allow start once - rm $CTRL_FILE + # consume (remove) the control file to allow start once + rm $CTRL_FILE - echo Press ENTER to relaunch + echo Press ENTER to relaunch fi fi @@ -87,9 +95,9 @@ do else # give the terminal user a chance to press enter to provoke a re-launch HOLD=`sh -ic '{ read a; echo "ENTER" 1>&3; kill 0; } | { sleep 2; kill 0; }' 3>&1 2>/dev/null` - if [ _${HOLD}_ != _HOLD_ ] - then - printf LAUNCH > $CTRL_FILE + if [ "${HOLD}" = "ENTER" ] + then + printf LAUNCH > $CTRL_FILE fi fi diff --git a/code/ryzom/server/patchman_cfg/default/ai_service.cfg b/code/ryzom/server/patchman_cfg/default/ai_service.cfg index 5f3882759..fdb381b38 100644 --- a/code/ryzom/server/patchman_cfg/default/ai_service.cfg +++ b/code/ryzom/server/patchman_cfg/default/ai_service.cfg @@ -6,7 +6,7 @@ SystemCmd = {}; //NegFiltersDebug += { "LNET", "HNET", "FEVIS"}; //NegFiltersInfo += { "LNET", "HNET", "VISION_DELTA", "FEIMPE", "FEVIS" }; // NegFiltersWarning += { "LNET", "FEHACK", "FERECV"}; -// NegFiltersWarning += { "positional", "faction", "pet" }; +// NegFiltersWarning += { "positional", "faction", "pet" }; ////////////////////////////////////////////////////////////////////////////// //- Basic (specific) heal profile parameters --------------------------------- @@ -49,7 +49,7 @@ DefaultNpcAggroDist = 15; DefaultEscortRange = 10; ////////////////////////////////////////////////////////////////////////////// -// Aggro // +// Aggro // ////////////////////////////////////////////////////////////////////////////// AggroReturnDistCheck = 15.0; AggroReturnDistCheckFauna = 15.0; @@ -318,7 +318,7 @@ StartCommandsWhenMirrorReadyPost = // commands for Ring continents StartCommandsWhenMirrorReadyRing = { - "loadContinent r2_desert", + "loadContinent r2_desert", "createDynamicAIInstance 10000", "loadPrimitiveFile dummy.primitive", From 70ace8b7d4e01059838eb543fee79a633fe94af8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 23:37:39 +0100 Subject: [PATCH 235/240] Print callstack --HG-- branch : develop --- code/web/public_php/login/r2_login.php | 1 + 1 file changed, 1 insertion(+) diff --git a/code/web/public_php/login/r2_login.php b/code/web/public_php/login/r2_login.php index fdce63958..b0a8a2d79 100644 --- a/code/web/public_php/login/r2_login.php +++ b/code/web/public_php/login/r2_login.php @@ -145,6 +145,7 @@ { $logFile = new CWwwLog(); $logFile->logStr("PHP ERROR/$errno $errmsg ($filename:$linenum)"); + $logFile->logStr("PHP CALLSTACK/" . print_r(debug_backtrace(), TRUE)); // Never die after an error } From ef2415257b37621395d104c142ed9f34f47f3c44 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 7 Nov 2014 23:51:42 +0100 Subject: [PATCH 236/240] Fix PHP error "Only variables should be passed by reference" --HG-- branch : develop --- code/web/public_php/tools/nel_message.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/web/public_php/tools/nel_message.php b/code/web/public_php/tools/nel_message.php index c970b9f2c..ee3177f8d 100644 --- a/code/web/public_php/tools/nel_message.php +++ b/code/web/public_php/tools/nel_message.php @@ -86,9 +86,10 @@ } else { - $this->serialUInt32(strlen($val)); + $valLen = strlen($val); + $this->serialUInt32($valLen); $this->Buffer .= $val; - $this->Pos += strlen($val); + $this->Pos += $valLen; debug(sprintf ("write string '%s' %d
\n", $val, $this->Pos)); } } From 2df9cb5f87458ab056d1041406a6e934810bc381 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 8 Nov 2014 00:29:50 +0100 Subject: [PATCH 237/240] Fix PHP error "Only variables should be passed by reference" --HG-- branch : develop --- code/web/public_php/admin/nel/nel_message.php | 5 +++-- code/web/public_php/tools/nel_message.php | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/web/public_php/admin/nel/nel_message.php b/code/web/public_php/admin/nel/nel_message.php index 5e704bff1..42dd91cbe 100644 --- a/code/web/public_php/admin/nel/nel_message.php +++ b/code/web/public_php/admin/nel/nel_message.php @@ -91,9 +91,10 @@ } else { - $this->serialUInt32(strlen($val)); + $valLen = strlen($val); + $this->serialUInt32($valLen); $this->Buffer .= $val; - $this->Pos += strlen($val); + $this->Pos += $valLen; debug(sprintf ("write string '%s' %d
\n", $val, $this->Pos)); } } diff --git a/code/web/public_php/tools/nel_message.php b/code/web/public_php/tools/nel_message.php index ee3177f8d..b696bb151 100644 --- a/code/web/public_php/tools/nel_message.php +++ b/code/web/public_php/tools/nel_message.php @@ -104,7 +104,8 @@ } else { - $this->serialUInt32($val->toInt()); + $intValue = $val->toInt(); + $this->serialUInt32($intValue); debug(sprintf ("write enum '%s' %d
\n", $val->toString(), $this->Pos)); } } From 0c1ff0df2a8686d74774b5274dd76a96bc8d2de4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 10 Nov 2014 23:34:41 +0100 Subject: [PATCH 238/240] ryzomcore/v0.11.0 --HG-- branch : develop --- code/CMakeLists.txt | 4 ++-- code/nel/tools/3d/plugin_max/nel_export/nel_export.rc | 8 ++++---- .../plugin_max/nel_patch_converter/nel_patch_converter.rc | 8 ++++---- code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc | 8 ++++---- .../3d/plugin_max/nel_patch_paint/nel_patch_paint.rc | 8 ++++---- .../plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc | 8 ++++---- code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc | 8 ++++---- code/ryzom/common/src/game_share/ryzom_version.h | 2 +- code/web/public_php/ams/templates/layout.tpl | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 071554e06..372177889 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -2,7 +2,7 @@ # # NeL # Authors: Nevrax and the NeL Community -# Version: 0.10.0 +# Version: 0.11.0 # # Notes: # * Changing install location: add -DCMAKE_INSTALL_PREFIX:PATH=/my/new/path @@ -47,7 +47,7 @@ CHECK_OUT_OF_SOURCE() CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(RyzomCore CXX C) SET(NL_VERSION_MAJOR 0) -SET(NL_VERSION_MINOR 10) +SET(NL_VERSION_MINOR 11) SET(NL_VERSION_PATCH 0) SET(NL_VERSION "${NL_VERSION_MAJOR}.${NL_VERSION_MINOR}.${NL_VERSION_PATCH}") diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc b/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc index 57edca682..d01762618 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export.rc @@ -575,8 +575,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -593,14 +593,14 @@ BEGIN BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "CNelExport\0" VALUE "LegalCopyright", "\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "CNelExport.dlu\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "SpecialBuild", "\0" END END diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc index aa8749a3e..b6eea41a6 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.rc @@ -85,8 +85,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -103,12 +103,12 @@ BEGIN BEGIN VALUE "Comments", "http://www.ryzomcore.org/" VALUE "FileDescription", "PatchMesh to RykolPatchMesh" - VALUE "FileVersion", "0.10.0" + VALUE "FileVersion", "0.11.0" VALUE "InternalName", "PatchMesh to RykolPatchMesh" VALUE "LegalCopyright", "Copyright, 2000 Nevrax Ltd." VALUE "OriginalFilename", "nel_convert_patch.dlm" VALUE "ProductName", "NeL Patch Converter" - VALUE "ProductVersion", "0.10.0" + VALUE "ProductVersion", "0.11.0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc index adc44260e..243e02da8 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/mods.rc @@ -514,8 +514,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -533,13 +533,13 @@ BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core" VALUE "FileDescription", "NeL Patch Edit" - VALUE "FileVersion", "0.10.0" + VALUE "FileVersion", "0.11.0" VALUE "InternalName", "neleditpatch" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd. Copyright © 1998 Autodesk Inc." VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF." VALUE "OriginalFilename", "neleditpatch.dlm" VALUE "ProductName", "Ryzom Core" - VALUE "ProductVersion", "0.10.0" + VALUE "ProductVersion", "0.11.0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc index fadbde308..534efb2ac 100644 --- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc +++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.rc @@ -96,8 +96,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -116,14 +116,14 @@ BEGIN VALUE "Comments", "TECH: cyril.corvazier\0" VALUE "CompanyName", "Ryzom Core\0" VALUE "FileDescription", "NeL Patch Paint\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "mods\0" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "nelpatchpaint.dlm\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "SpecialBuild", "\0" END END diff --git a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc index bf5fdd549..4e70d1afc 100644 --- a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc +++ b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.rc @@ -125,8 +125,8 @@ IDC_DROPPER_CURSOR CURSOR DISCARDABLE "dropcurs.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -145,13 +145,13 @@ BEGIN VALUE "Comments", "TECH: \0" VALUE "CompanyName", "Ryzom Core\0" VALUE "FileDescription", "Vertex Tree Paint\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "VertexTreePaint\0" VALUE "LegalCopyright", "Copyright © 2000 Nevrax Ltd. Copyright © 1998 Autodesk Inc.\0" VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF.\0" VALUE "OriginalFilename", "nel_vertex_tree_paint.dlm\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" END END BLOCK "VarFileInfo" diff --git a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc index c6118c2f8..80d1d390d 100644 --- a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc +++ b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.rc @@ -124,8 +124,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0, 10, 0, 0 - PRODUCTVERSION 0, 10, 0, 0 + FILEVERSION 0, 11, 0, 0 + PRODUCTVERSION 0, 11, 0, 0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -142,12 +142,12 @@ BEGIN BEGIN VALUE "Comments", "Based on Kinetix 3D Studio Max 3.0 plugin sample\0" VALUE "CompanyName", "Ryzom Core\0" - VALUE "FileVersion", "0.10.0\0" + VALUE "FileVersion", "0.11.0\0" VALUE "InternalName", "Tile_utility\0" VALUE "LegalCopyright", "\0" VALUE "OriginalFilename", "Tile_utility.dlu\0" VALUE "ProductName", "Ryzom Core\0" - VALUE "ProductVersion", "0.10.0\0" + VALUE "ProductVersion", "0.11.0\0" VALUE "FileDescription", "Create material for tiles\0" VALUE "Comments", "TECH: \0" VALUE "LegalTrademarks", "\0" diff --git a/code/ryzom/common/src/game_share/ryzom_version.h b/code/ryzom/common/src/game_share/ryzom_version.h index 1c13b7ed1..af714db4d 100644 --- a/code/ryzom/common/src/game_share/ryzom_version.h +++ b/code/ryzom/common/src/game_share/ryzom_version.h @@ -17,7 +17,7 @@ #ifndef RYZOM_VERSION_H #define RYZOM_VERSION_H -#define RYZOM_VERSION "ryzomcore/v0.10.0-dev" +#define RYZOM_VERSION "ryzomcore/v0.11.0-dev" #endif // RYZOM_VERSION_H diff --git a/code/web/public_php/ams/templates/layout.tpl b/code/web/public_php/ams/templates/layout.tpl index c949263d1..33dbf3be0 100644 --- a/code/web/public_php/ams/templates/layout.tpl +++ b/code/web/public_php/ams/templates/layout.tpl @@ -167,7 +167,7 @@
- {if $permission > 1}

AMS 0.10.0 Powered by: Charisma

{/if} + {if $permission > 1}

AMS 0.11.0 Powered by: Charisma

{/if}
{/if}
From d65a1cbd814c00bbe08ae48e5d24e69738536d33 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 10 Nov 2014 23:41:33 +0100 Subject: [PATCH 240/240] Added tag ryzomcore/v0.11.0 for changeset edaa3624a564 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index c6af6b011..931ad2ca5 100644 --- a/.hgtags +++ b/.hgtags @@ -3,3 +3,4 @@ 00d9b6e29e95f56785fbf85abe60afd34674f402 ryzomcore/v0.9.0 79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1 fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0 +edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0