Merge commit '505e13cd1eb576209ac7e088c91e0ba1a3e2da62' into feature/cdb-packed-ryzomclassic

feature/cdb-packed-ryzomclassic
kaetemi 4 years ago
commit 431b1140e9

@ -54,8 +54,8 @@ ENDIF()
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(RyzomCore CXX C) PROJECT(RyzomCore CXX C)
SET(NL_VERSION_MAJOR 1) SET(NL_VERSION_MAJOR 1)
SET(NL_VERSION_MINOR 0) SET(NL_VERSION_MINOR 1)
SET(NL_VERSION_PATCH 2) SET(NL_VERSION_PATCH 0 CACHE STRING "Patch version")
SET(YEAR "2001-${CURRENT_YEAR}") SET(YEAR "2001-${CURRENT_YEAR}")
SET(AUTHOR "Winch Gate and The Ryzom Core Community") SET(AUTHOR "Winch Gate and The Ryzom Core Community")

@ -33,7 +33,48 @@ jobs:
mkdir build mkdir build
cmake --version cmake --version
cd build cd build
cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON ../code cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON ..
cat CMakeCache.txt
displayName: 'CMake'
- script: |
cd build
make -j`nproc`
displayName: 'Make'
- job: ubuntu18
timeoutInMinutes: 120
pool:
vmImage: 'ubuntu-18.04'
steps:
- script: |
sudo apt update
sudo apt install -y software-properties-common
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install cmake build-essential -y
sudo apt install gcc-8 g++-8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60
sudo apt install bison autoconf automake -y
sudo apt install libpng-dev -y
sudo apt install libjpeg-dev -y
sudo apt install libgif-dev libfreetype6-dev -y
sudo apt install freeglut3-dev -y
sudo apt install liblua5.2-dev libluabind-dev libcpptest-dev -y
sudo apt install libogg-dev libvorbis-dev libopenal-dev -y
sudo apt install libavcodec-dev libavformat-dev libavdevice-dev libswscale-dev libpostproc-dev -y
sudo apt install libmysqlclient-dev -y
sudo apt install libxml2-dev -y
sudo apt install libcurl4-openssl-dev libssl-dev -y
sudo apt install libsquish-dev -y
sudo apt install liblzma-dev -y
sudo apt install libgsf-1-dev -y
sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools
displayName: 'Dependencies'
- script: |
mkdir build
cmake --version
cd build
cmake -DWITH_STATIC=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_SAMPLES=ON -DWITH_LUA51=OFF -DWITH_LUA52=ON -DWITH_RYZOM=ON -DWITH_RYZOM_SERVER=ON -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_TOOLS=ON -DWITH_NEL_TOOLS=ON -DWITH_NELNS=ON -DWITH_NELNS_LOGIN_SYSTEM=ON -DWITH_NELNS_SERVER=ON -DWITH_QT5=ON -DWITH_LIBGSF=ON ..
cat CMakeCache.txt cat CMakeCache.txt
displayName: 'CMake' displayName: 'CMake'
- script: | - script: |

@ -89,6 +89,9 @@ void createDebug (const char *logPath = NULL, bool logInFile = true, bool eraseL
/// Do not call this, unless you know what you're trying to do (it kills debug)! /// Do not call this, unless you know what you're trying to do (it kills debug)!
void destroyDebug(); void destroyDebug();
/// Attach exception handler, for new threads and fibers
void attachExceptionHandler();
// call this if you want to change the dir of the log.log file // call this if you want to change the dir of the log.log file
void changeLogDirectory(const std::string &dir); void changeLogDirectory(const std::string &dir);
@ -352,7 +355,7 @@ void setCrashAlreadyReported(bool state);
* Same as nlassertex(false,exp); * Same as nlassertex(false,exp);
*/ */
// removed because we always check assert (even in release mode) #if defined (NL_OS_WINDOWS) && defined (NL_DEBUG) #if defined(NL_DEBUG) /* Debug break is only useful in debug builds */
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
#define NLMISC_BREAKPOINT __debugbreak() #define NLMISC_BREAKPOINT __debugbreak()
#elif defined(NL_OS_UNIX) && defined(NL_COMP_GCC) #elif defined(NL_OS_UNIX) && defined(NL_COMP_GCC)
@ -360,6 +363,9 @@ void setCrashAlreadyReported(bool state);
#else #else
#define NLMISC_BREAKPOINT abort() #define NLMISC_BREAKPOINT abort()
#endif #endif
#else
#define NLMISC_BREAKPOINT do { } while (0)
#endif
// Internal, don't use it (make smaller assert code) // Internal, don't use it (make smaller assert code)
extern bool _assert_stop(bool &ignoreNextTime, sint line, const char *file, const char *funcName, const char *exp); extern bool _assert_stop(bool &ignoreNextTime, sint line, const char *file, const char *funcName, const char *exp);

@ -290,6 +290,14 @@ inline bool endsWith(const char *str, const char *suffix) { return endsWith(str,
inline bool endsWith(const std::string &str, const char *suffix) { return endsWith(str.c_str(), str.size(), suffix, strlen(suffix)); } inline bool endsWith(const std::string &str, const char *suffix) { return endsWith(str.c_str(), str.size(), suffix, strlen(suffix)); }
inline bool endsWith(const std::string &str, const std::string &suffix) { return endsWith(str.c_str(), str.size(), suffix.c_str(), suffix.size()); } inline bool endsWith(const std::string &str, const std::string &suffix) { return endsWith(str.c_str(), str.size(), suffix.c_str(), suffix.size()); }
// ****************************************************************************
// Conversion of strings between
// - UTF-8
// - Local codepage (UTF-8 on Linux)
// - TString (Local codepage or wide on Windows)
// - Wide (wchar_t *, UTF-16 on Windows, UTF-32 on Linux)
// ****************************************************************************
// Convert local codepage to UTF-8 // Convert local codepage to UTF-8
// On Windows, the local codepage is undetermined // On Windows, the local codepage is undetermined
// On Linux, the local codepage is always UTF-8 (no-op) // On Linux, the local codepage is always UTF-8 (no-op)

@ -662,6 +662,7 @@ private:
std::vector<TCallbackArgItem> _UpUniCallback; std::vector<TCallbackArgItem> _UpUniCallback;
TNameMappedCallback _DownCallbacks; TNameMappedCallback _DownCallbacks;
std::vector<TCallbackArgItem> _DownUniCallback; std::vector<TCallbackArgItem> _DownUniCallback;
std::set<std::pair<std::string, TServiceId>> _NotifiedUpCallbacks;
/// Recording state /// Recording state
CCallbackNetBase::TRecordingState _RecordingState; CCallbackNetBase::TRecordingState _RecordingState;

@ -191,7 +191,7 @@ public:
/// Create a native music channel, only supported by the FMod driver. /// Create a native music channel, only supported by the FMod driver.
virtual IMusicChannel *createMusicChannel() { return NULL; } virtual IMusicChannel *createMusicChannel() { return NULL; }
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */

@ -108,7 +108,7 @@ public:
bool play(const std::string &filepath, uint xFadeTime = 0, bool async = true, bool loop = true); bool play(const std::string &filepath, uint xFadeTime = 0, bool async = true, bool loop = true);
/// Stop the music previously loaded and played (the Memory is also freed) /// Stop the music previously loaded and played (the Memory is also freed)
void stop(uint xFadeTime = 0); bool stop(uint xFadeTime = 0);
/// Pause the music previously loaded and played (the Memory is not freed) /// Pause the music previously loaded and played (the Memory is not freed)
void pause(); void pause();

@ -96,6 +96,8 @@ private:
IAudioDecoder *m_AudioDecoder; IAudioDecoder *m_AudioDecoder;
std::string m_LookupPath;
bool m_Paused; bool m_Paused;
bool m_DecodingEnded; bool m_DecodingEnded;

@ -34,7 +34,7 @@ class CCurlHttpClient
public: public:
/// Constructor /// Constructor
CCurlHttpClient() {} CCurlHttpClient() : _CurlStruct(NULL) {}
/// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server. /// Connect to an http server (string by val is intended). If you specify a whole URL, an attempt will be made to determine the server.
bool connect(const std::string &server); bool connect(const std::string &server);

@ -323,7 +323,7 @@
<PARAMETER NAME="Array3" TYPE="string_array" VISIBLE="true" FILENAME="false" AUTONAME="Autoname-$Array$-$Array2$-" WIDGET_HEIGHT="100"> <PARAMETER NAME="Array3" TYPE="string_array" VISIBLE="true" FILENAME="false" AUTONAME="Autoname-$Array$-$Array2$-" WIDGET_HEIGHT="100">
</PARAMETER>--> </PARAMETER>-->
<PARAMETER NAME="ConstArray" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true"> <PARAMETER NAME="ConstArray" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true">
<COMBO_FILES CONTEXT_NAME="default" PATH="l:/leveldesign/game_elem/plant/flora_template/forest"/> <COMBO_FILES CONTEXT_NAME="default" PATH="R:/leveldesign/game_elem/plant/flora_template/forest"/>
<COMBO_VALUES CONTEXT_NAME="jungle"> <COMBO_VALUES CONTEXT_NAME="jungle">
<CONTEXT_VALUE VALUE="jungle0"/> <CONTEXT_VALUE VALUE="jungle0"/>
</COMBO_VALUES> </COMBO_VALUES>
@ -343,7 +343,7 @@
</PARAMETER> </PARAMETER>
<PARAMETER NAME="ConstArray2" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true" AUTONAME="$ConstArray$"> <PARAMETER NAME="ConstArray2" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true" AUTONAME="$ConstArray$">
<COMBO_FILES CONTEXT_NAME="default" PATH="l:/leveldesign/game_elem/plant/flora_template/forest"/> <COMBO_FILES CONTEXT_NAME="default" PATH="R:/leveldesign/game_elem/plant/flora_template/forest"/>
<COMBO_VALUES CONTEXT_NAME="jungle"> <COMBO_VALUES CONTEXT_NAME="jungle">
<CONTEXT_VALUE VALUE="jungle0"/> <CONTEXT_VALUE VALUE="jungle0"/>
</COMBO_VALUES> </COMBO_VALUES>

@ -323,7 +323,7 @@
<PARAMETER NAME="Array3" TYPE="string_array" VISIBLE="true" FILENAME="false" AUTONAME="Autoname-$Array$-$Array2$-" WIDGET_HEIGHT="100"> <PARAMETER NAME="Array3" TYPE="string_array" VISIBLE="true" FILENAME="false" AUTONAME="Autoname-$Array$-$Array2$-" WIDGET_HEIGHT="100">
</PARAMETER>--> </PARAMETER>-->
<PARAMETER NAME="ConstArray" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true"> <PARAMETER NAME="ConstArray" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true">
<COMBO_FILES CONTEXT_NAME="default" PATH="l:/leveldesign/game_elem/plant/flora_template/forest"/> <COMBO_FILES CONTEXT_NAME="default" PATH="R:/leveldesign/game_elem/plant/flora_template/forest"/>
<COMBO_VALUES CONTEXT_NAME="jungle"> <COMBO_VALUES CONTEXT_NAME="jungle">
<CONTEXT_VALUE VALUE="jungle0"/> <CONTEXT_VALUE VALUE="jungle0"/>
</COMBO_VALUES> </COMBO_VALUES>
@ -343,7 +343,7 @@
</PARAMETER> </PARAMETER>
<PARAMETER NAME="ConstArray2" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true" AUTONAME="$ConstArray$"> <PARAMETER NAME="ConstArray2" TYPE="const_string_array" VISIBLE="true" FILENAME="true" WIDGET_HEIGHT="100" FILE_EXTENSION="flora" LOOKUP="true" AUTONAME="$ConstArray$">
<COMBO_FILES CONTEXT_NAME="default" PATH="l:/leveldesign/game_elem/plant/flora_template/forest"/> <COMBO_FILES CONTEXT_NAME="default" PATH="R:/leveldesign/game_elem/plant/flora_template/forest"/>
<COMBO_VALUES CONTEXT_NAME="jungle"> <COMBO_VALUES CONTEXT_NAME="jungle">
<CONTEXT_VALUE VALUE="jungle0"/> <CONTEXT_VALUE VALUE="jungle0"/>
</COMBO_VALUES> </COMBO_VALUES>

@ -3830,9 +3830,15 @@ void CDriverD3D::CLightState::apply(CDriverD3D *driver)
void CDriverD3D::CRenderTargetState::apply(CDriverD3D *driver) void CDriverD3D::CRenderTargetState::apply(CDriverD3D *driver)
{ {
H_AUTO_D3D(CDriverD3D_CRenderTargetState); H_AUTO_D3D(CDriverD3D_CRenderTargetState);
driver->_DeviceInterface->SetRenderTarget (0, Target); nlassert(TargetOwned); // Can only apply once!
driver->_DeviceInterface->SetRenderTarget(0, Target);
driver->setupViewport(driver->_Viewport); driver->setupViewport(driver->_Viewport);
driver->setupScissor(driver->_Scissor); driver->setupScissor(driver->_Scissor);
if (TargetOwned)
{
Target->Release();
TargetOwned = false;
}
} }
// *************************************************************************** // ***************************************************************************

@ -1546,11 +1546,13 @@ public:
Texture = NULL; Texture = NULL;
Level = 0; Level = 0;
CubeFace = 0; CubeFace = 0;
TargetOwned = false;
} }
IDirect3DSurface9 *Target; IDirect3DSurface9 *Target;
ITexture *Texture; ITexture *Texture;
uint8 Level; uint8 Level;
uint8 CubeFace; uint8 CubeFace;
bool TargetOwned;
virtual void apply(CDriverD3D *driver); virtual void apply(CDriverD3D *driver);
}; };
@ -2076,10 +2078,17 @@ public:
NL_D3D_CACHE_TEST(CacheTest_RenderTarget, _RenderTarget.Target != target) NL_D3D_CACHE_TEST(CacheTest_RenderTarget, _RenderTarget.Target != target)
#endif // NL_D3D_USE_RENDER_STATE_CACHE #endif // NL_D3D_USE_RENDER_STATE_CACHE
{ {
if (_RenderTarget.TargetOwned)
{
nlassert(_RenderTarget.Target);
_RenderTarget.Target->Release();
}
_RenderTarget.Target = target; _RenderTarget.Target = target;
_RenderTarget.Texture = texture; _RenderTarget.Texture = texture;
_RenderTarget.Level = level; _RenderTarget.Level = level;
_RenderTarget.CubeFace = cubeFace; _RenderTarget.CubeFace = cubeFace;
_RenderTarget.TargetOwned = target;
target->AddRef();
touchRenderVariable (&_RenderTarget); touchRenderVariable (&_RenderTarget);

@ -706,9 +706,13 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Set the texture states // Set the texture states
if (text || (stage == 0)) if (text || (stage == 0))
{ {
// Doesn't use a pixel shader ? Set the textures stages if (matShader == CMaterial::Program)
if (pShader->PixelShader == NULL)
{ {
// Do nothing for user pixel shader
}
else if (!pShader->PixelShader)
{
// Doesn't use a pixel shader ? Set the textures stages
if (pShader->RGBPipe[stage]) if (pShader->RGBPipe[stage])
{ {
setTextureState (stage, D3DTSS_COLOROP, pShader->ColorOp[stage]); setTextureState (stage, D3DTSS_COLOROP, pShader->ColorOp[stage]);
@ -1145,7 +1149,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
} }
break; break;
case CMaterial::Cloud: case CMaterial::Cloud:
{ {
H_AUTO_D3D(CDriverD3D_setupMaterial_setupCloudShader) H_AUTO_D3D(CDriverD3D_setupMaterial_setupCloudShader)
activeShader (&_ShaderCloud); activeShader (&_ShaderCloud);
@ -1167,7 +1171,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
return false; return false;
} }
break; break;
case CMaterial::Water: case CMaterial::Water:
{ {
H_AUTO_D3D(CDriverD3D_setupMaterial_setupWaterShader) H_AUTO_D3D(CDriverD3D_setupMaterial_setupWaterShader)
activeShader(mat.getTexture(3) ? &_ShaderWaterDiffuse : &_ShaderWaterNoDiffuse); activeShader(mat.getTexture(3) ? &_ShaderWaterDiffuse : &_ShaderWaterNoDiffuse);
@ -1296,7 +1300,14 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
} }
} }
} }
// CMaterial::Water break; // CMaterial::Water
case CMaterial::Program:
{
H_AUTO_D3D(CDriverD3D_setupMaterial_setupProgramshader)
// No material shader
activeShader(NULL);
}
break;
} }
// New material setuped // New material setuped

@ -1084,6 +1084,7 @@ void CDriverD3D::swapTextureHandle(ITexture &tex0, ITexture &tex1)
swap(t0->Height, t1->Height); swap(t0->Height, t1->Height);
swap(t0->SrcCompressed, t1->SrcCompressed); swap(t0->SrcCompressed, t1->SrcCompressed);
swap(t0->IsCube, t1->IsCube); swap(t0->IsCube, t1->IsCube);
swap(t0->RenderTarget, t1->RenderTarget);
swap(t0->Levels, t1->Levels); swap(t0->Levels, t1->Levels);
swap(t0->FirstMipMap, t1->FirstMipMap); swap(t0->FirstMipMap, t1->FirstMipMap);
swap(t0->TextureMemory, t1->TextureMemory); swap(t0->TextureMemory, t1->TextureMemory);

@ -1584,6 +1584,14 @@ void registerGlExtensions(CGlExtensions &ext)
{ {
H_AUTO_OGL(registerGlExtensions); H_AUTO_OGL(registerGlExtensions);
#ifdef NL_OS_MAC
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx == NULL)
{
nlerror("No OpenGL context set");
}
#endif
// OpenGL 1.2 ?? // OpenGL 1.2 ??
const char *nglVersion = (const char *)glGetString (GL_VERSION); const char *nglVersion = (const char *)glGetString (GL_VERSION);

@ -1072,6 +1072,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
[_ctx flushBuffer]; [_ctx flushBuffer];
[_glView display]; [_glView display];
// Set context as thread context
CGLSetCurrentContext((CGLContextObj)[_ctx CGLContextObj]);
_EventEmitter.init(this, _glView, _DestroyWindow); _EventEmitter.init(this, _glView, _DestroyWindow);
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)

@ -246,6 +246,7 @@ void CFXAA::applyEffect()
// create render target // create render target
CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D); CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D);
nlassert(otherRenderTarget);
// swap render target // swap render target
CTextureUser texNull; CTextureUser texNull;

@ -979,6 +979,9 @@ void CLodCharacterManager::addTextureCompute(CLodCharacterInstance &instance,
// get lookup ptr. // get lookup ptr.
nlassert(lodTexture.Texture.size()==NL3D_CLOD_TEXT_SIZE); nlassert(lodTexture.Texture.size()==NL3D_CLOD_TEXT_SIZE);
if (lodTexture.Texture.size() < NL3D_CLOD_TEXT_SIZE)
return;
const CLodCharacterTexture::CTUVQ *lookUpPtr= &lodTexture.Texture[0]; const CLodCharacterTexture::CTUVQ *lookUpPtr= &lodTexture.Texture[0];
// apply the lodTexture, taking only better quality (ie nearer 0) // apply the lodTexture, taking only better quality (ie nearer 0)

@ -143,6 +143,9 @@ namespace NLMISC
NL_CT_DEBUG("CoTask : task %p start func called", task); NL_CT_DEBUG("CoTask : task %p start func called", task);
// Attach exception handler
attachExceptionHandler();
try try
{ {
// run the task // run the task
@ -151,6 +154,7 @@ namespace NLMISC
catch(...) catch(...)
{ {
nlwarning("CCoTask::startFunc : the task has generated an unhandled exeption and will terminate"); nlwarning("CCoTask::startFunc : the task has generated an unhandled exeption and will terminate");
NLMISC_BREAKPOINT;
} }
task->_Finished = true; task->_Finished = true;

@ -1157,6 +1157,15 @@ void destroyDebug()
} }
} }
void attachExceptionHandler()
{
#ifndef NL_COMP_MINGW
# ifdef NL_OS_WINDOWS
_set_se_translator(exceptionTranslator);
# endif // NL_OS_WINDOWS
#endif //!NL_COMP_MINGW
}
void createDebug (const char *logPath, bool logInFile, bool eraseLastLog) void createDebug (const char *logPath, bool logInFile, bool eraseLastLog)
{ {
// Do some basic compiler time check on type size // Do some basic compiler time check on type size

@ -171,15 +171,16 @@ bool CIXml::init (IStream &stream)
// Try binary mode // Try binary mode
if (_TryBinaryMode) if (_TryBinaryMode)
{ {
char header[4]; char header[5];
header[0] = buffer[0]; header[0] = buffer[0];
header[1] = buffer[1]; header[1] = buffer[1];
header[2] = buffer[2]; header[2] = buffer[2];
header[3] = buffer[3]; header[3] = buffer[3];
header[4] = '\0';
toLower(header); toLower(header);
// Does it a xml stream ? // Does it a xml stream ?
if (!strcmp(header, "<?xm")) if (strcmp(header, "<?xm"))
{ {
// NO ! Go in binary mode // NO ! Go in binary mode
_BinaryStream = &stream; _BinaryStream = &stream;

@ -179,7 +179,6 @@
#else #else
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/sysctl.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
# include <cerrno> # include <cerrno>

@ -67,6 +67,9 @@ static unsigned long __stdcall ProxyFunc (void *arg)
// Set the thread pointer in TLS memory // Set the thread pointer in TLS memory
nlverify (TlsSetValue (TLSThreadPointer, (void*)parent) != 0); nlverify (TlsSetValue (TLSThreadPointer, (void*)parent) != 0);
// Attach exception handler
attachExceptionHandler();
// Run the thread // Run the thread
parent->Runnable->run(); parent->Runnable->run();

@ -2090,6 +2090,14 @@ void CUnifiedNetwork::addNetworkAssociation (const string &networkName, uint8 ni
void CUnifiedNetwork::callServiceUpCallback (const std::string &serviceName, TServiceId sid, bool callGlobalCallback) void CUnifiedNetwork::callServiceUpCallback (const std::string &serviceName, TServiceId sid, bool callGlobalCallback)
{ {
std::pair<std::string, TServiceId> pss = std::make_pair(serviceName, sid);
if (_NotifiedUpCallbacks.find(pss) != _NotifiedUpCallbacks.end())
{
nlwarning("HNETL5: Attempt to call service UP callback twice for '%s', ignored!", serviceName.c_str());
return;
}
_NotifiedUpCallbacks.insert(pss);
// now we warn the user // now we warn the user
CUnifiedNetwork::TNameMappedCallback::iterator it = _UpCallbacks.find(serviceName); CUnifiedNetwork::TNameMappedCallback::iterator it = _UpCallbacks.find(serviceName);
if (it != _UpCallbacks.end()) if (it != _UpCallbacks.end())
@ -2119,6 +2127,14 @@ void CUnifiedNetwork::callServiceUpCallback (const std::string &serviceName, TSe
void CUnifiedNetwork::callServiceDownCallback (const std::string &serviceName, TServiceId sid, bool callGlobalCallback) void CUnifiedNetwork::callServiceDownCallback (const std::string &serviceName, TServiceId sid, bool callGlobalCallback)
{ {
std::pair<std::string, TServiceId> pss = std::make_pair(serviceName, sid);
if (_NotifiedUpCallbacks.find(pss) == _NotifiedUpCallbacks.end())
{
nlwarning("HNETL5: Attempt to call service DOWN callback twice for '%s', ignored!", serviceName.c_str());
return;
}
_NotifiedUpCallbacks.erase(pss);
// now we warn the user // now we warn the user
CUnifiedNetwork::TNameMappedCallback::iterator it = _DownCallbacks.find(serviceName); CUnifiedNetwork::TNameMappedCallback::iterator it = _DownCallbacks.find(serviceName);
if (it != _DownCallbacks.end()) if (it != _DownCallbacks.end())

@ -419,13 +419,13 @@ void CMoveContainer::updateCells (CMovePrimitive *primitive, uint8 worldImage)
// Check BB width not too large // Check BB width not too large
if (wI->getBBXMax() - wI->getBBXMin() > _CellWidth) if (wI->getBBXMax() - wI->getBBXMin() > _CellWidth)
{ {
nlwarning ("Primitives have moved more than a cell."); nlwarning ("Primitives have moved more than a cell, width: %f.", (float)(wI->getBBXMax() - wI->getBBXMin()));
} }
// Check BB height not too large // Check BB height not too large
if (wI->getBBYMax() - wI->getBBYMin() > _CellHeight) if (wI->getBBYMax() - wI->getBBYMin() > _CellHeight)
{ {
nlwarning ("Primitives have moved more than a cell."); nlwarning ("Primitives have moved more than a cell, height: %f.", (float)(wI->getBBYMax() - wI->getBBYMin()));
} }
#endif #endif
#endif #endif

@ -56,18 +56,12 @@ IAudioDecoder::~IAudioDecoder()
IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &filepath, bool async, bool loop) IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &filepath, bool async, bool loop)
{ {
std::string lookup = CPath::lookup(filepath, false);
if (lookup.empty())
{
nlwarning("Music file %s does not exist!", filepath.c_str());
return NULL;
}
std::string type = CFile::getExtension(filepath); std::string type = CFile::getExtension(filepath);
CIFile *ifile = new CIFile(); CIFile *ifile = new CIFile();
ifile->setCacheFileOnOpen(!async); ifile->setCacheFileOnOpen(!async);
ifile->allowBNPCacheFileOnOpen(!async); ifile->allowBNPCacheFileOnOpen(!async);
ifile->open(lookup); ifile->open(filepath);
IAudioDecoder *mb = createAudioDecoder(type, ifile, loop); IAudioDecoder *mb = createAudioDecoder(type, ifile, loop);
@ -116,10 +110,9 @@ IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC
bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length)
{ {
std::string lookup = CPath::lookup(filepath, false); if (filepath.empty() || !CFile::fileExists(filepath))
if (lookup.empty())
{ {
nlwarning("Music file %s does not exist!", filepath.c_str()); nlwarning("Music file '%s' does not exist!", filepath.c_str());
return false; return false;
} }
@ -127,7 +120,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length); return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length);
#else #else
std::string type = CFile::getExtension(filepath); std::string type = CFile::getExtension(filepath);
@ -138,7 +131,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length); return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str()); nlwarning("Unable to open: '%s'", filepath.c_str());
@ -149,7 +142,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderMP3::getInfo(&ifile, artist, title, length); return CAudioDecoderMP3::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str()); nlwarning("Unable to open: '%s'", filepath.c_str());

@ -496,36 +496,20 @@ bool getTag (std::string &result, const char *tag, FSOUND_STREAM *stream)
} }
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */
bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title, float &length)
{ {
/* Open a stream, get the tag if it exists, close the stream */ if (filepath.empty() || !CFile::fileExists(filepath))
string pathName = CPath::lookup(filepath, false);
uint32 fileOffset = 0, fileSize = 0;
if (pathName.empty())
{ {
nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str()); nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str());
return false; return false;
} }
// if the file is in a bnp
if (pathName.find('@') != string::npos)
{
if (CBigFile::getInstance().getFileInfo(pathName, fileSize, fileOffset))
{
// set pathname to bnp
pathName = pathName.substr(0, pathName.find('@'));
}
else
{
nlwarning("NLSOUND FMod Driver: BNP BROKEN");
return false;
}
}
FSOUND_STREAM *stream = FSOUND_Stream_Open((const char *)CPath::lookup(filepath, false).c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize); uint32 fileOffset = 0, fileSize = 0;
FSOUND_STREAM *stream = FSOUND_Stream_Open(filepath.c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize);
if (stream) if (stream)
{ {
getTag(artist, "ARTIST", stream); getTag(artist, "ARTIST", stream);

@ -112,7 +112,7 @@ public:
virtual IMusicChannel *createMusicChannel(); virtual IMusicChannel *createMusicChannel();
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */

@ -480,7 +480,7 @@ void CSourceXAudio2::setLooping(bool l)
_SourceVoice->GetState(&voice_state); _SourceVoice->GetState(&voice_state);
if (voice_state.BuffersQueued) if (voice_state.BuffersQueued)
{ {
nlwarning(NLSOUND_XAUDIO2_PREFIX "Not playing but buffer already queued while switching loop mode!?! Flush and requeue"); // nlwarning(NLSOUND_XAUDIO2_PREFIX "Not playing but buffer already queued while switching loop mode!?! Flush and requeue");
if (FAILED(_SourceVoice->FlushSourceBuffers())) if (FAILED(_SourceVoice->FlushSourceBuffers()))
nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED FlushSourceBuffers"); nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED FlushSourceBuffers");
// queue buffer with correct looping parameters // queue buffer with correct looping parameters

@ -147,7 +147,7 @@ void CMusicChannelFader::updateVolume()
*/ */
bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool async, bool loop) bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool async, bool loop)
{ {
stop(xFadeTime); bool stopped = stop(xFadeTime);
// Find the next best free music channel // Find the next best free music channel
uint nextFader = _MaxMusicFader; uint nextFader = _MaxMusicFader;
@ -164,7 +164,7 @@ bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool
// Play a song in it :) // Play a song in it :)
_CMusicFader &fader = _MusicFader[_ActiveMusicFader]; _CMusicFader &fader = _MusicFader[_ActiveMusicFader];
if (xFadeTime) fader.fadeIn(xFadeTime); if (xFadeTime && !stopped) fader.fadeIn(xFadeTime); // only fade in when fading out
else fader.XFadeVolume = 1.0f; else fader.XFadeVolume = 1.0f;
fader.Playing = true; fader.Playing = true;
updateVolume(); // make sure at ok volume to start :) updateVolume(); // make sure at ok volume to start :)
@ -173,12 +173,17 @@ bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool
} }
/// Stop the music previously loaded and played (the Memory is also freed) /// Stop the music previously loaded and played (the Memory is also freed)
void CMusicChannelFader::stop(uint xFadeTime) bool CMusicChannelFader::stop(uint xFadeTime)
{ {
if (xFadeTime) if (xFadeTime)
{ {
bool stopped = true;
for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].Playing) for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].Playing)
{
_MusicFader[i].fadeOut(xFadeTime); _MusicFader[i].fadeOut(xFadeTime);
stopped = false; // fading
}
return stopped;
} }
else else
{ {
@ -188,6 +193,7 @@ void CMusicChannelFader::stop(uint xFadeTime)
_MusicFader[i].Fade = false; _MusicFader[i].Fade = false;
_MusicFader[i].Playing = false; _MusicFader[i].Playing = false;
} }
return true;
} }
} }

@ -108,6 +108,13 @@ void CStreamFileSource::play()
//{ //{
// nlwarning("Already waiting for play"); // nlwarning("Already waiting for play");
//} //}
std::string filepath = getStreamFileSound()->getFilePath();
m_LookupPath = NLMISC::CPath::lookup(filepath, false, false);
if (m_LookupPath.empty())
{
nlwarning("Music file %s does not exist!", filepath.c_str());
return;
}
if (!getStreamFileSound()->getAsync()) if (!getStreamFileSound()->getAsync())
{ {
if (!prepareDecoder()) if (!prepareDecoder())
@ -272,7 +279,8 @@ bool CStreamFileSource::prepareDecoder()
if (!m_AudioDecoder) if (!m_AudioDecoder)
{ {
// load the file // load the file
m_AudioDecoder = IAudioDecoder::createAudioDecoder(getStreamFileSound()->getFilePath(), getStreamFileSound()->getAsync(), getStreamFileSound()->getLooping()); nlassert(!m_LookupPath.empty());
m_AudioDecoder = IAudioDecoder::createAudioDecoder(m_LookupPath, getStreamFileSound()->getAsync(), getStreamFileSound()->getLooping());
if (!m_AudioDecoder) if (!m_AudioDecoder)
{ {
nlwarning("Failed to create IAudioDecoder, likely invalid format"); nlwarning("Failed to create IAudioDecoder, likely invalid format");

@ -191,7 +191,11 @@ bool CCurlHttpClient::receive(string &res, bool verbose)
// *************************************************************************** // ***************************************************************************
void CCurlHttpClient::disconnect() void CCurlHttpClient::disconnect()
{ {
curl_easy_cleanup(_Curl); if (_CurlStruct)
{
curl_easy_cleanup(_Curl);
_CurlStruct = NULL;
}
curl_global_cleanup(); curl_global_cleanup();
} }

@ -135,6 +135,9 @@ bool CLodTextureBuilder::computeTexture(const CMeshMRM &meshMRM, NL3D::CLodCha
const uint8 *srcPos= (const uint8*)vba.getVertexCoordPointer(); const uint8 *srcPos= (const uint8*)vba.getVertexCoordPointer();
const uint8 *srcNormal= (const uint8*)vba.getNormalCoordPointer(); const uint8 *srcNormal= (const uint8*)vba.getNormalCoordPointer();
const uint8 *srcUV= (const uint8*)vba.getTexCoordPointer(); const uint8 *srcUV= (const uint8*)vba.getTexCoordPointer();
nlassert(srcPos);
nlassert(srcNormal);
nlassert(srcUV);
uint vertexSize = VB.getVertexSize(); uint vertexSize = VB.getVertexSize();
// For the more precise lod // For the more precise lod
uint lodId= meshMRM.getNbLod()-1; uint lodId= meshMRM.getNbLod()-1;

@ -22,4 +22,4 @@ database_server =
client_directory = R:/code/snowballs2/client/data/3d client_directory = R:/code/snowballs2/client/data/3d
# DFN directories # DFN directories
dfn_directory = L:\leveldesign\DFN dfn_directory = R:\leveldesign\DFN

@ -7,7 +7,7 @@ BanksPath = "../smallbank/smallbank/";
Bank = "rbank_bank_name"; Bank = "rbank_bank_name";
ZoneExt = ".zonew"; ZoneExt = ".zonew";
IGBoxes = "bbox/temp.bbox"; IGBoxes = "bbox/temp.bbox";
LevelDesignWorldPath = "l:/leveldesign/World"; LevelDesignWorldPath = "R:/leveldesign/world";
IgLandPath = "../ig/ig_land"; IgLandPath = "../ig/ig_land";
IgVillagePath = "../ig/ig_other"; IgVillagePath = "../ig/ig_other";

@ -7,7 +7,7 @@ BanksPath = "../smallbank/smallbank/";
Bank = "rbank_bank_name"; Bank = "rbank_bank_name";
ZoneExt = ".zonew"; ZoneExt = ".zonew";
IGBoxes = "bbox/temp.bbox"; IGBoxes = "bbox/temp.bbox";
LevelDesignWorldPath = "l:/leveldesign/World"; LevelDesignWorldPath = "R:/leveldesign/world";
IgLandPath = "../ig/ig_land"; IgLandPath = "../ig/ig_land";
IgVillagePath = "../ig/ig_other"; IgVillagePath = "../ig/ig_other";

@ -256,9 +256,9 @@ int main(int nNbArg, char**ppArgs)
printf ("InputIGDir = \"ig_land_max\";\n"); printf ("InputIGDir = \"ig_land_max\";\n");
printf ("OutputIGDir = \"ig_land_max_elev\";\n"); printf ("OutputIGDir = \"ig_land_max_elev\";\n");
printf ("CellSize = 160.0;\n"); printf ("CellSize = 160.0;\n");
printf ("HeightMapFile1 = \"w:/database/landscape/ligo/jungle/big.tga\";\n"); printf ("HeightMapFile1 = \"R:/graphics/landscape/ligo/jungle/big.tga\";\n");
printf ("ZFactor1 = 1.0;\n"); printf ("ZFactor1 = 1.0;\n");
printf ("HeightMapFile2 = \"w:/database/landscape/ligo/jungle/noise.tga\";\n"); printf ("HeightMapFile2 = \"R:/graphics/landscape/ligo/jungle/noise.tga\";\n");
printf ("ZFactor2 = 0.5;\n"); printf ("ZFactor2 = 0.5;\n");
printf ("LandFile = \"w:/matis.land\";\n"); printf ("LandFile = \"w:/matis.land\";\n");

@ -3,29 +3,29 @@
// your searhc pathes, (where to find textures, shapes, tiles, zones ...) // your searhc pathes, (where to find textures, shapes, tiles, zones ...)
search_pathes = search_pathes =
{ {
"w:\database\stuff\fyros\agents\_textures\actors", "R:\graphics\stuff\fyros\agents\_textures\actors",
"w:\database\stuff\tryker\agents\_textures\actors", "R:\graphics\stuff\tryker\agents\_textures\actors",
"w:\database\stuff\matis\agents\_textures\actors", "R:\graphics\stuff\matis\agents\_textures\actors",
"w:\database\stuff\zorai\agents\_textures\actors", "R:\graphics\stuff\zorai\agents\_textures\actors",
"w:\database\stuff\fyros\agents\_textures\monster", "R:\graphics\stuff\fyros\agents\_textures\monster",
"w:\database\stuff\tryker\agents\_textures\monster", "R:\graphics\stuff\tryker\agents\_textures\monster",
"w:\database\stuff\matis\agents\_textures\monster", "R:\graphics\stuff\matis\agents\_textures\monster",
"w:\database\stuff\zorai\agents\_textures\monster", "R:\graphics\stuff\zorai\agents\_textures\monster",
"w:\database\stuff\fyros\agents\_textures\accessories", "R:\graphics\stuff\fyros\agents\_textures\accessories",
"w:\database\stuff\tryker\agents\_textures\accessories", "R:\graphics\stuff\tryker\agents\_textures\accessories",
"w:\database\stuff\matis\agents\_textures\accessories", "R:\graphics\stuff\matis\agents\_textures\accessories",
"w:\database\stuff\zorai\agents\_textures\accessories", "R:\graphics\stuff\zorai\agents\_textures\accessories",
"W:\Database\Stuff\Matis\Decors\_textures\batiments", "R:\graphics\Stuff\Matis\Decors\_textures\batiments",
"W:\Database\Stuff\zorai\Decors\_textures\batiments", "R:\graphics\Stuff\zorai\Decors\_textures\batiments",
"W:\Database\Stuff\tryker\Decors\_textures\batiments", "R:\graphics\Stuff\tryker\Decors\_textures\batiments",
"W:\Database\Stuff\fyros\Decors\_textures\batiments", "R:\graphics\Stuff\fyros\Decors\_textures\batiments",
"W:\Database\Stuff\fyros\Decors\_textures", "R:\graphics\Stuff\fyros\Decors\_textures",
"W:\Database\SFX\maps", "R:\graphics\SFX\maps",
"W:\Database\SFX\old_shapes", "R:\graphics\SFX\old_shapes",
"W:\Database\Stuff\Primes_Racines\Agents\_textures\Monster", "R:\graphics\Stuff\Primes_Racines\Agents\_textures\Monster",
"W:\Database\Stuff\Jungle\Agents\_textures\Monster", "R:\graphics\Stuff\Jungle\Agents\_textures\Monster",
"W:\Database\Stuff\Goo\Agents\_textures\monster", "R:\graphics\Stuff\Goo\Agents\_textures\monster",
"W:\Database\Stuff\caravan\Agents\_textures\Actors", "R:\graphics\Stuff\caravan\Agents\_textures\Actors",
}; };
recursive_search_pathes= recursive_search_pathes=

@ -427,7 +427,7 @@ void doFileInitialize(const std::string &filePath)
KnownFileCache[NLMISC::CFile::getFilename(filePath)] = standardizePath(filePath, false); KnownFileCache[NLMISC::CFile::getFilename(filePath)] = standardizePath(filePath, false);
} }
// maxRewritePaths W:/database/interfaces/anims_max // maxRewritePaths R:/graphics/interfaces/anims_max
void doDirectoryInitialize(const std::string &directoryPath) void doDirectoryInitialize(const std::string &directoryPath)
{ {

@ -21,6 +21,7 @@
#define NLMAX_STRING_COMMON_H #define NLMAX_STRING_COMMON_H
#include <nel/misc/ucstring.h> #include <nel/misc/ucstring.h>
#include <nel/misc/string_common.h>
#if (MAX_VERSION_MAJOR < 15) #if (MAX_VERSION_MAJOR < 15)
#define GET_OBJECT_NAME_CONST #define GET_OBJECT_NAME_CONST
@ -37,9 +38,7 @@ static TSTR MaxTStrFromUtf8(const std::string &src)
{ {
TSTR dst; TSTR dst;
#if (MAX_VERSION_MAJOR < 15) #if (MAX_VERSION_MAJOR < 15)
ucstring uc; dst = nlUtf8ToTStr(src);
uc.fromUtf8(src);
dst = (const mwchar_t *)uc.c_str();
#else #else
dst.FromUTF8(src.c_str()); dst.FromUTF8(src.c_str());
#endif #endif
@ -49,14 +48,7 @@ static TSTR MaxTStrFromUtf8(const std::string &src)
static std::string MaxTStrToUtf8(const TSTR& src) static std::string MaxTStrToUtf8(const TSTR& src)
{ {
#if (MAX_VERSION_MAJOR < 15) #if (MAX_VERSION_MAJOR < 15)
#ifdef _UNICODE return NLMISC::tStrToUtf8(src.data());
ucstring uc(src.data());
return uc.toUtf8();
#else
WStr ws = src;
ucstring uc((const ucchar *)ws.data());
return uc.toUtf8();
#endif
#else #else
return src.ToUTF8().data(); return src.ToUTF8().data();
#endif #endif
@ -64,13 +56,7 @@ static std::string MaxTStrToUtf8(const TSTR& src)
static std::string MCharStrToUtf8(const MCHAR *src) static std::string MCharStrToUtf8(const MCHAR *src)
{ {
#ifdef _UNICODE return NLMISC::tStrToUtf8(src);
ucstring uc((const ucchar *)src);
return uc.toUtf8();
#else
ucstring uc((const ucchar *)WStr(src).data());
return uc.toUtf8();
#endif
} }
#endif /* #ifndef NLMAX_STRING_COMMON_H */ #endif /* #ifndef NLMAX_STRING_COMMON_H */

@ -1271,7 +1271,7 @@ Value* get_patch_vertex_cf (Value** arg_list, int count)
// Check to see if the arguments match up to what we expect // Check to see if the arguments match up to what we expect
// We want to use 'TurnAllTexturesOn <object to use>' // We want to use 'TurnAllTexturesOn <object to use>'
const MCHAR *message= _M("NeLGetPatchVertex [NeLPatchMesh] [PatchId] [VertexId]"); MCHAR *message= _M("NeLGetPatchVertex [NeLPatchMesh] [PatchId] [VertexId]");
type_check(arg_list[0], MAXNode, message); type_check(arg_list[0], MAXNode, message);
type_check(arg_list[1], Integer, message); type_check(arg_list[1], Integer, message);
type_check(arg_list[2], Integer, message); type_check(arg_list[2], Integer, message);

@ -4,7 +4,7 @@ NEL3D_APPDATA_INTERFACE_FILE = 1423062700
-- Allocate 20 Me for the script -- Allocate 20 Me for the script
heapSize += 30000000 heapSize += 30000000
nlErrorFilename = "W:/database/timings.log" nlErrorFilename = "R:/graphics/timings.log"
nlErrorStream = openFile nlErrorFilename mode:"w" nlErrorStream = openFile nlErrorFilename mode:"w"
if nlErrorStream == undefined then if nlErrorStream == undefined then
nlErrorStream = createFile nlErrorFilename nlErrorStream = createFile nlErrorFilename
@ -171,7 +171,7 @@ rollout assets_resave_rollout "Properties"
ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
Progress.value = i*100/files.count Progress.value = i*100/files.count
if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then if (UseTag.checked == false) or ((NeLTestFileDate file "R:/graphics/conversion.tag") == true) then
( (
resetMAXFile #noprompt resetMAXFile #noprompt

@ -4,7 +4,7 @@ NEL3D_APPDATA_INTERFACE_FILE = 1423062700
-- Allocate 20 Me for the script -- Allocate 20 Me for the script
heapSize += 15000000 heapSize += 15000000
nlErrorFilename = "W:/database/conversion.log" nlErrorFilename = "R:/graphics/conversion.log"
nlErrorStream = openFile nlErrorFilename mode:"w" nlErrorStream = openFile nlErrorFilename mode:"w"
if nlErrorStream == undefined then if nlErrorStream == undefined then
nlErrorStream = createFile nlErrorFilename nlErrorStream = createFile nlErrorFilename
@ -447,7 +447,7 @@ rollout assets_png_rollout "Properties"
ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
Progress.value = i*100/files.count Progress.value = i*100/files.count
if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then if (UseTag.checked == false) or ((NeLTestFileDate file "R:/graphics/conversion.tag") == true) then
( (
resetMAXFile #noprompt resetMAXFile #noprompt

@ -4,7 +4,7 @@ NEL3D_APPDATA_INTERFACE_FILE = 1423062700
-- Allocate 20 Me for the script -- Allocate 20 Me for the script
heapSize += 15000000 heapSize += 15000000
nlErrorFilename = "W:/database/conversion.log" nlErrorFilename = "R:/graphics/conversion.log"
nlErrorStream = openFile nlErrorFilename mode:"w" nlErrorStream = openFile nlErrorFilename mode:"w"
if nlErrorStream == undefined then if nlErrorStream == undefined then
nlErrorStream = createFile nlErrorFilename nlErrorStream = createFile nlErrorFilename
@ -230,7 +230,7 @@ rollout assets_ps_rollout "Properties"
ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
Progress.value = i*100/files.count Progress.value = i*100/files.count
if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then if (UseTag.checked == false) or ((NeLTestFileDate file "R:/graphics/conversion.tag") == true) then
( (
resetMAXFile #noprompt resetMAXFile #noprompt

@ -4,7 +4,7 @@ NEL3D_APPDATA_INTERFACE_FILE = 1423062700
-- Allocate 20 Me for the script -- Allocate 20 Me for the script
heapSize += 15000000 heapSize += 15000000
nlErrorFilename = "W:/database/conversion.log" nlErrorFilename = "R:/graphics/conversion.log"
nlErrorStream = openFile nlErrorFilename mode:"w" nlErrorStream = openFile nlErrorFilename mode:"w"
if nlErrorStream == undefined then if nlErrorStream == undefined then
nlErrorStream = createFile nlErrorFilename nlErrorStream = createFile nlErrorFilename
@ -171,7 +171,7 @@ rollout assets_resave_rollout "Properties"
ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
Progress.value = i*100/files.count Progress.value = i*100/files.count
if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then if (UseTag.checked == false) or ((NeLTestFileDate file "R:/graphics/conversion.tag") == true) then
( (
resetMAXFile #noprompt resetMAXFile #noprompt

@ -4,7 +4,7 @@ NEL3D_APPDATA_INTERFACE_FILE = 1423062700
-- Allocate 20 Me for the script -- Allocate 20 Me for the script
heapSize += 15000000 heapSize += 15000000
nlErrorFilename = "W:/database/conversion.log" nlErrorFilename = "R:/graphics/conversion.log"
nlErrorStream = openFile nlErrorFilename mode:"w" nlErrorStream = openFile nlErrorFilename mode:"w"
if nlErrorStream == undefined then if nlErrorStream == undefined then
nlErrorStream = createFile nlErrorFilename nlErrorStream = createFile nlErrorFilename
@ -171,7 +171,7 @@ rollout assets_resave_rollout "Properties"
ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
Progress.value = i*100/files.count Progress.value = i*100/files.count
if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then if (UseTag.checked == false) or ((NeLTestFileDate file "R:/graphics/conversion.tag") == true) then
( (
resetMAXFile #noprompt resetMAXFile #noprompt

@ -34,12 +34,12 @@ struct metazone (name, posMin, posMax)
-- Trykers : X: [194 - 215] Y: [DV - EW] Generate : X: [96 - 115] Y: [-215 - -215+22] -- Trykers : X: [194 - 215] Y: [DV - EW] Generate : X: [96 - 115] Y: [-215 - -215+22]
-- Parameters, uppercase for cell position -- Parameters, uppercase for cell position
old_zone_directory_fyros = "w:/database/landscape/zones/fyros" old_zone_directory_fyros = "R:/graphics/landscape/zones/fyros"
ligo_directory_fyros = "w:/database/landscape/ligo/desert" ligo_directory_fyros = "R:/graphics/landscape/ligo/desert"
metazones_fyros = #(metazone "1_MZ_city" "152_EK" "155_EO", metazone "bridge_a" "158_EM" "158_EO", metazone "brandon" "164_ES" "165_ET", metazone "ecorce_A" "155_EI" "157_EJ") metazones_fyros = #(metazone "1_MZ_city" "152_EK" "155_EO", metazone "bridge_a" "158_EM" "158_EO", metazone "brandon" "164_ES" "165_ET", metazone "ecorce_A" "155_EI" "157_EJ")
old_zone_directory_tryker = "w:/database/landscape/zones/tryker" old_zone_directory_tryker = "R:/graphics/landscape/zones/tryker"
ligo_directory_tryker = "r:/database/landscape/ligo/lacustre" ligo_directory_tryker = "R:/graphics/landscape/ligo/lacustre"
metazones_tryker = #(metazone "village_a" "205_EC" "208_EE", metazone "village_b" "199_EH" "200_EI", metazone "village_c" "206_EH" "208_EJ", metazone "village_d" "206_DS" "208_DU") metazones_tryker = #(metazone "village_a" "205_EC" "208_EE", metazone "village_b" "199_EH" "200_EI", metazone "village_c" "206_EH" "208_EJ", metazone "village_d" "206_DS" "208_DU")
cell_size = 160.0 cell_size = 160.0

@ -5,8 +5,8 @@ size_x = 7680-320
from_y = -25600+160 from_y = -25600+160
size_y = 5120-320 size_y = 5120-320
targetdir = "W:/database/landscape/ligo/asteroids/max" targetdir = "R:/graphics/landscape/ligo/asteroids/max"
snapshotdir = "W:/database/landscape/ligo/asteroids/zonebitmaps" snapshotdir = "R:/graphics/landscape/ligo/asteroids/zonebitmaps"
zonename = "anne" zonename = "anne"
resumeonly = true resumeonly = true

@ -66,7 +66,7 @@ if not args.noconf:
try: try:
ToolDirectories ToolDirectories
except NameError: except NameError:
ToolDirectories = [ 'R:/build/dev/bin/Release', 'D:/libraries/external/bin' ] ToolDirectories = [ 'R:/build/dev/bin/Release', 'R:/external/bin' ]
try: try:
ToolSuffix ToolSuffix
except NameError: except NameError:
@ -78,63 +78,63 @@ if not args.noconf:
try: try:
WorkspaceDirectory WorkspaceDirectory
except NameError: except NameError:
WorkspaceDirectory = "L:/workspace" WorkspaceDirectory = "R:/leveldesign/workspace"
try: try:
DatabaseDirectory DatabaseDirectory
except NameError: except NameError:
DatabaseDirectory = "W:/database" DatabaseDirectory = "R:/graphics"
try: try:
SoundDirectory SoundDirectory
except NameError: except NameError:
SoundDirectory = "V:" SoundDirectory = "R:/sound"
try: try:
SoundDfnDirectory SoundDfnDirectory
except NameError: except NameError:
SoundDfnDirectory = "V:/DFN" SoundDfnDirectory = "R:/sound/DFN"
try: try:
ExportBuildDirectory ExportBuildDirectory
except NameError: except NameError:
ExportBuildDirectory = "T:/export" ExportBuildDirectory = "R:/pipeline/export"
try: try:
InstallDirectory InstallDirectory
except NameError: except NameError:
InstallDirectory = "T:/install" InstallDirectory = "R:/pipeline/install"
try: try:
ClientDevDirectory ClientDevDirectory
except NameError: except NameError:
ClientDevDirectory = "T:/client_dev" ClientDevDirectory = "R:/pipeline/client_dev"
try: try:
ClientPatchDirectory ClientPatchDirectory
except NameError: except NameError:
ClientPatchDirectory = "T:/client_patch" ClientPatchDirectory = "R:/pipeline/client_patch"
try: try:
ClientInstallDirectory ClientInstallDirectory
except NameError: except NameError:
ClientInstallDirectory = "T:/client_install" ClientInstallDirectory = "R:/pipeline/client_install"
try: try:
ShardInstallDirectory ShardInstallDirectory
except NameError: except NameError:
ShardInstallDirectory = "T:/shard" ShardInstallDirectory = "R:/pipeline/shard"
try: try:
WorldEditInstallDirectory WorldEditInstallDirectory
except NameError: except NameError:
WorldEditInstallDirectory = "T:/worldedit" WorldEditInstallDirectory = "R:/pipeline/worldedit"
try: try:
LeveldesignDirectory LeveldesignDirectory
except NameError: except NameError:
LeveldesignDirectory = "L:/leveldesign" LeveldesignDirectory = "R:/leveldesign"
try: try:
LeveldesignDfnDirectory LeveldesignDfnDirectory
except NameError: except NameError:
LeveldesignDfnDirectory = "L:/leveldesign/DFN" LeveldesignDfnDirectory = "R:/leveldesign/DFN"
try: try:
LeveldesignWorldDirectory LeveldesignWorldDirectory
except NameError: except NameError:
LeveldesignWorldDirectory = "L:/leveldesign/world" LeveldesignWorldDirectory = "R:/leveldesign/world"
try: try:
PrimitivesDirectory PrimitivesDirectory
except NameError: except NameError:
PrimitivesDirectory = "L:/primitives" PrimitivesDirectory = "R:/leveldesign/primitives"
try: try:
GamedevDirectory GamedevDirectory
except NameError: except NameError:
@ -150,15 +150,15 @@ if not args.noconf:
try: try:
LeveldesignDataShardDirectory LeveldesignDataShardDirectory
except NameError: except NameError:
LeveldesignDataShardDirectory = "L:/shard" LeveldesignDataShardDirectory = "R:/leveldesign/shard"
try: try:
LeveldesignDataCommonDirectory LeveldesignDataCommonDirectory
except NameError: except NameError:
LeveldesignDataCommonDirectory = "L:/common" LeveldesignDataCommonDirectory = "R:/leveldesign/common"
try: try:
TranslationDirectory TranslationDirectory
except NameError: except NameError:
TranslationDirectory = "L:/translation" TranslationDirectory = "R:/leveldesign/translation"
try: try:
WorldEditorFilesDirectory WorldEditorFilesDirectory
except NameError: except NameError:
@ -166,27 +166,27 @@ if not args.noconf:
try: try:
WindowsExeDllCfgDirectories WindowsExeDllCfgDirectories
except NameError: except NameError:
WindowsExeDllCfgDirectories = [ 'C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/redist/x86', 'D:/libraries/external/bin', 'R:/build/dev/bin/Release', 'R:/code/ryzom/client', 'R:/code/nel/lib', 'R:/code/ryzom/bin', 'R:/code/ryzom/tools/client/client_config/bin' ] WindowsExeDllCfgDirectories = [ 'C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/redist/x86', 'R:/external/bin', 'R:/build/dev/bin/Release', 'R:/code/ryzom/client', 'R:/code/nel/lib', 'R:/code/ryzom/bin', 'R:/code/ryzom/tools/client/client_config/bin' ]
try: try:
LinuxServiceExecutableDirectory LinuxServiceExecutableDirectory
except NameError: except NameError:
LinuxServiceExecutableDirectory = "S:/devls_x64/bin" LinuxServiceExecutableDirectory = "R:/build/gcc_server/bin"
try: try:
LinuxClientExecutableDirectory LinuxClientExecutableDirectory
except NameError: except NameError:
LinuxClientExecutableDirectory = "S:/devl_x64/bin" LinuxClientExecutableDirectory = "R:/build/gcc_client/bin"
try: try:
PatchmanCfgAdminDirectory PatchmanCfgAdminDirectory
except NameError: except NameError:
PatchmanCfgAdminDirectory = "R:/code/ryzom/server/patchman_cfg/admin_install" PatchmanCfgAdminDirectory = "R:/patchman/admin_install"
try: try:
PatchmanCfgDefaultDirectory PatchmanCfgDefaultDirectory
except NameError: except NameError:
PatchmanCfgDefaultDirectory = "R:/code/ryzom/server/patchman_cfg/default" PatchmanCfgDefaultDirectory = "R:/patchman/default"
try: try:
PatchmanBridgeServerDirectory PatchmanBridgeServerDirectory
except NameError: except NameError:
PatchmanBridgeServerDirectory = "T:/bridge_server" PatchmanBridgeServerDirectory = "R:/pipeline/bridge_server"
try: try:
SignToolExecutable SignToolExecutable
except NameError: except NameError:

@ -49,6 +49,9 @@ printLog(log, "-------")
printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time()))) printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time())))
printLog(log, "") printLog(log, "")
# Find tools
SevenZip = findTool(log, ToolDirectories, SevenZipTool, ToolSuffix)
# List the directories that will be used # List the directories that will be used
archiveDirectories = [ ] archiveDirectories = [ ]
for dir in InstallShardDataDirectories: for dir in InstallShardDataDirectories:
@ -89,23 +92,29 @@ else:
printLog(log, "") printLog(log, "")
if not args.admininstall: if not args.admininstall:
printLog(log, ">>> Create new version <<<") if SevenZip == "":
newVersion = 1 toolLogFail(log, SevenZipTool, ToolSuffix)
vstr = str(newVersion).zfill(6) else:
vpath = PatchmanBridgeServerDirectory + "/" + vstr printLog(log, ">>> Create new version <<<")
while os.path.exists(vpath): newVersion = 1
newVersion = newVersion + 1
vstr = str(newVersion).zfill(6) vstr = str(newVersion).zfill(6)
vpath = PatchmanBridgeServerDirectory + "/" + vstr vpath = PatchmanBridgeServerDirectory + "/" + vstr
mkPath(log, vpath) while os.path.exists(vpath):
for dir in archiveDirectories: newVersion = newVersion + 1
mkPath(log, ShardInstallDirectory + "/" + dir) vstr = str(newVersion).zfill(6)
tgzPath = vpath + "/" + dir + ".tgz" vpath = PatchmanBridgeServerDirectory + "/" + vstr
printLog(log, "WRITE " + tgzPath) mkPath(log, vpath)
tar = tarfile.open(tgzPath, "w:gz") for dir in archiveDirectories:
tar.add(ShardInstallDirectory + "/" + dir, arcname = dir) mkPath(log, ShardInstallDirectory + "/" + dir)
tar.close() # tgzPath = vpath + "/" + dir + ".tgz"
printLog(log, "") # printLog(log, "WRITE " + tgzPath)
# tar = tarfile.open(tgzPath, "w:gz")
# tar.add(ShardInstallDirectory + "/" + dir, arcname = dir)
# tar.close()
sevenZipPath = vpath + "/" + dir + ".7z"
printLog(log, "WRITE " + sevenZipPath)
subprocess.call([ SevenZip, "a", sevenZipPath, ShardInstallDirectory + "/" + dir ])
printLog(log, "")
log.close() log.close()
if os.path.isfile("c1_shard_patch.log"): if os.path.isfile("c1_shard_patch.log"):

@ -98,3 +98,4 @@ PatchGenTool = "patch_gen"
TranslationToolsTool = "translation_tools" TranslationToolsTool = "translation_tools"
BuildWorldPackedColTool = "build_world_packed_col" BuildWorldPackedColTool = "build_world_packed_col"
R2IslandsTexturesTool = "r2_islands_textures" R2IslandsTexturesTool = "r2_islands_textures"
SevenZipTool = "7za"

@ -123,7 +123,9 @@ else:
printLog(log, "") printLog(log, "")
printLog(log, ">>> Make bnp <<<") printLog(log, ">>> Make bnp <<<")
targetPath = ClientPatchDirectory + "/bnp" targetPath = ClientPatchDirectory + "/bnp"
tagPath = ClientPatchDirectory + "/bnp_tag"
mkPath(log, targetPath) mkPath(log, targetPath)
mkPath(log, tagPath)
for category in InstallClientData: for category in InstallClientData:
packExt = ".bnp" packExt = ".bnp"
if (category["StreamedPackages"]): if (category["StreamedPackages"]):
@ -133,25 +135,32 @@ else:
sourcePath = InstallDirectory + "/" + package[0] sourcePath = InstallDirectory + "/" + package[0]
mkPath(log, sourcePath) mkPath(log, sourcePath)
targetBnp = targetPath + "/" + package[0] + packExt targetBnp = targetPath + "/" + package[0] + packExt
tagBnp = tagPath + "/" + package[0] + packExt + ".tag"
if (len(package[1]) > 0): if (len(package[1]) > 0):
targetBnp = targetPath + "/" + package[1][0] targetBnp = targetPath + "/" + package[1][0]
tagBnp = tagPath + "/" + package[1][0] + ".tag"
printLog(log, "TARGET " + package[1][0]) printLog(log, "TARGET " + package[1][0])
needUpdateBnp = 1 needUpdateBnp = 1
if (len(package) > 2): if (len(package) > 2):
needUpdateBnp = needUpdate(log, sourcePath + "/" + package[2], targetBnp) needUpdateBnp = needUpdate(log, sourcePath + "/" + package[2], tagBnp)
else: else:
needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, targetBnp) needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, tagBnp)
if (needUpdateBnp): if (needUpdateBnp):
subRet = 0
open(tagBnp, 'a').close()
os.utime(tagBnp, None)
if (category["StreamedPackages"]): if (category["StreamedPackages"]):
printLog(log, "SNP " + targetBnp) printLog(log, "SNP " + targetBnp)
# cwDir = os.getcwd().replace("\\", "/") # cwDir = os.getcwd().replace("\\", "/")
# toolDir = os.path.dirname(Lzma).replace("\\", "/") # toolDir = os.path.dirname(Lzma).replace("\\", "/")
# os.chdir(toolDir) # os.chdir(toolDir)
subprocess.call([ SnpMake, "-p", sourcePath, targetBnp, ClientPatchDirectory + "/stream" ] + package[1][1:]) subRet = subprocess.call([ SnpMake, "-p", sourcePath, targetBnp, ClientPatchDirectory + "/stream" ] + package[1][1:])
# os.chdir(cwDir) # os.chdir(cwDir)
else: else:
printLog(log, "BNP " + targetBnp) printLog(log, "BNP " + targetBnp)
subprocess.call([ BnpMake, "-p", sourcePath, "-o", targetBnp ] + package[1][1:]) subRet = subprocess.call([ BnpMake, "-p", sourcePath, "-o", targetBnp ] + package[1][1:])
if (subRet != 0):
os.remove(tagBnp)
else: else:
printLog(log, "SKIP " + targetBnp) printLog(log, "SKIP " + targetBnp)
printLog(log, "") printLog(log, "")

@ -74,6 +74,13 @@ else:
printLog(log, ">>> Copy Shape <<<") printLog(log, ">>> Copy Shape <<<")
copyFilesExtNoTreeIfNeeded(log, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory, ".shape") copyFilesExtNoTreeIfNeeded(log, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory, ".shape")
printLog(log, ">>> Copy non-ShadowSkin non-CLodTex Shape <<<")
shapeDirectory = ExportBuildDirectory + "/" + ShapeNotOptimizedExportDirectory
mkPath(log, shapeDirectory)
mkPath(log, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory)
copyFilesExtNoTreeIfNeeded(log, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory, ".shape")
shapeDirectory = ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory
# copy lightmap_not_optimized to lightmap # copy lightmap_not_optimized to lightmap
printLog(log, ">>> Optimize lightmaps <<<") printLog(log, ">>> Optimize lightmaps <<<")
loPathLightmapsOriginal = ExportBuildDirectory + "/" + ShapeLightmapNotOptimizedExportDirectory loPathLightmapsOriginal = ExportBuildDirectory + "/" + ShapeLightmapNotOptimizedExportDirectory

@ -1,5 +1,5 @@
MainDirectory = "w:\database"; MainDirectory = "R:\graphics";
MirrorDirectory = "q:\database"; MirrorDirectory = "Q:\graphics";
LogDirectory = ""; LogDirectory = "";
BinaryCompare = "false"; BinaryCompare = "false";
IgnoreDirectory = ""; IgnoreDirectory = "";

@ -72,7 +72,7 @@ bool CPrimChecker::build(const string &primitivesPath, const string &igLandPath,
// Init ligo // Init ligo
if (!LigoConfig.readPrimitiveClass ("world_editor_classes.xml", false)) if (!LigoConfig.readPrimitiveClass ("world_editor_classes.xml", false))
{ {
// Should be in l:\leveldesign\world_edit_files // Should be in R:\leveldesign\world_edit_files
nlwarning ("Can't load ligo primitive config file world_editor_classes.xml"); nlwarning ("Can't load ligo primitive config file world_editor_classes.xml");
return false; return false;
} }

@ -3,8 +3,8 @@
build_sound <leveldesign> <dfn> <source_samplebanks> <build_packed_sheets> <build_samplebanks> build_sound <leveldesign> <dfn> <source_samplebanks> <build_packed_sheets> <build_samplebanks>
leveldesign = L:\leveldesign\ leveldesign = R:\leveldesign\
dfn = L:\leveldesign\dfn\ dfn = R:\leveldesign\dfn\
source_samplebanks = L:\assets\sound\samplebanks\ source_samplebanks = L:\assets\sound\samplebanks\
build_packed_sheets = L:\build\sound_sheets\ build_packed_sheets = L:\build\sound_sheets\
build_samplebanks = L:\build\sound_samplebanks\ build_samplebanks = L:\build\sound_samplebanks\

@ -1 +1 @@
build_sound_r L:\leveldesign\ L:\leveldesign\dfn\ L:\assets\sound\samplebanks\ L:\build\sound_sheets\ L:\build\sound_samplebanks build_sound_r R:\leveldesign\ R:\leveldesign\dfn\ L:\assets\sound\samplebanks\ L:\build\sound_sheets\ L:\build\sound_samplebanks

@ -3,8 +3,8 @@
build_soundbank <leveldesign> <dfn> <build_packed_sheets> build_soundbank <leveldesign> <dfn> <build_packed_sheets>
leveldesign = L:\leveldesign\ leveldesign = R:\leveldesign\
dfn = L:\leveldesign\dfn\ dfn = R:\leveldesign\dfn\
build_packed_sheets = L:\build\sound_sheets\ build_packed_sheets = L:\build\sound_sheets\
Where L:\ is your game content database. Where L:\ is your game content database.

@ -1 +1 @@
build_soundbank_r L:\leveldesign\ L:\leveldesign\dfn\ L:\build\sound_sheets\ build_soundbank_r R:\leveldesign\ R:\leveldesign\dfn\ L:\build\sound_sheets\

@ -340,6 +340,9 @@ R2EDMaxMapScale = 8.0;
WindowSnapInvert = 0; WindowSnapInvert = 0;
WindowSnapDistance = 10; WindowSnapDistance = 10;
WindowSnapDistance_min = 0;
WindowSnapDistance_max = 50;
WindowSnapDistance_step = 1;
////////////////// //////////////////
// SOUND CONFIG // // SOUND CONFIG //

@ -919,7 +919,7 @@ This MUST follow the Enum MISSION_DESC::TIconId
<param name="ctrl_sheet_greenify_color" value="140 255 140 150" /> <param name="ctrl_sheet_greenify_color" value="140 255 140 150" />
<param name="ctrl_text_greenify_color" value="140 255 140 150" /> <param name="ctrl_text_greenify_color" value="140 255 140 150" />
<param name="text_over_back_color" value="64 64 64 255" /> <param name="text_over_back_color" value="64 64 64 255" />
<param name="font" value="noto_sans_display.ttf" /> <param name="font" value="noto_sans.ttf" />
<param name="monospace_font" value="noto_mono.ttf" /> <param name="monospace_font" value="noto_mono.ttf" />
<param name="add_coef_font" value="1" /> <param name="add_coef_font" value="1" />
<param name="mul_coef_anim" value="0.8" /> <param name="mul_coef_anim" value="0.8" />

@ -909,18 +909,18 @@ function RingPlayerInfo:fill(ringPoints)
-- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDMasterlessRingRatingTooltip") -- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDMasterlessRingRatingTooltip")
-- ecosystem Points -- ecosystem Points
local ecosystems = {"Basic", "Desert", "Subtropic", "Forest", "Jungle", "PrimeRoot"} -- local ecosystems = {"Basic", "Desert", "Subtropic", "Forest", "Jungle", "PrimeRoot"}
for k, eco in pairs(ecosystems) do -- for k, eco in pairs(ecosystems) do
local ecoVal = tostring(ringPoints[eco.."RingPoints"]) -- local ecoVal = tostring(ringPoints[eco.."RingPoints"])
local ecoValMax = tostring(ringPoints["Max" .. eco.."RingPoints"]) -- local ecoValMax = tostring(ringPoints["Max" .. eco.."RingPoints"])
local ecoUI = ui:find(string.lower(eco)) -- local ecoUI = ui:find(string.lower(eco))
local maxUI = ecoUI:find("max") -- local maxUI = ecoUI:find("max")
local valUI = ecoUI:find("val") -- local valUI = ecoUI:find("val")
tooltipUI = ecoUI:find("tt") -- tooltipUI = ecoUI:find("tt")
maxUI.hardtext = ecoValMax -- maxUI.hardtext = ecoValMax
valUI.hardtext = ecoVal -- valUI.hardtext = ecoVal
tooltipUI.tooltip = self:tooltipEcosystemPoints(ecoVal, ecoValMax, "uiR2ED" .. eco .. "PointsTooltip") -- tooltipUI.tooltip = self:tooltipEcosystemPoints(ecoVal, ecoValMax, "uiR2ED" .. eco .. "PointsTooltip")
end -- end
end end
-------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------

@ -428,7 +428,7 @@ This MUST follow the Enum MISSION_DESC::TIconId
<param name="ctrl_sheet_gray_color" value="255 255 255 100" /> <param name="ctrl_sheet_gray_color" value="255 255 255 100" />
<param name="ctrl_sheet_redify_color" value="255 100 100 100" /> <param name="ctrl_sheet_redify_color" value="255 100 100 100" />
<param name="ctrl_text_redify_color" value="255 32 32 160" /> <param name="ctrl_text_redify_color" value="255 32 32 160" />
<param name="font" value="noto_sans_display.ttf" /> <param name="font" value="noto_sans.ttf" />
<param name="monospace_font" value="noto_mono.ttf" /> <param name="monospace_font" value="noto_mono.ttf" />
<param name="add_coef_font" value="3" /> <param name="add_coef_font" value="3" />
<param name="mul_coef_anim" value="0.8" /> <param name="mul_coef_anim" value="0.8" />

@ -1037,10 +1037,11 @@
<!-- Music playing --> <!-- Music playing -->
<action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,0)" params="name=Character Creation Fyros.ogg|async=1" /> <!-- Play character creation music -->
<action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,1)" params="name=Character Creation Matis.ogg|async=1" /> <action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,0)" params="name=character creation fyros.ogg|async=1" />
<action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,2)" params="name=Character Creation Trykers.ogg|async=1" /> <action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,1)" params="name=character creation matis.ogg|async=1" />
<action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,3)" params="name=Character Creation Zorai.ogg|async=1" /> <action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,2)" params="name=character creation trykers.ogg|async=1" />
<action handler="play_music_outgame" cond="eq(@UI:TEMP:CHAR3D:PEOPLE,3)" params="name=character creation zorai.ogg|async=1" />
</proc> </proc>

@ -13,7 +13,7 @@
<param name="ctrl_sheet_gray_color" value="255 255 255 128" /> <param name="ctrl_sheet_gray_color" value="255 255 255 128" />
<param name="ctrl_sheet_redify_color" value="255 100 100 128" /> <param name="ctrl_sheet_redify_color" value="255 100 100 128" />
<param name="ctrl_text_redify_color" value="255 32 32 160" /> <param name="ctrl_text_redify_color" value="255 32 32 160" />
<param name="font" value="noto_sans_display.ttf" /> <param name="font" value="noto_sans.ttf" />
<param name="monospace_font" value="noto_mono.ttf" /> <param name="monospace_font" value="noto_mono.ttf" />
<param name="add_coef_font" value="0" /> <param name="add_coef_font" value="0" />
<param name="mul_coef_anim" value="1.0" /> <param name="mul_coef_anim" value="1.0" />

@ -611,7 +611,8 @@
<!-- Continue or Restart Default Outgame Music <!-- Continue or Restart Default Outgame Music
MUST PLAY IT NOT ASYNCLY, else it don't works well during loading MUST PLAY IT NOT ASYNCLY, else it don't works well during loading
--> -->
<action handler="play_music_outgame" params="async=0" /> <!-- Play character selection music -->
<!-- <action handler="play_music_outgame" params="async=0" /> -->
</proc> </proc>
<proc id="proc_location_finish2"> <proc id="proc_location_finish2">

@ -76,7 +76,8 @@
<!-- Continue or Restart Default Outgame Music <!-- Continue or Restart Default Outgame Music
MUST PLAY IT NOT ASYNCLY, else it don't works well during loading MUST PLAY IT NOT ASYNCLY, else it don't works well during loading
--> -->
<action handler="play_music_outgame" params="async=0" /> <!-- Play character selection music -->
<!-- <action handler="play_music_outgame" params="async=0" /> -->
</proc> </proc>
@ -187,6 +188,13 @@
<action handler="set" params="target_property=ui:outgame:charsel:3d_select:y | <action handler="set" params="target_property=ui:outgame:charsel:3d_select:y |
value=switch(@0, 0, -153, -306, -459, -612)" /> value=switch(@0, 0, -153, -306, -459, -612)" />
<!-- Play character selection music -->
<action handler="play_music_outgame" cond="and(eq(@UI:TEMP:CHAR3D:PEOPLE,0),not(isCharSelSlotEmpty(@0)))" params="name=character creation fyros.ogg|async=1" />
<action handler="play_music_outgame" cond="and(eq(@UI:TEMP:CHAR3D:PEOPLE,1),not(isCharSelSlotEmpty(@0)))" params="name=character creation matis.ogg|async=1" />
<action handler="play_music_outgame" cond="and(eq(@UI:TEMP:CHAR3D:PEOPLE,2),not(isCharSelSlotEmpty(@0)))" params="name=character creation trykers.ogg|async=1" />
<action handler="play_music_outgame" cond="and(eq(@UI:TEMP:CHAR3D:PEOPLE,3),not(isCharSelSlotEmpty(@0)))" params="name=character creation zorai.ogg|async=1" />
<action handler="play_music_outgame" cond="isCharSelSlotEmpty(@0)" params="async=1" />
<action handler="proc" params="proc_charsel_infos2" /> <action handler="proc" params="proc_charsel_infos2" />
</proc> </proc>

@ -13,7 +13,7 @@
<param name="ctrl_sheet_gray_color" value="255 255 255 128" /> <param name="ctrl_sheet_gray_color" value="255 255 255 128" />
<param name="ctrl_sheet_redify_color" value="255 100 100 128" /> <param name="ctrl_sheet_redify_color" value="255 100 100 128" />
<param name="ctrl_text_redify_color" value="255 32 32 160" /> <param name="ctrl_text_redify_color" value="255 32 32 160" />
<param name="font" value="noto_sans_display.ttf" /> <param name="font" value="noto_sans.ttf" />
<param name="monospace_font" value="noto_mono.ttf" /> <param name="monospace_font" value="noto_mono.ttf" />
<param name="add_coef_font" value="3" /> <param name="add_coef_font" value="3" />
<param name="mul_coef_anim" value="0.8" /> <param name="mul_coef_anim" value="0.8" />

@ -240,9 +240,9 @@ local scratchUCStr = ucstring()
--*********************************************************************** --***********************************************************************
function RingAccessPoint:newTemplate(name, cache) function RingAccessPoint:newTemplate(name, cache)
local group local group
if table.getn(cache) ~= 0 then if #cache ~= 0 then
group = cache[table.getn(cache)] group = cache[#cache]
table.remove(cache, table.getn(cache)) table.remove(cache, #cache)
else else
group = createGroupInstance(name, "", {}) group = createGroupInstance(name, "", {})
end end
@ -461,10 +461,10 @@ function RingAccessPoint:fill(list)
self:putInCache() self:putInCache()
-- --
-- ("***********************") -- ("***********************")
--debugInfo("TextCache size = " .. table.getn(self.TextCache)) --debugInfo("TextCache size = " .. #self.TextCache)
--debugInfo("CenteredTextCache size = " .. table.getn(self.CenteredTextCache)) --debugInfo("CenteredTextCache size = " .. #self.CenteredTextCache)
--debugInfo("NumberCache size = " .. table.getn(self.NumberCache)) --debugInfo("NumberCache size = " .. #self.NumberCache)
--debugInfo("BitmapCache size = " .. table.getn(self.BitmapCache)) --debugInfo("BitmapCache size = " .. #self.BitmapCache)
--self:clear() --self:clear()
self.CurrList = list self.CurrList = list
self.CurrActiveList = {} self.CurrActiveList = {}
@ -555,7 +555,7 @@ end
function RingAccessPoint:sort(list) function RingAccessPoint:sort(list)
local sortDir = self.SortDir local sortDir = self.SortDir
local function sorter(lhs, rhs) local function sorter(lhs, rhs)
for k = 1, table.getn(sortDir) do for k = 1, #sortDir do
if lhs[sortDir[k].Var] ~= rhs[sortDir[k].Var] then if lhs[sortDir[k].Var] ~= rhs[sortDir[k].Var] then
if sortDir[k].Up then if sortDir[k].Up then
return not sortDir[k].Cmp(lhs[sortDir[k].Var], rhs[sortDir[k].Var]) return not sortDir[k].Cmp(lhs[sortDir[k].Var], rhs[sortDir[k].Var])
@ -577,7 +577,7 @@ function RingAccessPoint:headerLeftClick(down, criterion)
parent.tup.active = not down parent.tup.active = not down
-- insert -- insert
local sortDir = self.SortDir local sortDir = self.SortDir
for k = 1, table.getn(sortDir) do for k = 1, #sortDir do
if sortDir[k].Var == criterion then if sortDir[k].Var == criterion then
sortDir[k].Up = not sortDir[k].Up sortDir[k].Up = not sortDir[k].Up
table.insert(sortDir, 1, sortDir[k]) table.insert(sortDir, 1, sortDir[k])

@ -1120,7 +1120,7 @@ void CCharacterCL::computeAnimSet()
// Use the generic method to compute the animation set. // Use the generic method to compute the animation set.
if(!::computeAnimSet(_CurrentAnimSet[MOVE], _Mode, _Sheet->getAnimSetBaseName(), _Items[SLOTTYPE::LEFT_HAND_SLOT].Sheet, _Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet, !modeWithHiddenItems())) if(!::computeAnimSet(_CurrentAnimSet[MOVE], _Mode, _Sheet->getAnimSetBaseName(), _Items[SLOTTYPE::LEFT_HAND_SLOT].Sheet, _Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet, !modeWithHiddenItems()))
{ {
//nlwarning("CH:computeAnimSet:%d: pb when trying to compute the animset. Sheet Id '%u(%s)'.", _Slot, _SheetId.asInt(), _SheetId.toString().c_str()); nlwarning("CH:computeAnimSet:%d: pb when trying to compute the animset. Sheet Id '%u(%s)'.", _Slot, _SheetId.asInt(), _SheetId.toString().c_str());
} }
}// computeAnimSet // }// computeAnimSet //
@ -3360,7 +3360,7 @@ void CCharacterCL::showOrHideBodyParts( bool objectsVisible )
lHandInstIdx = SLOTTYPE::LEFT_HAND_SLOT; lHandInstIdx = SLOTTYPE::LEFT_HAND_SLOT;
// hide gloves(armor) if player has magician amplifier // hide gloves(armor) if player has magician amplifier
if( _Items[rHandInstIdx].Sheet && (_Items[rHandInstIdx].Sheet->ItemType == ITEM_TYPE::MAGICIAN_STAFF) ) if( _Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet && (_Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet->ItemType == ITEM_TYPE::MAGICIAN_STAFF) )
{ {
if( !_Instances[SLOTTYPE::HANDS_SLOT].Current.empty() ) if( !_Instances[SLOTTYPE::HANDS_SLOT].Current.empty() )
_Instances[SLOTTYPE::HANDS_SLOT].Current.hide(); _Instances[SLOTTYPE::HANDS_SLOT].Current.hide();
@ -3378,8 +3378,9 @@ void CCharacterCL::showOrHideBodyParts( bool objectsVisible )
if( !objectsVisible ) if( !objectsVisible )
{ {
// Right Hand // Right Hand
nlassert(SLOTTYPE::RIGHT_HAND_SLOT < _Items.size() && SLOTTYPE::LEFT_HAND_SLOT < _Items.size());
if(rHandInstIdx<_Instances.size()) if(rHandInstIdx<_Instances.size())
if( !(_Items[rHandInstIdx].Sheet && _Items[rHandInstIdx].Sheet->NeverHideWhenEquipped ) ) if( !(_Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet && _Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet->NeverHideWhenEquipped ) )
if(!_Instances[rHandInstIdx].Current.empty()) if(!_Instances[rHandInstIdx].Current.empty())
{ {
_Instances[rHandInstIdx].Current.hide(); _Instances[rHandInstIdx].Current.hide();
@ -3387,7 +3388,7 @@ void CCharacterCL::showOrHideBodyParts( bool objectsVisible )
} }
// Left Hand // Left Hand
if(lHandInstIdx <_Instances.size()) if(lHandInstIdx <_Instances.size())
if( !(_Items[lHandInstIdx].Sheet && _Items[lHandInstIdx].Sheet->NeverHideWhenEquipped ) ) if( !(_Items[SLOTTYPE::LEFT_HAND_SLOT].Sheet && _Items[SLOTTYPE::LEFT_HAND_SLOT].Sheet->NeverHideWhenEquipped ) )
if(!_Instances[lHandInstIdx].Current.empty()) if(!_Instances[lHandInstIdx].Current.empty())
{ {
_Instances[lHandInstIdx].Current.hide(); _Instances[lHandInstIdx].Current.hide();
@ -9250,14 +9251,14 @@ const char *CCharacterCL::getBoneNameFromBodyPart(BODY::TBodyPart part, BODY::TS
const CItemSheet *CCharacterCL::getRightHandItemSheet() const const CItemSheet *CCharacterCL::getRightHandItemSheet() const
{ {
if (_RHandInstIdx == CEntityCL::BadIndex) return NULL; if (_RHandInstIdx == CEntityCL::BadIndex) return NULL;
return _Items[_RHandInstIdx].Sheet; return _Items[SLOTTYPE::RIGHT_HAND_SLOT].Sheet;
} }
// ********************************************************************************************* // *********************************************************************************************
const CItemSheet *CCharacterCL::getLeftHandItemSheet() const const CItemSheet *CCharacterCL::getLeftHandItemSheet() const
{ {
if (_LHandInstIdx == CEntityCL::BadIndex) return NULL; if (_LHandInstIdx == CEntityCL::BadIndex) return NULL;
return _Items[_LHandInstIdx].Sheet; return _Items[SLOTTYPE::LEFT_HAND_SLOT].Sheet;
} }
// *************************************************************************** // ***************************************************************************

@ -458,7 +458,13 @@ CClientConfig::CClientConfig()
SoundOn = true; // Default is with sound. SoundOn = true; // Default is with sound.
DriverSound = SoundDrvAuto; DriverSound = SoundDrvAuto;
SoundForceSoftwareBuffer = true; SoundForceSoftwareBuffer = true;
SoundOutGameMusic = "main menu loop.ogg"; StartMusic = "main theme air.ogg"; // Use at game startup (originally no music)
EmptySlotMusic = "loading music loop.ogg"; // Use in character selection for empty slots
LoadingMusic = "main menu loop.ogg"; // Main loading used after leaving character selection, and when going back to character selection
KamiTeleportMusic = "kami teleport.ogg"; // Kami teleport
KaravanTeleportMusic = "karavan teleport.ogg"; // Karavan teleport
TeleportLoadingMusic = "loading music loop.ogg"; // Use for generic teleportations
DeathMusic = "death.ogg"; // Player death
SoundSFXVolume = 1.f; SoundSFXVolume = 1.f;
SoundGameMusicVolume = 1.f; SoundGameMusicVolume = 1.f;
SoundTPFade = 500; SoundTPFade = 500;
@ -469,7 +475,7 @@ CClientConfig::CClientConfig()
UserEntitySoundLevel = 0.5f; // Default volume for sound in 1st person UserEntitySoundLevel = 0.5f; // Default volume for sound in 1st person
UseEax = true; // Default to use EAX; UseEax = true; // Default to use EAX;
UseADPCM = false; // Defualt to PCM sample, NO ADPCM UseADPCM = false; // Defualt to PCM sample, NO ADPCM
MaxTrack = 32; // DEfault to 32 track MaxTrack = 32; // Default to 32 track
ColorShout = CRGBA(150,0,0,255); // Default Shout color. ColorShout = CRGBA(150,0,0,255); // Default Shout color.
ColorTalk = CRGBA(255,255,255,255); // Default Talk color. ColorTalk = CRGBA(255,255,255,255); // Default Talk color.
@ -1242,7 +1248,13 @@ void CClientConfig::setValues()
// SoundForceSoftwareBuffer // SoundForceSoftwareBuffer
READ_BOOL_FV(SoundForceSoftwareBuffer); READ_BOOL_FV(SoundForceSoftwareBuffer);
// SoundOutGameMusic // SoundOutGameMusic
READ_STRING_DEV(SoundOutGameMusic) READ_STRING_DEV(StartMusic)
READ_STRING_DEV(EmptySlotMusic)
READ_STRING_DEV(LoadingMusic)
READ_STRING_DEV(KamiTeleportMusic)
READ_STRING_DEV(KaravanTeleportMusic)
READ_STRING_DEV(TeleportLoadingMusic)
READ_STRING_DEV(DeathMusic)
// SoundSFXVolume // SoundSFXVolume
READ_FLOAT_FV(SoundSFXVolume); READ_FLOAT_FV(SoundSFXVolume);
// SoundGameMusicVolume // SoundGameMusicVolume

@ -350,8 +350,14 @@ struct CClientConfig
/// SoundForceSoftwareBuffer /// SoundForceSoftwareBuffer
bool SoundForceSoftwareBuffer; bool SoundForceSoftwareBuffer;
/// The outgame music file /// Music files
string SoundOutGameMusic; string StartMusic;
string EmptySlotMusic;
string LoadingMusic;
string KamiTeleportMusic;
string KaravanTeleportMusic;
string TeleportLoadingMusic;
string DeathMusic;
/// The Sound SFX Volume (0-1) (ie all but music) /// The Sound SFX Volume (0-1) (ie all but music)
float SoundSFXVolume; float SoundSFXVolume;

@ -213,6 +213,21 @@ void CCharacterSheet::build(const NLGEORGES::UFormElm &item)
// IN LEFT HAND // IN LEFT HAND
readEquipment(item, "Basics.Equipment.HandL", ObjectInLeftHand); readEquipment(item, "Basics.Equipment.HandL", ObjectInLeftHand);
if (!ObjectInRightHand.IdItem)
{
std::string right;
item.getValueByName(right, "item_right");
if (!right.empty())
ObjectInRightHand.IdItem = ClientSheetsStrings.add(NLMISC::toLower(right));
}
if (!ObjectInLeftHand.IdItem)
{
std::string left;
item.getValueByName(left, "item_left");
if (!left.empty())
ObjectInLeftHand.IdItem = ClientSheetsStrings.add(NLMISC::toLower(left));
}
// Get the animation set Base Name. // Get the animation set Base Name.
string AnimSetBaseName; string AnimSetBaseName;

@ -273,6 +273,73 @@ void setOutGameFullScreen()
CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768); CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768);
} }
// ------------------------------------------------------------------------------------------------
class CSoundGlobalMenu
{
public:
CSoundGlobalMenu()
{
_MusicWantedAsync= false;
_NbFrameBeforeChange= NbFrameBeforeChangeMax;
}
void reset();
void setMusic(const string &music, bool async);
void updateSound();
private:
string _MusicPlayed;
string _MusicWanted;
bool _MusicWantedAsync;
sint _NbFrameBeforeChange;
enum {NbFrameBeforeChangeMax= 10};
};
void CSoundGlobalMenu::reset()
{
_MusicPlayed.clear();
_MusicWanted.clear();
}
void CSoundGlobalMenu::updateSound()
{
// **** update the music played
// The first music played is the music played at loading, before select char
if (_MusicPlayed.empty())
_MusicPlayed = toLower(LoadingMusic.empty() ? ClientCfg.StartMusic : LoadingMusic);
if (_MusicWanted.empty())
_MusicWanted = toLower(LoadingMusic.empty() ? ClientCfg.StartMusic : LoadingMusic);
// because music is changed when the player select other race for instance,
// wait the 3D to load (stall some secs)
// if the wanted music is the same as the one currently playing, just continue playing
if(_MusicPlayed!=_MusicWanted)
{
// wait nbFrameBeforeChangeMax before actually changing the music
_NbFrameBeforeChange--;
if(_NbFrameBeforeChange<=0)
{
_MusicPlayed= _MusicWanted;
// play the music
if (SoundMngr != NULL)
SoundMngr->playMusic(_MusicPlayed, 500, _MusicWantedAsync, true, true);
}
}
// **** update mngr
if (SoundMngr != NULL)
SoundMngr->update();
}
void CSoundGlobalMenu::setMusic(const string &music, bool async)
{
_MusicWanted= toLower(music);
_MusicWantedAsync= async;
// reset the counter
_NbFrameBeforeChange= NbFrameBeforeChangeMax;
}
static CSoundGlobalMenu SoundGlobalMenu;
// New version of the menu after the server connection // New version of the menu after the server connection
// //
@ -405,6 +472,8 @@ bool connection (const string &cookie, const string &fsaddr)
InterfaceState = GLOBAL_MENU; InterfaceState = GLOBAL_MENU;
} }
// No loading music here, this is right before character selection, using the existing music
// Create the loading texture. We can't do that before because we need to add search path first. // Create the loading texture. We can't do that before because we need to add search path first.
beginLoading (LoadBackground); beginLoading (LoadBackground);
UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING; UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING;
@ -443,7 +512,7 @@ bool connection (const string &cookie, const string &fsaddr)
Actions.enable(false); Actions.enable(false);
EditActions.enable(false); EditActions.enable(false);
resetTextContext("noto_sans_display.ttf", true); resetTextContext("noto_sans.ttf", true);
if (InterfaceState == GOGOGO_IN_THE_GAME) if (InterfaceState == GOGOGO_IN_THE_GAME)
{ {
@ -506,6 +575,7 @@ bool reconnection()
ProgressBar.setFontFactor(1.0f); ProgressBar.setFontFactor(1.0f);
// Init out game // Init out game
SoundGlobalMenu.reset();
pIM->initOutGame(); pIM->initOutGame();
// Hide cursor for interface // Hide cursor for interface
@ -521,6 +591,9 @@ bool reconnection()
FarTP.setOutgame(); FarTP.setOutgame();
if (SoundMngr)
SoundMngr->setupFadeSound(1.0f, 1.0f);
// these two globals sequence GlobalMenu to display the character select dialog // these two globals sequence GlobalMenu to display the character select dialog
WaitServerAnswer = true; WaitServerAnswer = true;
userChar = true; userChar = true;
@ -555,6 +628,8 @@ bool reconnection()
// this also kicks the state machine to sendReady() so we stop spinning in farTPmainLoop // this also kicks the state machine to sendReady() so we stop spinning in farTPmainLoop
FarTP.setIngame(); FarTP.setIngame();
// Not loading music here, this is before character selection, keep existing music
// Create the loading texture. We can't do that before because we need to add search path first. // Create the loading texture. We can't do that before because we need to add search path first.
beginLoading (LoadBackground); beginLoading (LoadBackground);
UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING; UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING;
@ -576,7 +651,7 @@ bool reconnection()
Actions.enable(false); Actions.enable(false);
EditActions.enable(false); EditActions.enable(false);
resetTextContext("noto_sans_display.ttf", true); resetTextContext("noto_sans.ttf", true);
if (InterfaceState == GOGOGO_IN_THE_GAME) if (InterfaceState == GOGOGO_IN_THE_GAME)
{ {
@ -729,66 +804,6 @@ std::string buildPlayerNameForSaveFile(const ucstring &playerNameIn)
return ret; return ret;
} }
// ------------------------------------------------------------------------------------------------
class CSoundGlobalMenu
{
public:
CSoundGlobalMenu()
{
_MusicWantedAsync= false;
_NbFrameBeforeChange= NbFrameBeforeChangeMax;
}
void setMusic(const string &music, bool async);
void updateSound();
private:
string _MusicPlayed;
string _MusicWanted;
bool _MusicWantedAsync;
sint _NbFrameBeforeChange;
enum {NbFrameBeforeChangeMax= 10};
};
void CSoundGlobalMenu::updateSound()
{
// **** update the music played
// The first music played is the music played at loading, before select char
if(_MusicPlayed.empty())
_MusicPlayed= toLower(ClientCfg.SoundOutGameMusic);
if(_MusicWanted.empty())
_MusicWanted= toLower(ClientCfg.SoundOutGameMusic);
// because music is changed when the player select other race for instance,
// wait the 3D to load (stall some secs)
// if the wanted music is the same as the one currently playing, just continue playing
if(_MusicPlayed!=_MusicWanted)
{
// wait nbFrameBeforeChangeMax before actually changing the music
_NbFrameBeforeChange--;
if(_NbFrameBeforeChange<=0)
{
_MusicPlayed= _MusicWanted;
// play the music
if (SoundMngr != NULL)
SoundMngr->playMusic(_MusicPlayed, 500, _MusicWantedAsync, true, true);
}
}
// **** update mngr
if (SoundMngr != NULL)
SoundMngr->update();
}
void CSoundGlobalMenu::setMusic(const string &music, bool async)
{
_MusicWanted= toLower(music);
_MusicWantedAsync= async;
// reset the counter
_NbFrameBeforeChange= NbFrameBeforeChangeMax;
}
static CSoundGlobalMenu SoundGlobalMenu;
static bool LuaBGDSuccessFlag = true; // tmp, for debug static bool LuaBGDSuccessFlag = true; // tmp, for debug
@ -2039,8 +2054,8 @@ public:
fromString(getParam(Params, "async"), async); fromString(getParam(Params, "async"), async);
// if empty name, return to default mode // if empty name, return to default mode
if(sName.empty()) if (sName.empty())
sName= ClientCfg.SoundOutGameMusic; sName = ClientCfg.EmptySlotMusic;
// change the music // change the music
SoundGlobalMenu.setMusic(sName, async); SoundGlobalMenu.setMusic(sName, async);

@ -162,7 +162,9 @@ CDecal::CDecal()
{ {
DecalAttenuationVertexProgram = new CVertexProgramDecalAttenuation(); DecalAttenuationVertexProgram = new CVertexProgramDecalAttenuation();
} }
_ShadowMap = new CShadowMap(&(((CSceneUser *) Scene)->getScene().getRenderTrav().getShadowMapManager()));
// initialized in render() as depends on scene
_ShadowMap = NULL;
_Material.initUnlit(); _Material.initUnlit();
_Diffuse = CRGBA::White; _Diffuse = CRGBA::White;
_Emissive = CRGBA::Black; _Emissive = CRGBA::Black;
@ -251,7 +253,11 @@ CRGBA CDecal::getDiffuse() const
// **************************************************************************** // ****************************************************************************
CDecal::~CDecal() CDecal::~CDecal()
{ {
delete _ShadowMap; if (_ShadowMap)
{
delete _ShadowMap;
_ShadowMap = NULL;
}
} }
// **************************************************************************** // ****************************************************************************
@ -527,7 +533,12 @@ void CDecal::render(NL3D::UDriver &/* drv */,
// //
float tileNear = Landscape->getTileNear(); float tileNear = Landscape->getTileNear();
// //
nlassert(_ShadowMap); if (!_ShadowMap)
{
_ShadowMap = new CShadowMap(&(((CSceneUser *) Scene)->getScene().getRenderTrav().getShadowMapManager()));
nlassert(_ShadowMap);
}
_ShadowMap->LocalClipPlanes.resize(4); _ShadowMap->LocalClipPlanes.resize(4);
CVector corners[4] = CVector corners[4] =
{ {

@ -378,6 +378,8 @@ void CEntityCL::SInstanceCL::updateCurrentFromLoading(NL3D::USkeleton Skeleton)
sint stickID = Skeleton.getBoneIdByName(StickPoint); sint stickID = Skeleton.getBoneIdByName(StickPoint);
if(stickID != -1) if(stickID != -1)
Skeleton.stickObject(Current, stickID); Skeleton.stickObject(Current, stickID);
else
nlwarning("Skeleton '%s' is missing bone '%s' for object attachment.", Skeleton.getShapeName().c_str(), StickPoint.c_str());
} }
} }

@ -1112,15 +1112,6 @@ void CFarTP::disconnectFromPreviousShard()
beginLoading (StartBackground); beginLoading (StartBackground);
UseEscapeDuringLoading = false; UseEscapeDuringLoading = false;
// Play music and fade out the Game Sound
if (SoundMngr)
{
// Loading Music Loop.ogg
LoadingMusic = ClientCfg.SoundOutGameMusic;
SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true);
SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
}
// Change the tips // Change the tips
selectTipsOfTheDay (rand()); selectTipsOfTheDay (rand());
@ -1129,6 +1120,21 @@ void CFarTP::disconnectFromPreviousShard()
ucstring nmsg("Loading..."); ucstring nmsg("Loading...");
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
ProgressBar.progress(0); ProgressBar.progress(0);
// Play music and fade out the Game Sound
if (SoundMngr)
{
SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
// Stop and enable music
SoundMngr->stopMusic(0);
SoundMngr->setupFadeSound(0.0f, 1.0f);
// Loading Music Loop.ogg
LoadingMusic = ClientCfg.LoadingMusic;
// SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true);
SoundMngr->playMusic(LoadingMusic, 0, false, true, true);
}
} }
// Disconnect from the FS // Disconnect from the FS

@ -1342,7 +1342,7 @@ void prelogInit()
// Create a text context. We need to put the full path because we not already add search path // Create a text context. We need to put the full path because we not already add search path
resetTextContext("noto_sans_display.ttf", true); resetTextContext("noto_sans.ttf", true);
CInterfaceManager::getInstance(); CInterfaceManager::getInstance();
@ -1411,6 +1411,42 @@ void prelogInit()
StereoDisplay->setDriver(Driver); // VR_DRIVER StereoDisplay->setDriver(Driver); // VR_DRIVER
} }
{
H_AUTO(InitRZSound)
// Init the sound manager
nmsg = "Initializing sound manager...";
ProgressBar.newMessage(ClientCfg.buildLoadingString(nmsg));
if (ClientCfg.SoundOn)
{
nlassert(!SoundMngr);
SoundMngr = new CSoundManager(&ProgressBar);
try
{
SoundMngr->init(&ProgressBar);
}
catch(const Exception &e)
{
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
delete SoundMngr;
SoundMngr = NULL;
}
// Play Music just after the SoundMngr is inited
if (SoundMngr)
{
// init the SoundMngr with backuped volume
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
// Play the login screen music
SoundMngr->playMusic(ClientCfg.StartMusic, 0, true, true, true);
}
}
CPath::memoryCompress(); // Because sound calls addSearchPath
}
nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);
FPU_CHECKER_ONCE FPU_CHECKER_ONCE
@ -1553,55 +1589,6 @@ void postlogInit()
// set the primitive context // set the primitive context
CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
{
H_AUTO(InitRZSound)
// Init the sound manager
nmsg = "Initializing sound manager...";
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
if(ClientCfg.SoundOn)
{
SoundMngr = new CSoundManager(&ProgressBar);
try
{
SoundMngr->init(&ProgressBar);
}
catch(const Exception &e)
{
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
delete SoundMngr;
SoundMngr = NULL;
}
// Play Music just after the SoundMngr is inited
if(SoundMngr)
{
// init the SoundMngr with backuped volume
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
// no fadein, and not async because don't work well because of loading in the main thread
// Force use GameMusic volume
const uint fadeInTime= 500;
SoundMngr->playMusic(ClientCfg.SoundOutGameMusic, fadeInTime, false, true, true);
// Because of blocking loading, force the fadeIn
TTime t0= ryzomGetLocalTime();
TTime t1;
while((t1=ryzomGetLocalTime())<t0+fadeInTime)
{
//ProgressBar.progress(1.f);
SoundMngr->updateAudioMixerOnly();
}
}
}
CPath::memoryCompress(); // Because sound call addSearchPath
initLast = initCurrent;
initCurrent = ryzomGetLocalTime();
//nlinfo ("PROFILE: %d seconds (%d total) for Initializing sound manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
}
{ {
H_AUTO(InitRZShIdI) H_AUTO(InitRZShIdI)

@ -485,6 +485,27 @@ void initMainLoop()
FPU_CHECKER_ONCE FPU_CHECKER_ONCE
if (SoundMngr)
{
// Loading Music
LoadingMusic = ClientCfg.LoadingMusic;
// SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true);
// no fadein, and not async because don't work well because of loading in the main thread
// Force use GameMusic volume
const uint fadeInTime = 500;
SoundMngr->playMusic(LoadingMusic, fadeInTime, false, true, true);
// Because of blocking loading, force the fadeIn
TTime t0 = ryzomGetLocalTime();
TTime t1;
do
{
ProgressBar.progress(0);
SoundMngr->updateAudioMixerOnly();
nlSleep(10);
} while ((t1 = ryzomGetLocalTime()) < t0 + fadeInTime);
}
// Get the interface manager // Get the interface manager
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();

@ -2819,24 +2819,6 @@ public:
virtual void execute (CCtrlBase * /* pCaller */, const string &Params) virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
{ {
/* // Previous version (multiple pressed on a desktop change a central window
uint desktop;
fromString(Params, desktop);
if (desktop <MAX_NUM_MODES)
{
CInterfaceManager *pIM= CInterfaceManager::getInstance();
const string procNames[MAX_NUM_MODES] = { "tb_setexp", "tb_setinfo", "tb_setlab", "tb_setkeys" };
const string dbNames[MAX_NUM_MODES] = { "", "UI:SAVE:CURRENT_INFO_MODE", "UI:SAVE:CURRENT_LAB_MODE", "UI:SAVE:CURRENT_KEY_MODE" };
string sValue;
CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(dbNames[desktop], false);
if (pNL != NULL)
sValue = NLMISC::toString((sint32)pNL->getValue64());
vector<string> vecStr;
vecStr.push_back(procNames[desktop]);
vecStr.push_back(sValue);
CWidgetManager::getInstance()->runProcedure(procNames[desktop], NULL, vecStr);
}*/
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:gestion_windows")); CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:gestion_windows"));
if (pGC == NULL) if (pGC == NULL)
@ -2847,11 +2829,14 @@ public:
CInterfaceElement *pIE = CWidgetManager::getInstance()->getElementFromId("ui:interface:gestion_windows:close"); CInterfaceElement *pIE = CWidgetManager::getInstance()->getElementFromId("ui:interface:gestion_windows:close");
if (pIE != NULL) pIE->setActive(false); if (pIE != NULL) pIE->setActive(false);
bool switchDesktop = false;
CActionsManager *pAM = &Actions; CActionsManager *pAM = &Actions;
if (!pAM->valide(CAction::CName("set_desktop",Params.c_str()))) if (!pAM->valide(CAction::CName("set_desktop",Params.c_str())))
{ {
pGC->setActive(false); pGC->setActive(false);
_FirstTime = true; _FirstTime = true;
switchDesktop = true;
} }
else // Key is down else // Key is down
{ {
@ -2859,11 +2844,7 @@ public:
if (_FirstTime) if (_FirstTime)
{ {
_FirstTime = false; _FirstTime = false;
switchDesktop = true;
vector<string> vecStr;
vecStr.push_back("tb_setdesktop");
vecStr.push_back(Params);
CWidgetManager::getInstance()->runProcedure("tb_setdesktop", NULL, vecStr);
} }
else // Not the first time else // Not the first time
{ {
@ -2873,6 +2854,13 @@ public:
CWidgetManager::getInstance()->setTopWindow(pGC); CWidgetManager::getInstance()->setTopWindow(pGC);
} }
} }
if (switchDesktop)
{
vector<string> vecStr;
vecStr.push_back("tb_setdesktop");
vecStr.push_back(Params);
CWidgetManager::getInstance()->runProcedure("tb_setdesktop", NULL, vecStr);
}
} }
private: private:
bool _FirstTime; bool _FirstTime;

@ -540,6 +540,9 @@ CCtrlDraggable(param)
_SapBuffIcon = "ico_sap.tga"; _SapBuffIcon = "ico_sap.tga";
_StaBuffIcon = "ico_stamina.tga"; _StaBuffIcon = "ico_stamina.tga";
_FocusBuffIcon = "ico_focus.tga"; _FocusBuffIcon = "ico_focus.tga";
_RegenText = NULL;
_RegenTextValue = 0;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -564,6 +567,11 @@ CDBCtrlSheet::~CDBCtrlSheet()
Driver->deleteTextureFile(_GuildSymb); Driver->deleteTextureFile(_GuildSymb);
_GuildSymb = NULL; _GuildSymb = NULL;
} }
if (_RegenText)
{
delete _RegenText;
_RegenText = NULL;
}
// ensure erase static // ensure erase static
if(this==_CurrMenuSheet) _CurrMenuSheet = NULL; if(this==_CurrMenuSheet) _CurrMenuSheet = NULL;
@ -2039,6 +2047,12 @@ void CDBCtrlSheet::draw()
if (!_LastSheetId) if (!_LastSheetId)
{ {
_RegenTickRange = CTickRange(); _RegenTickRange = CTickRange();
if (_RegenText)
{
delete _RegenText;
_RegenText = NULL;
_RegenTextValue = 0;
}
} }
else else
{ {
@ -2065,6 +2079,36 @@ void CDBCtrlSheet::draw()
{ {
rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false); rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false);
} }
if (!_RegenText) {
_RegenText = new CViewText(CViewBase::TCtorParam());
_RegenText->setId(getId() + ":regen");
_RegenText->setParent(_Parent);
_RegenText->setOverflowText(ucstring(""));
_RegenText->setModulateGlobalColor(false);
_RegenText->setMultiLine(false);
_RegenText->setTextMode(CViewText::ClipWord);
_RegenText->setFontSizing("0", "0");
// TODO: font size / color hardcoded.
_RegenText->setFontSize(8);
_RegenText->setColor(CRGBA::White);
_RegenText->setShadow(true);
_RegenText->setActive(true);
_RegenText->updateTextContext();
}
// TODO: ticks in second hardcoded
uint32 nextValue = _RegenTickRange.EndTick > LastGameCycle ? (_RegenTickRange.EndTick - LastGameCycle) / 10 : 0;
if (_RegenTextValue != nextValue)
{
_RegenTextValue = nextValue;
_RegenText->setText(toString("%d", _RegenTextValue));
_RegenText->updateTextContext();
}
_RegenText->setXReal(_XReal+1);
_RegenText->setYReal(_YReal+2);
_RegenText->setRenderLayer(_RenderLayer+2);
_RegenText->draw();
} }
} }

@ -56,6 +56,7 @@ class COutpostBuildingSheet;
namespace NLGUI namespace NLGUI
{ {
class CViewRenderer; class CViewRenderer;
class CViewText;
} }
class CDBCtrlSheet; class CDBCtrlSheet;
@ -736,6 +737,8 @@ protected:
sint8 _ArmourColorIndex; sint8 _ArmourColorIndex;
CTickRange _RegenTickRange; CTickRange _RegenTickRange;
NLGUI::CViewText *_RegenText;
uint32 _RegenTextValue;
/// D'n'd /// D'n'd
sint32 _DragX, _DragY; sint32 _DragX, _DragY;

@ -1293,15 +1293,18 @@ void CGroupMap::checkCoords()
{ {
if( _AnimalLM[i] ) if( _AnimalLM[i] )
{ {
// update pos
sint32 px, py;
_AnimalPosStates[i]->getPos(px, py);
updateLMPosFromDBPos(_AnimalLM[i], px, py);
if (_IsIsland) if (_IsIsland)
{ {
_AnimalLM[i]->setActive(false); _AnimalLM[i]->setActive(false);
} }
else else if (_AnimalLM[i]->getActive())
{ {
_AnimalLM[i]->setActive(true);
// update texture from animal status // update texture from animal status
CInterfaceManager *pIM= CInterfaceManager::getInstance();
CCDBNodeLeaf *statusNode = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d", i) + ":STATUS", false); CCDBNodeLeaf *statusNode = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d", i) + ":STATUS", false);
if (statusNode && ANIMAL_STATUS::isInStable((ANIMAL_STATUS::EAnimalStatus)statusNode->getValue32()) ) if (statusNode && ANIMAL_STATUS::isInStable((ANIMAL_STATUS::EAnimalStatus)statusNode->getValue32()) )
{ {
@ -1332,11 +1335,6 @@ void CGroupMap::checkCoords()
case ANIMAL_TYPE::Demon: sPrefix = "uiPATitleDemon"; break; case ANIMAL_TYPE::Demon: sPrefix = "uiPATitleDemon"; break;
} }
_AnimalLM[i]->setDefaultContextHelp(NLMISC::CI18N::get(sPrefix+toString(i+1))); _AnimalLM[i]->setDefaultContextHelp(NLMISC::CI18N::get(sPrefix+toString(i+1)));
// update pos
sint32 px, py;
_AnimalPosStates[i]->getPos(px, py);
updateLMPosFromDBPos(_AnimalLM[i], px, py);
} }
} }
} }
@ -2420,7 +2418,8 @@ void CGroupMap::updateMatchedLandmarks()
std::vector<std::pair<string,string> > params; std::vector<std::pair<string,string> > params;
params.clear(); params.clear();
params.push_back(std::pair<string,string>("id", toString("lm%d", k))); params.push_back(std::pair<string,string>("id", toString("lm%d", k)));
params.push_back(std::pair<string,string>("tooltip", _MatchedLandmarks[k].Title.toUtf8())); // ctrl base expects utf8 string to start with "u:"
params.push_back(std::pair<string,string>("tooltip", "u:" + _MatchedLandmarks[k].Title.toUtf8()));
params.push_back(std::pair<string,string>("index", toString(k))); params.push_back(std::pair<string,string>("index", toString(k)));
CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params); CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params);
@ -2613,7 +2612,7 @@ void CGroupMap::setLandmarkFilter(const std::string &s)
if (!s.empty()) { if (!s.empty()) {
ucstring ucs; ucstring ucs;
ucs.fromUtf8(s); ucs.fromUtf8(s);
splitUCString(toLower(s), ucstring(" "), _LandmarkFilter); splitUCString(toLower(ucs), ucstring(" "), _LandmarkFilter);
} }
// recreate landmarks // recreate landmarks

@ -271,16 +271,16 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
{ {
CViewPointer &rIP = *static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() ); CViewPointer &rIP = *static_cast<CViewPointer *>(CWidgetManager::getInstance()->getPointer());
NLGUI::CEventDescriptorMouse eventDesc; NLGUI::CEventDescriptorMouse eventDesc;
sint32 x,y; sint32 x, y;
rIP.getPointerDispPos (x, y); rIP.getPointerDispPos(x, y);
eventDesc.setX (x); eventDesc.setX(x);
eventDesc.setY (y); eventDesc.setY(y);
bool handled= false; bool handled = false;
// button down ? // button down ?
static volatile bool doTest = false; static volatile bool doTest = false;
@ -291,7 +291,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
{ {
if (_RecoverFocusLost) if (_RecoverFocusLost)
{ {
handled |= updateMousePos((CEventMouse&)event, eventDesc); // must update mouse pos here, handled |= updateMousePos((CEventMouse&)event); // must update mouse pos here,
// because when app window focus is gained by a mouse click, this is // because when app window focus is gained by a mouse click, this is
// the only place where we can retrieve mouse pos before a mouse move // the only place where we can retrieve mouse pos before a mouse move
_RecoverFocusLost = false; _RecoverFocusLost = false;
@ -299,10 +299,19 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
if (!handled) if (!handled)
{ {
if (R2::getEditor().isInitialized() if (R2::getEditor().isInitialized()
&& (R2::isEditionCurrent() || R2::getEditor().getCurrentTool()) && (R2::isEditionCurrent() || R2::getEditor().getCurrentTool()))
)
{ {
handled |= R2::getEditor().handleEvent(eventDesc); const NLMISC::CEventMouseDown *mouseDownEvent = static_cast<const NLMISC::CEventMouseDown *>(&event);
if (mouseDownEvent->Button & NLMISC::leftButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouseleftdown);
handled |= R2::getEditor().handleEvent(eventDesc);
}
if (mouseDownEvent->Button & NLMISC::rightButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouserightdown);
handled |= R2::getEditor().handleEvent(eventDesc);
}
} }
} }
handled |= inputHandler.handleMouseButtonDownEvent( event ); handled |= inputHandler.handleMouseButtonDownEvent( event );
@ -321,7 +330,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
// mouse move? // mouse move?
else if(event == EventMouseMoveId) else if(event == EventMouseMoveId)
{ {
handled |= updateMousePos((CEventMouse&)event, eventDesc); handled |= updateMousePos((CEventMouse&)event);
} }
else if (event == EventMouseWheelId) else if (event == EventMouseWheelId)
{ {
@ -330,19 +339,77 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
} }
// if Event not handled, post to Action Manager // if Event not handled, post to Action Manager
if( !handled ) if (!handled)
{ {
bool handled = false;
if (R2::getEditor().isInitialized() if (R2::getEditor().isInitialized()
&& (R2::isEditionCurrent() || R2::getEditor().getCurrentTool()) && (R2::isEditionCurrent() || R2::getEditor().getCurrentTool()))
)
{ {
handled = R2::getEditor().handleEvent(eventDesc); if (event == EventMouseDownId)
{
const NLMISC::CEventMouseDown *mouseDownEvent = static_cast<const NLMISC::CEventMouseDown *>(&event);
if (mouseDownEvent->Button & NLMISC::leftButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouseleftdown);
handled |= R2::getEditor().handleEvent(eventDesc);
}
if (mouseDownEvent->Button & NLMISC::rightButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouserightdown);
handled |= R2::getEditor().handleEvent(eventDesc);
}
}
else if (event == EventMouseUpId)
{
const NLMISC::CEventMouseUp *mouseUpEvent = static_cast<const NLMISC::CEventMouseUp *>(&event);
if (mouseUpEvent->Button & NLMISC::leftButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouseleftup);
handled |= R2::getEditor().handleEvent(eventDesc);
}
if (mouseUpEvent->Button & NLMISC::rightButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouserightup);
handled |= R2::getEditor().handleEvent(eventDesc);
}
}
else if (event == EventMouseDblClkId)
{
const NLMISC::CEventMouseDblClk *mouseDblClkEvent = static_cast<const NLMISC::CEventMouseDblClk *>(&event);
if (mouseDblClkEvent->Button & NLMISC::leftButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouseleftdblclk);
handled |= R2::getEditor().handleEvent(eventDesc);
}
if (mouseDblClkEvent->Button & NLMISC::rightButton)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mouserightdblclk);
handled |= R2::getEditor().handleEvent(eventDesc);
}
}
else
{
if (event == EventMouseWheelId)
{
const NLMISC::CEventMouseWheel *wheelEvent = static_cast<const NLMISC::CEventMouseWheel *>(&event);
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mousewheel);
eventDesc.setWheel(wheelEvent->Direction ? 1 : -1);
handled = R2::getEditor().handleEvent(eventDesc);
}
else if (event == EventMouseMoveId)
{
eventDesc.setEventTypeExtended(CEventDescriptorMouse::mousemove);
handled = R2::getEditor().handleEvent(eventDesc);
}
else
{
nlwarning("R2 unknown mouse event '%s'", event.toString().c_str());
}
}
} }
if (!handled) if (!handled)
{ {
// post to Action Manager // post to Action Manager
FilteredEventServer.postEvent( event.clone() ); FilteredEventServer.postEvent(event.clone());
} }
} }
} }
@ -355,7 +422,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
// *************************************************************************** // ***************************************************************************
bool CInputHandlerManager::updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc) bool CInputHandlerManager::updateMousePos(NLMISC::CEventMouse &event)
{ {
if (!IsMouseFreeLook()) if (!IsMouseFreeLook())
return inputHandler.handleMouseMoveEvent( event ); return inputHandler.handleMouseMoveEvent( event );

@ -181,7 +181,7 @@ private:
void parseKey(xmlNodePtr cur, std::vector<CComboKey> &out); void parseKey(xmlNodePtr cur, std::vector<CComboKey> &out);
// return true if handled // return true if handled
bool updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc); bool updateMousePos(NLMISC::CEventMouse &event);
NLGUI::CInputHandler inputHandler; NLGUI::CInputHandler inputHandler;

@ -1046,6 +1046,10 @@ void CInterfaceManager::initInGame()
gc->setTarget(gc->getSavedTarget()); gc->setTarget(gc->getSavedTarget());
} }
// rebuild mp3 player playlist if user reselected a char (songs are already scanned)
CAHManager::getInstance()->runActionHandler("music_player", NULL, "update_playlist");
CAHManager::getInstance()->runActionHandler("music_player", NULL, "stop");
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHATLOG_STATE", false); CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHATLOG_STATE", false);
if (node) if (node)
{ {

@ -3582,15 +3582,23 @@ void CInventoryManager::onTradeChangeSession()
// *************************************************************************** // ***************************************************************************
void CInventoryManager::updateItemInfoQueue() void CInventoryManager::updateItemInfoQueue()
{ {
if (!ConnectionReadySent) // CONNECTION:READY not yet sent, so we cannot send requests yet!
{
// Caused by CNetworkConnection::reinit, and NLMISC::CCDBNodeBranch::resetData
// TODO: Item sheets are effectively being set to 0, any way to detect this in particular?
// Slots with sheet 0 won't have any info to request anyway!
// Remove this check in favour of the assert lower down when properly implemented.
nlwarning("Update item info queue (%i), but connection not ready", (int)_ItemInfoWaiters.size());
return;
}
// CONNECTION:READY not yet sent, so we cannot send requests yet!
nlassert(ConnectionReadySent || !_ItemInfoWaiters.size());
// For All waiters, look if one need update. // For All waiters, look if one need update.
TItemInfoWaiters::iterator it; TItemInfoWaiters::iterator it;
for(it= _ItemInfoWaiters.begin();it!=_ItemInfoWaiters.end();it++) for(it= _ItemInfoWaiters.begin();it!=_ItemInfoWaiters.end();it++)
{ {
/* \todo yoyo remove: temp patch to be sure that the client does not send messages before the
CONNECTION:READY is sent
*/
nlassert(ConnectionReadySent);
IItemInfoWaiter *waiter=*it; IItemInfoWaiter *waiter=*it;
uint itemSlotId= waiter->ItemSlotId; uint itemSlotId= waiter->ItemSlotId;
TItemInfoMap::iterator it= _ItemInfoMap.find(itemSlotId); TItemInfoMap::iterator it= _ItemInfoMap.find(itemSlotId);

@ -28,6 +28,9 @@
#include "interface_manager.h" #include "interface_manager.h"
#include "../client_cfg.h" #include "../client_cfg.h"
#include "nel/misc/thread.h"
#include "nel/misc/mutex.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
using namespace NL3D; using namespace NL3D;
@ -48,6 +51,88 @@ extern UDriver *Driver;
#define MP3_SAVE_REPEAT "UI:SAVE:MP3_REPEAT" #define MP3_SAVE_REPEAT "UI:SAVE:MP3_REPEAT"
CMusicPlayer MusicPlayer; CMusicPlayer MusicPlayer;
static NLMISC::CUnfairMutex MusicPlayerMutex;
// ***************************************************************************
class CMusicPlayerWorker : public NLMISC::IRunnable
{
private:
bool _Running;
IThread *_Thread;
std::vector<std::string> _Files;
public:
CMusicPlayerWorker(): _Running(false), _Thread(NULL)
{
}
~CMusicPlayerWorker()
{
_Running = false;
if (_Thread)
{
_Thread->terminate();
delete _Thread;
_Thread = NULL;
}
}
bool isRunning() const { return _Running; }
void run()
{
_Running = true;
uint i = 0;
while(_Running && SoundMngr && i < _Files.size())
{
// get copy incase _Files changes
std::string filename(_Files[i]);
std::string title;
float length;
if (SoundMngr->getMixer()->getSongTitle(filename, title, length))
{
MusicPlayer.updateSong(filename, title, length);
}
++i;
}
_Running = false;
_Files.clear();
}
// called from GUI
void getSongsInfo(const std::vector<std::string> &filenames)
{
if (_Thread)
{
stopThread();
}
_Files = filenames;
_Thread = IThread::create(this);
nlassert(_Thread != NULL);
_Thread->start();
}
void stopThread()
{
_Running = false;
if (_Thread)
{
_Thread->wait();
delete _Thread;
_Thread = NULL;
}
}
};
static CMusicPlayerWorker MusicPlayerWorker;
// *************************************************************************** // ***************************************************************************
@ -69,11 +154,14 @@ bool CMusicPlayer::isShuffleEnabled() const
return (NLGUI::CDBManager::getInstance()->getDbProp(MP3_SAVE_SHUFFLE)->getValue32() == 1); return (NLGUI::CDBManager::getInstance()->getDbProp(MP3_SAVE_SHUFFLE)->getValue32() == 1);
} }
// *************************************************************************** // ***************************************************************************
void CMusicPlayer::playSongs (const std::vector<CSongs> &songs) void CMusicPlayer::playSongs (const std::vector<std::string> &filenames)
{ {
_Songs = songs; _Songs.clear();
for (uint i=0; i<filenames.size(); i++)
{
_Songs.push_back(CSongs(filenames[i], CFile::getFilename(filenames[i]), 0.f));
}
// reset song index if out of bounds // reset song index if out of bounds
if (_CurrentSongIndex > _Songs.size()) if (_CurrentSongIndex > _Songs.size())
@ -85,26 +173,113 @@ void CMusicPlayer::playSongs (const std::vector<CSongs> &songs)
rebuildPlaylist(); rebuildPlaylist();
// If pause, stop, else play will resume // If pause, stop, else play will resume
if (_State == Paused) if (_State == Paused || _Songs.empty())
_State = Stopped; stop();
// get song title/duration using worker thread
MusicPlayerWorker.getSongsInfo(filenames);
} }
// *************************************************************************** // ***************************************************************************
void CMusicPlayer::updatePlaylist(sint prevIndex) void CMusicPlayer::updatePlaylist(uint index, bool state)
{ {
CInterfaceElement *pIE; if (index >= _Songs.size()) return;
std::string rowId;
std::string rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, index);
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(state);
}
void CMusicPlayer::updatePlaylist(sint prevIndex)
{
if (prevIndex >= 0 && prevIndex < _Songs.size()) if (prevIndex >= 0 && prevIndex < _Songs.size())
{ {
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, prevIndex); updatePlaylist(prevIndex, false);
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId)); }
if (pIE) pIE->setActive(false);
updatePlaylist(_CurrentSongIndex, true);
}
// ***************************************************************************
// called from worker thread
void CMusicPlayer::updateSong(const std::string filename, const std::string title, float length)
{
CAutoMutex<CUnfairMutex> mutex(MusicPlayerMutex);
_SongUpdateQueue.push_back(CSongs(filename, title, length));
}
// ***************************************************************************
// called from GUI
void CMusicPlayer::updateSongs()
{
CAutoMutex<CUnfairMutex> mutex(MusicPlayerMutex);
if (!_SongUpdateQueue.empty())
{
for(uint i = 0; i < _SongUpdateQueue.size(); ++i)
{
updateSong(_SongUpdateQueue[i]);
}
_SongUpdateQueue.clear();
}
}
// ***************************************************************************
void CMusicPlayer::updateSong(const CSongs &song)
{
uint index = 0;
while(index < _Songs.size())
{
if (_Songs[index].Filename == song.Filename)
{
_Songs[index].Title = song.Title;
_Songs[index].Length = song.Length;
break;
}
++index;
}
if (index == _Songs.size())
{
nlwarning("Unknown song file '%s'", song.Filename.c_str());
return;
}
std::string rowId(toString("%s:s%d", MP3_PLAYER_PLAYLIST_LIST, index));
CInterfaceGroup *pIG = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (!pIG)
{
nlwarning("Playlist row '%s' not found", rowId.c_str());
return;
} }
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, _CurrentSongIndex); CViewText *pVT;
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId)); pVT = dynamic_cast<CViewText *>(pIG->getView(TEMPLATE_PLAYLIST_SONG_TITLE));
if (pIE) pIE->setActive(true); if (pVT)
{
pVT->setHardText(song.Title);
}
else
{
nlwarning("title element '%s' not found", TEMPLATE_PLAYLIST_SONG_TITLE);
}
pVT = dynamic_cast<CViewText *>(pIG->getView(TEMPLATE_PLAYLIST_SONG_DURATION));
if (pVT)
{
uint min = (sint32)(song.Length / 60) % 60;
uint sec = (sint32)(song.Length) % 60;
uint hour = song.Length / 3600;
std::string duration(toString("%02d:%02d", min, sec));
if (hour > 0)
duration = toString("%02d:", hour) + duration;
pVT->setHardText(duration);
}
else
{
nlwarning("duration element '%s' not found", TEMPLATE_PLAYLIST_SONG_DURATION);
}
} }
// *************************************************************************** // ***************************************************************************
@ -131,12 +306,16 @@ void CMusicPlayer::rebuildPlaylist()
_CurrentSongIndex = i; _CurrentSongIndex = i;
} }
uint min = (sint32)(_Songs[i].Length / 60) % 60; std::string duration("--:--");
uint sec = (sint32)(_Songs[i].Length) % 60; if (_Songs[i].Length > 0)
uint hour = _Songs[i].Length / 3600; {
std::string duration(toString("%02d:%02d", min, sec)); uint min = (sint32)(_Songs[i].Length / 60) % 60;
if (hour > 0) uint sec = (sint32)(_Songs[i].Length) % 60;
duration = toString("%02d:", hour) + duration; uint hour = _Songs[i].Length / 3600;
duration = toString("%02d:%02d", min, sec);
if (hour > 0)
duration = toString("%02d:", hour) + duration;
}
vector< pair<string, string> > vParams; vector< pair<string, string> > vParams;
vParams.push_back(pair<string, string>("id", "s" + toString(i))); vParams.push_back(pair<string, string>("id", "s" + toString(i)));
@ -176,6 +355,17 @@ void CMusicPlayer::play (sint index)
if(!SoundMngr) if(!SoundMngr)
return; return;
if (_Songs.empty())
{
index = 0;
createPlaylistFromMusic();
}
if (_Songs.empty())
{
stop();
return;
}
sint prevSongIndex = _CurrentSongIndex; sint prevSongIndex = _CurrentSongIndex;
@ -244,11 +434,15 @@ void CMusicPlayer::stop ()
return; return;
// stop the music only if we are really playing (else risk to stop a background music!) // stop the music only if we are really playing (else risk to stop a background music!)
SoundMngr->stopMusic(0); if (_State != Stopped)
SoundMngr->stopMusic(0);
_State = Stopped; _State = Stopped;
_PlayStart = 0; _PlayStart = 0;
_PauseTime = 0; _PauseTime = 0;
clearPlayingInfo();
NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MP3_PLAYING")->setValueBool(false); NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MP3_PLAYING")->setValueBool(false);
} }
@ -284,15 +478,48 @@ void CMusicPlayer::next ()
} }
// *************************************************************************** // ***************************************************************************
void CMusicPlayer::updatePlayingInfo(const std::string info)
{
CViewText *pVT = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text"));
if (pVT)
{
pVT->setText(ucstring::makeFromUtf8(info));
}
}
// ***************************************************************************
void CMusicPlayer::clearPlayingInfo()
{
if (_Songs.empty())
{
updatePlayingInfo(CI18N::get("uiNoFiles").toUtf8());
}
else
{
updatePlayingInfo("");
}
}
// ***************************************************************************
void CMusicPlayer::update () void CMusicPlayer::update ()
{ {
if(!SoundMngr) if(!SoundMngr)
{
if (_State != Stopped)
{
_State = Stopped;
clearPlayingInfo();
}
return; return;
}
if (MusicPlayerWorker.isRunning() || !_SongUpdateQueue.empty())
{
updateSongs();
}
if (_State == Playing) if (_State == Playing)
{ {
CViewText *pVT = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text"));
if (pVT)
{ {
TTime dur = (CTime::getLocalTime() - _PlayStart) / 1000; TTime dur = (CTime::getLocalTime() - _PlayStart) / 1000;
uint min = (dur / 60) % 60; uint min = (dur / 60) % 60;
@ -302,7 +529,7 @@ void CMusicPlayer::update ()
std::string title(toString("%02d:%02d", min, sec)); std::string title(toString("%02d:%02d", min, sec));
if (hour > 0) title = toString("%02d:", hour) + title; if (hour > 0) title = toString("%02d:", hour) + title;
title += " " + _CurrentSong.Title; title += " " + _CurrentSong.Title;
pVT->setText(ucstring::makeFromUtf8(title)); updatePlayingInfo(title);
} }
if (SoundMngr->isMusicEnded ()) if (SoundMngr->isMusicEnded ())
@ -323,15 +550,20 @@ void CMusicPlayer::update ()
} }
else else
{ {
SoundMngr->stopMusic(0); // remove active highlight from playlist
_State = Stopped; updatePlaylist(_CurrentSongIndex, false);
stop();
// restart from top on next 'play'
_CurrentSongIndex = 0;
} }
} }
} }
} }
// *************************************************************************** // ***************************************************************************
static void addFromPlaylist(const std::string &playlist, std::vector<std::string> &filenames) static void addFromPlaylist(const std::string &playlist, const std::vector<std::string> &extensions, std::vector<std::string> &filenames)
{ {
static uint8 utf8Header[] = { 0xefu, 0xbbu, 0xbfu }; static uint8 utf8Header[] = { 0xefu, 0xbbu, 0xbfu };
@ -362,15 +594,82 @@ static void addFromPlaylist(const std::string &playlist, std::vector<std::string
// Not a comment line // Not a comment line
if (lineStr[0] != '#') if (lineStr[0] != '#')
{ {
std::string filepath = CFile::getPath(lineStr); std::string filename = CPath::makePathAbsolute(CFile::getPath(lineStr), basePlaylist) + CFile::getFilename(lineStr);
std::string filename = CFile::getFilename(lineStr); std::string ext = toLower(CFile::getExtension(filename));
filenames.push_back (CPath::makePathAbsolute(filepath, basePlaylist)+filename); if (std::find(extensions.begin(), extensions.end(), ext) != extensions.end())
{
if (CFile::fileExists(filename))
filenames.push_back(filename);
else
nlwarning("Ignore non-existing file '%s'", filename.c_str());
}
else
{
nlwarning("Ingnore invalid extension '%s'", filename.c_str());
}
} }
} }
fclose (file); fclose (file);
} }
} }
void CMusicPlayer::createPlaylistFromMusic()
{
std::vector<std::string> extensions;
SoundMngr->getMixer()->getMusicExtensions(extensions);
// no format supported
if (extensions.empty())
{
// in the very unlikely scenario
const ucstring message("Sound driver has no support for music.");
CInterfaceManager::getInstance()->displaySystemInfo(message, "SYS");
nlinfo("%s", message.toUtf8().c_str());
return;
}
std::string newPath = CPath::makePathAbsolute(CPath::standardizePath(ClientCfg.MediaPlayerDirectory), CPath::getCurrentPath(), true);
std::string extlist;
join(extensions, ", ", extlist);
extlist += ", m3u, m3u8";
std::string msg(CI18N::get("uiMk_system6").toUtf8());
msg += ": " + newPath + " (" + extlist + ")";
CInterfaceManager::getInstance()->displaySystemInfo(ucstring::makeFromUtf8(msg), "SYS");
nlinfo("%s", msg.c_str());
// Recursive scan for files from media directory
vector<string> filesToProcess;
CPath::getPathContent (newPath, true, false, true, filesToProcess);
uint i;
std::vector<std::string> filenames;
std::vector<std::string> playlists;
for (i = 0; i < filesToProcess.size(); ++i)
{
std::string ext = toLower(CFile::getExtension(filesToProcess[i]));
if (std::find(extensions.begin(), extensions.end(), ext) != extensions.end())
{
filenames.push_back(filesToProcess[i]);
}
else if (ext == "m3u" || ext == "m3u8")
{
playlists.push_back(filesToProcess[i]);
}
}
// Add songs from playlists
for (i = 0; i < playlists.size(); ++i)
{
addFromPlaylist(playlists[i], extensions, filenames);
}
// Sort songs by filename
sort(filenames.begin(), filenames.end());
playSongs(filenames);
}
// *************************************************************************** // ***************************************************************************
class CMusicPlayerPlaySongs: public IActionHandler class CMusicPlayerPlaySongs: public IActionHandler
{ {
@ -379,82 +678,16 @@ public:
{ {
if(!SoundMngr) if(!SoundMngr)
{ {
CInterfaceManager::getInstance()->messageBox (CI18N::get ("uiSoundDisabled")); // Do not show warning on volume change as its restored at startup
if (Params.find("volume") == std::string::npos)
CInterfaceManager::getInstance()->messageBox (CI18N::get ("uiMP3SoundDisabled"));
return; return;
} }
if (Params == "play_songs") if (Params == "play_songs")
{ {
std::vector<std::string> extensions; MusicPlayer.createPlaylistFromMusic();
SoundMngr->getMixer()->getMusicExtensions(extensions);
// no format supported
if (extensions.empty())
{
// in the very unlikely scenario
const ucstring message("Sound driver has no support for music.");
CInterfaceManager::getInstance()->displaySystemInfo(message, "SYS");
nlinfo("%s", message.toUtf8().c_str());
return;
}
std::string newPath = CPath::makePathAbsolute(CPath::standardizePath(ClientCfg.MediaPlayerDirectory), CPath::getCurrentPath(), true);
std::string extlist;
join(extensions, ", ", extlist);
extlist += ", m3u, m3u8";
std::string msg(CI18N::get("uiMk_system6").toUtf8());
msg += ": " + newPath + " (" + extlist + ")";
CInterfaceManager::getInstance()->displaySystemInfo(ucstring::makeFromUtf8(msg), "SYS");
nlinfo("%s", msg.c_str());
// Recursive scan for files from media directory
vector<string> filesToProcess;
CPath::getPathContent (newPath, true, false, true, filesToProcess);
uint i;
std::vector<std::string> filenames;
std::vector<std::string> playlists;
for (i = 0; i < filesToProcess.size(); ++i)
{
std::string ext = toLower(CFile::getExtension(filesToProcess[i]));
if (std::find(extensions.begin(), extensions.end(), ext) != extensions.end())
{
filenames.push_back(filesToProcess[i]);
}
else if (ext == "m3u" || ext == "m3u8")
{
playlists.push_back(filesToProcess[i]);
}
}
// Sort songs by filename
sort (filenames.begin(), filenames.end());
// Add songs from playlists
for (i = 0; i < playlists.size(); ++i)
{
addFromPlaylist(playlists[i], filenames);
}
// Build the songs array
std::vector<CMusicPlayer::CSongs> songs;
for (i=0; i<filenames.size(); i++)
{
if (!CFile::fileExists(filenames[i])) {
nlwarning("Ignore non-existing file '%s'", filenames[i].c_str());
continue;
}
CMusicPlayer::CSongs song;
song.Filename = filenames[i];
// TODO: cache the result for next refresh
SoundMngr->getMixer()->getSongTitle(filenames[i], song.Title, song.Length);
if (song.Length > 0)
songs.push_back (song);
}
MusicPlayer.playSongs(songs);
} }
else if (Params == "update_playlist") else if (Params == "update_playlist")
{ {

@ -42,12 +42,16 @@ public:
class CSongs class CSongs
{ {
public: public:
CSongs(std::string file = std::string(), std::string title = std::string(), float length = 0.f)
: Filename(file), Title(title), Length(length)
{ }
std::string Filename; std::string Filename;
std::string Title; std::string Title;
float Length; float Length;
}; };
void playSongs (const std::vector<CSongs> &songs); void playSongs (const std::vector<std::string> &filenames);
void play (sint index = -1); // Play the song at current position, if playing, restart. If paused, resume. void play (sint index = -1); // Play the song at current position, if playing, restart. If paused, resume.
void pause (); void pause ();
void stop (); void stop ();
@ -58,6 +62,10 @@ public:
void update (); void update ();
// update currently playing song info/duration on main gui
void updatePlayingInfo(const std::string info);
void clearPlayingInfo();
bool isRepeatEnabled() const; bool isRepeatEnabled() const;
bool isShuffleEnabled() const; bool isShuffleEnabled() const;
@ -67,6 +75,20 @@ public:
void shuffleAndRebuildPlaylist(); void shuffleAndRebuildPlaylist();
// Update playlist active row // Update playlist active row
void updatePlaylist(sint prevIndex = -1); void updatePlaylist(sint prevIndex = -1);
// set/remove playlist highlight
void updatePlaylist(uint index, bool state);
// Update single song title/duration on _Songs and on playlist
void updateSong(const CSongs &song);
// Update _Songs and playlist from _SongUpdateQueue
void updateSongs();
// update song from worker thread
void updateSong(const std::string filename, const std::string title, float length);
// scan music folder and rebuild playlist
void createPlaylistFromMusic();
private: private:
@ -74,6 +96,8 @@ private:
CSongs _CurrentSong; CSongs _CurrentSong;
uint _CurrentSongIndex; // If (!_Songs.empty()) must always be <_Songs.size() uint _CurrentSongIndex; // If (!_Songs.empty()) must always be <_Songs.size()
std::vector<CSongs> _Songs; std::vector<CSongs> _Songs;
// updated info from worker thread
std::vector<CSongs> _SongUpdateQueue;
// State // State
enum TState { Stopped, Playing, Paused } _State; enum TState { Stopped, Playing, Paused } _State;

@ -3279,6 +3279,7 @@ bool loginIntroSkip;
void loginIntro() void loginIntro()
{ {
// Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one) // Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one)
#if 0
for (uint i = 0; i < 1; i++) // previously display nevrax then nvidia for (uint i = 0; i < 1; i++) // previously display nevrax then nvidia
{ {
if (i != 0) if (i != 0)
@ -3316,6 +3317,7 @@ void loginIntro()
NLGUI::CDBManager::getInstance()->flushObserverCalls(); NLGUI::CDBManager::getInstance()->flushObserverCalls();
} }
} }
#endif
beginLoading(StartBackground); beginLoading(StartBackground);
ProgressBar.finish(); ProgressBar.finish();
} }

@ -555,11 +555,11 @@ void clearBuffers()
} }
// Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it
if (Driver->getPolygonMode() != UDriver::Filled) if (Driver->getPolygonMode() != UDriver::Filled || !Filter3D[FilterSky])
{ {
if (!Driver->isLost()) if (!Driver->isLost())
{ {
Driver->clearBuffers (CRGBA(127, 127, 127)); Driver->clearBuffers (ClientCfg.BGColor);
} }
} }
} }
@ -2233,19 +2233,21 @@ bool mainLoop()
{ {
StartPlayTime = NLMISC::CTime::getLocalTime(); StartPlayTime = NLMISC::CTime::getLocalTime();
} }
// Start background sound play now ! (nb: restarted if load just ended, or if sound re-enabled) // Start background sound play now ! (nb: restarted if load just ended, or if sound re-enabled)
if (SoundMngr) if (SoundMngr)
{ {
H_AUTO_USE ( RZ_Client_Main_Loop_Sound ) H_AUTO_USE ( RZ_Client_Main_Loop_Sound )
SoundMngr->playBackgroundSound();
}
// Fade in Game Sound now (before endLoading)
if(SoundMngr)
{
// fade out loading music // fade out loading music
if(LoadingMusic==SoundMngr->getEventMusicPlayed()) if (SoundMngr->getEventMusicPlayed() == LoadingMusic)
{
SoundMngr->stopEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade); SoundMngr->stopEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade);
}
SoundMngr->playBackgroundSound();
// Fade in Game Sound now (before endLoading)
// fade in game sound // fade in game sound
SoundMngr->fadeInGameSound(ClientCfg.SoundTPFade); SoundMngr->fadeInGameSound(ClientCfg.SoundTPFade);
} }
@ -2508,9 +2510,6 @@ bool mainLoop()
Actions.enable(true); Actions.enable(true);
EditActions.enable(true); EditActions.enable(true);
// For stoping the outgame music, start after 30 frames, and duration of 3 seconds
// CMusicFader outgameFader(60, 3);
// check for banned player // check for banned player
if (testPermanentBanMarkers()) if (testPermanentBanMarkers())
{ {
@ -2520,6 +2519,9 @@ bool mainLoop()
} }
} }
// For stoping the outgame music, start after 30 frames, and duration of 3 seconds
outgameFader = CMusicFader(60, 3);
// Short reinit of the main loop after farTP or character reselection // Short reinit of the main loop after farTP or character reselection
Ping.init(); Ping.init();
updateLightDesc(); updateLightDesc();

@ -110,6 +110,9 @@ void updateFromClientCfg()
if (ClientCfg.BilinearUI != LastClientCfg.BilinearUI) if (ClientCfg.BilinearUI != LastClientCfg.BilinearUI)
CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI); CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI);
CWidgetManager::getInstance()->setWindowSnapInvert(ClientCfg.WindowSnapInvert);
CWidgetManager::getInstance()->setWindowSnapDistance(ClientCfg.WindowSnapDistance);
//--------------------------------------------------- //---------------------------------------------------
if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL)
{ {

@ -1483,32 +1483,33 @@ void impulseTPCommon(NLMISC::CBitMemStream &impulse, bool hasSeason)
void impulseTPCommon2(NLMISC::CBitMemStream &impulse, bool hasSeason) void impulseTPCommon2(NLMISC::CBitMemStream &impulse, bool hasSeason)
{ {
// choose a default screen if not setuped // choose a default screen if not setuped
if( LoadingBackground!=ResurectKamiBackground && LoadingBackground!=ResurectKaravanBackground && if (LoadingBackground != ResurectKamiBackground && LoadingBackground != ResurectKaravanBackground
LoadingBackground!=TeleportKamiBackground && LoadingBackground!=TeleportKaravanBackground) && LoadingBackground != TeleportKamiBackground && LoadingBackground != TeleportKaravanBackground)
LoadingBackground= TeleportKaravanBackground; LoadingBackground = ElevatorBackground;
// if resurect but user not dead, choose default. NB: this is a bug, the tp impulse should tell // if resurect but user not dead, choose default. NB: this is a bug, the tp impulse should tell
// which background to choose. \todo yoyo: this is a temp fix // which background to choose. \todo yoyo: this is a temp fix
if( UserEntity && !UserEntity->isDead() && if (UserEntity && !UserEntity->isDead() && (LoadingBackground == ResurectKamiBackground || LoadingBackground == ResurectKaravanBackground))
(LoadingBackground==ResurectKamiBackground || LoadingBackground==ResurectKaravanBackground) ) LoadingBackground = ElevatorBackground;
LoadingBackground= TeleportKaravanBackground;
// Play music according to the background // Play music according to the background
if(SoundMngr) if (SoundMngr)
{ {
LoadingMusic.clear(); LoadingMusic.clear();
if(LoadingBackground==TeleportKamiBackground) switch (LoadingBackground)
LoadingMusic= "Kami Teleport.ogg";
else if(LoadingBackground==TeleportKaravanBackground)
LoadingMusic= "Karavan Teleport.ogg";
// if resurection, continue to play death music
else if(LoadingBackground==ResurectKamiBackground || LoadingBackground==ResurectKaravanBackground)
{
// noop
}
// default: loading music
else
{ {
LoadingMusic= "Loading Music Loop.ogg"; case TeleportKamiBackground:
LoadingMusic = ClientCfg.KamiTeleportMusic;
break;
case TeleportKaravanBackground:
LoadingMusic = ClientCfg.KaravanTeleportMusic;
break;
case ResurectKamiBackground:
case ResurectKaravanBackground:
// TODO: Resurrect music
break;
default:
LoadingMusic = ClientCfg.TeleportLoadingMusic;
break;
} }
// start to play // start to play

@ -497,7 +497,7 @@ void CEditor::requestSetLocalNode(const std::string& instanceId, const std::stri
CObject *src = _DMC->find(instanceId); CObject *src = _DMC->find(instanceId);
if (!src) if (!src)
{ {
nlwarning("Can't find object with id %s", instanceId.c_str()); nlwarning("Can't find object with id '%s' (setting attribute '%s')", instanceId.c_str(), attrName.c_str());
return; return;
} }
if (!attrName.empty()) if (!attrName.empty())
@ -7808,7 +7808,8 @@ NLMISC_COMMAND(saveScenarioRtData, "save scenario RtData to file", "<filename>")
output.open(fullFileName); output.open(fullFileName);
pRtData->serialize(ss); pRtData->serialize(ss);
//std::string str = ss.str(); //std::string str = ss.str();
output.serial(ss); // output.serial(ss);
output.serialBuffer((uint8 *)ss.c_str(), ss.length());
output.flush(); output.flush();
output.close(); output.close();
} }

@ -240,8 +240,8 @@ void releaseMainLoopReselect()
// alredy called from farTPMainLoop() // alredy called from farTPMainLoop()
// --R2::getEditor().autoConfigRelease(IsInRingSession); // --R2::getEditor().autoConfigRelease(IsInRingSession);
// Pause any user played music // stop any user played music
MusicPlayer.pause(); MusicPlayer.stop();
// flush the server string cache // flush the server string cache
STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); STRING_MANAGER::CStringManagerClient::instance()->flushStringCache();
@ -390,8 +390,8 @@ void releaseMainLoop(bool closeConnection)
// Release R2 editor if applicable // Release R2 editor if applicable
R2::getEditor().autoConfigRelease(IsInRingSession); R2::getEditor().autoConfigRelease(IsInRingSession);
// Pause any user played music // stop any user played music
MusicPlayer.pause(); MusicPlayer.stop();
// flush the server string cache // flush the server string cache
STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); STRING_MANAGER::CStringManagerClient::instance()->flushStringCache();

@ -4309,20 +4309,19 @@ void CUserEntity::updatePreCollision(const NLMISC::TTime &time, CEntityCL *targe
// test each frame if the mode has changed // test each frame if the mode has changed
if(SoundMngr) if(SoundMngr)
{ {
string deadMusic= "death.ogg";
// Play/stop music if comes from or goes to dead // Play/stop music if comes from or goes to dead
bool isDead= _Mode==MBEHAV::DEATH || _Mode==MBEHAV::SWIM_DEATH; bool isDead = _Mode == MBEHAV::DEATH || _Mode == MBEHAV::SWIM_DEATH;
// must start music? // must start music?
if( isDead && SoundMngr->getEventMusicPlayed()!=deadMusic ) if (isDead && SoundMngr->getEventMusicPlayed() != ClientCfg.DeathMusic)
{ {
SoundMngr->playEventMusic(deadMusic, 0, true); SoundMngr->playEventMusic(ClientCfg.DeathMusic, 0, true);
} }
// must end music? // must end music?
if( !isDead && SoundMngr->getEventMusicPlayed()==deadMusic ) if (!isDead && SoundMngr->getEventMusicPlayed() == ClientCfg.DeathMusic)
{ {
SoundMngr->stopEventMusic(deadMusic, CSoundManager::LoadingMusicXFade); SoundMngr->stopEventMusic(ClientCfg.DeathMusic, CSoundManager::LoadingMusicXFade);
} }
} }
} }

@ -865,7 +865,7 @@ component.create = function()
debugInfo("Cancel form for bandit camp creation") debugInfo("Cancel form for bandit camp creation")
end end
local function posOk(x, y, z) local function posOk(x, y, z)
debugInfo(string.format("Validate creation of bandit camp at pos (%d, %d, %d)", x, y, z)) debugInfo(string.format("Validate creation of bandit camp at pos (%f, %f, %f)", x, y, z))
if r2.mustDisplayInfo("BanditCamp") == 1 then if r2.mustDisplayInfo("BanditCamp") == 1 then
r2.displayFeatureHelp("BanditCamp") r2.displayFeatureHelp("BanditCamp")
end end

@ -518,7 +518,7 @@ component.create = function()
debugInfo("Cancel form for 'BossSpawnerFeature' creation") debugInfo("Cancel form for 'BossSpawnerFeature' creation")
end end
local function posOk(x, y, z) local function posOk(x, y, z)
debugInfo(string.format("Validate creation of 'BossSpawnerFeature' at pos (%d, %d, %d)", x, y, z)) debugInfo(string.format("Validate creation of 'BossSpawnerFeature' at pos (%f, %f, %f)", x, y, z))
if r2.mustDisplayInfo("BossSpawner") == 1 then if r2.mustDisplayInfo("BossSpawner") == 1 then
r2.displayFeatureHelp("BossSpawner") r2.displayFeatureHelp("BossSpawner")
end end

@ -245,7 +245,7 @@ component.create = function()
debugInfo("Cancel form for 'CounterFeature' creation") debugInfo("Cancel form for 'CounterFeature' creation")
end end
local function posOk(x, y, z) local function posOk(x, y, z)
debugInfo(string.format("Validate creation of 'CounterFeature' at pos (%d, %d, %d)", x, y, z)) debugInfo(string.format("Validate creation of 'CounterFeature' at pos (%f, %f, %f)", x, y, z))
r2:doForm("CounterFeatureForm", {X=x, Y=y}, paramsOk, paramsCancel) r2:doForm("CounterFeatureForm", {X=x, Y=y}, paramsOk, paramsCancel)
end end
local function posCancel() local function posCancel()

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

Loading…
Cancel
Save