This commit is contained in:
sfb 2010-10-15 20:54:14 -05:00
commit 4cf7f660d2
40 changed files with 1260 additions and 1527 deletions

View file

@ -188,7 +188,7 @@ ENDIF(BUILD_DOCUMENTATION)
IF(WITH_NEL_TESTS) IF(WITH_NEL_TESTS)
ENABLE_TESTING() ENABLE_TESTING()
ADD_TEST(nel_unit_test ${EXECUTABLE_OUTPUT_PATH}/nel_unit_test --html) ADD_TEST(nel_unit_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_unit_test --html)
IF(BUILD_DASHBOARD) IF(BUILD_DASHBOARD)
INCLUDE(Dart) INCLUDE(Dart)
SET(SVNCOMMAND svn) SET(SVNCOMMAND svn)

View file

@ -120,13 +120,14 @@ FIND_WWW_LIBRARY(LIBREGEX_LIBRARY OPTIONAL gnu_regex)
# Now link all libs together # Now link all libs together
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWCACHE_LIBRARY HTLoadCache) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWCACHE_LIBRARY HTLoadCache)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWCACHE_LIBRARY HTCacheAppend)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWFTP_LIBRARY HTLoadFTP) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWFTP_LIBRARY HTLoadFTP)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWGOPHER_LIBRARY HTLoadGopher) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWGOPHER_LIBRARY HTLoadGopher)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWNEWS_LIBRARY HTLoadNews) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWNEWS_LIBRARY HTLoadNews)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWTELNET_LIBRARY HTLoadTelnet) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWTELNET_LIBRARY HTLoadTelnet)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWSTREAM_LIBRARY HTStreamToChunk) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWSTREAM_LIBRARY HTStreamToChunk)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWDIR_LIBRARY HTIcon_addDir) LINK_WWW_LIBRARY(LIBWWWFILE_LIBRARY LIBWWWDIR_LIBRARY HTDir_new)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWINIT_LIBRARY HTProtocolInit) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWINIT_LIBRARY HTProtocolInit)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWXML_LIBRARY HTXML_new) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWXML_LIBRARY HTXML_new)
LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWZIP_LIBRARY HTZLib_inflate) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWZIP_LIBRARY HTZLib_inflate)

View file

@ -58,8 +58,8 @@ ENDIF(WITH_GTK)
IF(UNIX) IF(UNIX)
SET(prefix ${CMAKE_INSTALL_PREFIX}) SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin)
SET(libdir "${CMAKE_INSTALL_PREFIX}/lib") SET(libdir ${CMAKE_INSTALL_PREFIX}/lib)
SET(includedir "${CMAKE_INSTALL_PREFIX}/include") SET(includedir ${CMAKE_INSTALL_PREFIX}/include)
SET(enable_ligo ${WITH_LIGO}) SET(enable_ligo ${WITH_LIGO})
SET(enable_logic ${WITH_LOGIC}) SET(enable_logic ${WITH_LOGIC})
SET(enable_georges ${WITH_GEORGES}) SET(enable_georges ${WITH_GEORGES})
@ -67,7 +67,7 @@ IF(UNIX)
SET(enable_3d ${WITH_3D}) SET(enable_3d ${WITH_3D})
SET(enable_pacs ${WITH_PACS}) SET(enable_pacs ${WITH_PACS})
SET(enable_sound ${WITH_SOUND}) SET(enable_sound ${WITH_SOUND})
CONFIGURE_FILE(nel-config.in nel-config) CONFIGURE_FILE(nel-config.in ${CMAKE_CURRENT_BINARY_DIR}/nel-config)
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/nel-config DESTINATION bin) INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/nel-config DESTINATION bin)
ENDIF(UNIX) ENDIF(UNIX)

View file

@ -48,6 +48,8 @@
typedef HWND nlWindow; typedef HWND nlWindow;
#define EmptyWindow NULL #define EmptyWindow NULL
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
// TODO This should be NSView*, but then we would need to include Cocoa.h
// and compile with "-x objective-c++" ... everything including this file.
typedef void* nlWindow; typedef void* nlWindow;
#define EmptyWindow NULL #define EmptyWindow NULL
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)

View file

@ -218,8 +218,8 @@ private:
// the alternative language that will be used if the sentence is not found in the original language // the alternative language that will be used if the sentence is not found in the original language
static StrMapContainer _StrMapFallback; static StrMapContainer _StrMapFallback;
static const std::string _LanguageCodes[]; static std::vector<std::string> _LanguageCodes;
static const uint _NbLanguages; static std::vector<ucstring> _LanguageNames;
static bool _LanguagesNamesLoaded; static bool _LanguagesNamesLoaded;

View file

@ -22,17 +22,19 @@
#include "common.h" #include "common.h"
#include <map> #include <map>
#ifdef NL_OS_UNIX #ifdef NL_OS_WINDOWS
//#include <iostream> # ifdef NL_NO_ASM
# include <intrin.h>
# endif
#elif defined(NL_OS_UNIX)
# include <pthread.h> // PThread # include <pthread.h> // PThread
# include <semaphore.h> // PThread POSIX semaphores # include <semaphore.h> // PThread POSIX semaphores
# include <unistd.h> # include <unistd.h>
# define __forceinline # define __forceinline
#elif defined(NL_OS_WINDOWS) # ifdef NL_OS_MAC
# ifdef NL_NO_ASM # include <libkern/OSAtomic.h>
# include <intrin.h>
# endif
# endif # endif
#endif // NL_OS_WINDOWS
#undef MUTEX_DEBUG #undef MUTEX_DEBUG
@ -204,6 +206,7 @@ test_again:
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
#pragma managed(push, off) #pragma managed(push, off)
#endif #endif
class CFastMutex class CFastMutex
{ {
public: public:
@ -245,12 +248,18 @@ public:
} }
# endif // NL_DEBUG # endif // NL_DEBUG
# endif // NL_NO_ASM # endif // NL_NO_ASM
#else #elif defined(NL_OS_MAC)
return OSAtomicCompareAndSwap32(0, 1, reinterpret_cast<volatile sint32 *>(lockPtr));
#elif defined(NL_OS_UNIX)
// GCC implements the same functionality using a builtin function // GCC implements the same functionality using a builtin function
// http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html // http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html
// the macro below crashed on Mac OS X 10.6 in a 64bit build // the macro below crashed on Mac OS X 10.6 in a 64bit build
//ASM_ASWAP_FOR_GCC_XCHG # if (GCC_VERSION > 40100)
result = __sync_bool_compare_and_swap(lockPtr, 0, 1); // return __sync_bool_compare_and_swap(lockPtr, 0, 1);
result = __sync_val_compare_and_swap(lockPtr, 0, 1);
# else
ASM_ASWAP_FOR_GCC_XCHG
# endif
#endif // NL_OS_WINDOWS #endif // NL_OS_WINDOWS
return result != 0; return result != 0;
} }

View file

@ -148,7 +148,7 @@ public:
* for the HighestPri source. * for the HighestPri source.
* By default, reserve are set for each channel to the number of available tracks. * By default, reserve are set for each channel to the number of available tracks.
*/ */
virtual void setPriorityReserve(TSoundPriority priorityChannel, size_t reserve); virtual void setPriorityReserve(TSoundPriority priorityChannel, uint reserve);
/** Set the Low water mark. /** Set the Low water mark.
* This value is use to mute sound source that try to play when there priority * This value is use to mute sound source that try to play when there priority
* channel is full (see setPriorityReserve). * channel is full (see setPriorityReserve).
@ -161,7 +161,7 @@ public:
* available tracks (witch is almos alwais the case). But this value will help * available tracks (witch is almos alwais the case). But this value will help
* the mixer make it's best. * the mixer make it's best.
*/ */
virtual void setLowWaterMark(size_t value); virtual void setLowWaterMark(uint value);
virtual void changeMaxTrack(uint maxTrack); virtual void changeMaxTrack(uint maxTrack);

View file

@ -229,7 +229,7 @@ public:
* for the HighestPri source. * for the HighestPri source.
* By default, reserve are set for each channel to the number of available tracks. * By default, reserve are set for each channel to the number of available tracks.
*/ */
virtual void setPriorityReserve(TSoundPriority priorityChannel, size_t reserve) = 0; virtual void setPriorityReserve(TSoundPriority priorityChannel, uint reserve) = 0;
/** Set the Low water mark. /** Set the Low water mark.
* This value is use to mute sound source that try to play when their priority * This value is use to mute sound source that try to play when their priority
* channel is full (see setPriorityReserve). * channel is full (see setPriorityReserve).
@ -242,7 +242,7 @@ public:
* available tracks (which is almost always the case). But this value will help * available tracks (which is almost always the case). But this value will help
* the mixer make its best. * the mixer make its best.
*/ */
virtual void setLowWaterMark(size_t value) = 0; virtual void setLowWaterMark(uint value) = 0;
/** Change the number of tracks in RealTime. If the number is lowered, random tracks are deleted. /** Change the number of tracks in RealTime. If the number is lowered, random tracks are deleted.
* Any playing sources of such deleted track will be stopped * Any playing sources of such deleted track will be stopped
*/ */

View file

@ -2,6 +2,8 @@ FILE(GLOB SRC *.cpp *.h *.def)
IF(APPLE) IF(APPLE)
FILE(GLOB MAC_SRC mac/*.h mac/*.m mac/*.mm mac/*.cpp) FILE(GLOB MAC_SRC mac/*.h mac/*.m mac/*.mm mac/*.cpp)
SET(SRC ${SRC} ${MAC_SRC}) SET(SRC ${SRC} ${MAC_SRC})
SET_SOURCE_FILES_PROPERTIES(${SRC}
PROPERTIES COMPILE_FLAGS "-x objective-c++")
ENDIF(APPLE) ENDIF(APPLE)
IF(WIN32) IF(WIN32)

View file

@ -29,10 +29,6 @@
# include <string> # include <string>
# include <GL/gl.h> # include <GL/gl.h>
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# include "mac/glext.h"
# include "mac/cocoa_adapter.h"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
# include <GL/gl.h> # include <GL/gl.h>
# include <GL/glx.h> # include <GL/glx.h>
@ -189,7 +185,23 @@ CDriverGL::CDriverGL()
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::ctor(); _ctx = nil;
_glView = nil;
_backBufferHeight = 0;
_backBufferWidth = 0;
// autorelease pool for memory management
_autoreleasePool = [[NSAutoreleasePool alloc] init];
// init the application object
[NSApplication sharedApplication];
// create the menu in the top screen bar
setupApplicationMenu();
// finish the application launching
[NSApp finishLaunching];
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -331,7 +343,7 @@ CDriverGL::~CDriverGL()
release(); release();
#if defined(NL_OS_MAC) #if defined(NL_OS_MAC)
NL3D::MAC::dtor(); [_autoreleasePool release];
#endif #endif
} }
@ -860,7 +872,12 @@ bool CDriverGL::swapBuffers()
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::swapBuffers(_win); // TODO: maybe do this somewhere else?
[_autoreleasePool release];
_autoreleasePool = [[NSAutoreleasePool alloc] init];
[_ctx flushBuffer];
[containerView() display];
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2307,8 +2324,8 @@ void CDriverGL::retrieveATIDriverVersion()
RegCloseKey(parentKey); RegCloseKey(parentKey);
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation" # warning "OpenGL Driver: Missing Mac Implementation for ATI version retrieval"
nlwarning("OpenGL Driver: Missing Mac Implementation"); nlwarning("OpenGL Driver: Missing Mac Implementation for ATI version retrieval");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
// TODO for Linux: implement retrieveATIDriverVersion... assuming versions under linux are probably different // TODO for Linux: implement retrieveATIDriverVersion... assuming versions under linux are probably different

View file

@ -33,7 +33,10 @@
# include <GL/gl.h> # include <GL/gl.h>
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY # define GL_GLEXT_LEGACY
# import <Cocoa/Cocoa.h>
# include <OpenGL/gl.h> # include <OpenGL/gl.h>
# include "mac/glext.h"
# import "mac/cocoa_opengl_view.h"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
# define GLX_GLXEXT_PROTOTYPES # define GLX_GLXEXT_PROTOTYPES
# include <GL/gl.h> # include <GL/gl.h>
@ -701,6 +704,14 @@ private:
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NLMISC::CCocoaEventEmitter _EventEmitter; NLMISC::CCocoaEventEmitter _EventEmitter;
NSOpenGLContext* _ctx;
NSOpenGLView* _glView;
NSAutoreleasePool* _autoreleasePool;
uint16 _backBufferHeight;
uint16 _backBufferWidth;
NSView* containerView() { return (NSView*)_win; }
void setupApplicationMenu();
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1388,11 +1399,6 @@ public:
CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it);
}; };
#ifdef NL_OS_MAC
// Specific mac functions
extern bool getMacModes(std::vector<GfxMode> &modes);
#endif
} // NL3D } // NL3D
#endif // NL_DRIVER_OPENGL_H #endif // NL_DRIVER_OPENGL_H

View file

@ -25,10 +25,6 @@
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
# include <windowsx.h> # include <windowsx.h>
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# include "mac/glext.h"
# include "mac/cocoa_adapter.h"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
# include <GL/gl.h> # include <GL/gl.h>
# include <GL/glx.h> # include <GL/glx.h>
@ -298,11 +294,7 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
retrieveATIDriverVersion(); retrieveATIDriverVersion();
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
if(!NL3D::MAC::init(windowIcon, exitFunc)) // nothing to do
{
nldebug("cannot init");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -393,11 +385,7 @@ bool CDriverGL::unInit()
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
if(!NL3D::MAC::unInit()) // nothing to do
{
nldebug("cannot uninit");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -478,7 +466,7 @@ void CDriverGL::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
// nothing to do // nothing to do, on Mac OS X, only windows representing a file have icons
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -901,10 +889,67 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
_win = NL3D::MAC::setDisplay(wnd, mode, show, resizeable); if (wnd == EmptyWindow)
{
if (!createWindow(mode))
return false;
}
else
{
_win = wnd;
}
if(_win != EmptyWindow) // setup opengl settings
_DestroyWindow = true; NSOpenGLPixelFormatAttribute att[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFANoRecovery,
NSOpenGLPFAAccelerated,
NSOpenGLPFABackingStore,
0
};
// put the settings into a format object
NSOpenGLPixelFormat* format =
[[NSOpenGLPixelFormat alloc] initWithAttributes:att];
if(!format)
nlerror("cannot create NSOpenGLPixelFormat");
// create a opengl view with the created format
_glView = [[CocoaOpenGLView alloc]
initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format];
if(!_glView)
nlerror("cannot create view");
// make the view automatically fit the super view
[_glView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
// put the open gl view into the dummy view contained in the window
[containerView() addSubview:_glView];
// adjust size
[_glView setFrame: [containerView() frame]];
// create a opengl context for the view
_ctx = [_glView openGLContext];
if(!_ctx)
nlerror("cannot create context");
// free the pixel format object
[format release];
// let the open gl view handle the input
[[containerView() window] makeFirstResponder:_glView];
[_ctx flushBuffer];
[containerView() display];
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -1145,7 +1190,8 @@ bool CDriverGL::restoreScreenMode()
return res; return res;
} }
// -------------------------------------------------- // ***************************************************************************
#ifdef XF86VIDMODE #ifdef XF86VIDMODE
static sint modeInfoToFrequency(XF86VidModeModeInfo *info) static sint modeInfoToFrequency(XF86VidModeModeInfo *info)
{ {
@ -1153,7 +1199,8 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info)
} }
#endif // XF86VIDMODE #endif // XF86VIDMODE
// -------------------------------------------------- // ***************************************************************************
bool CDriverGL::setScreenMode(const GfxMode &mode) bool CDriverGL::setScreenMode(const GfxMode &mode)
{ {
H_AUTO_OGL(CDriverGL_setScreenMode) H_AUTO_OGL(CDriverGL_setScreenMode)
@ -1324,11 +1371,45 @@ bool CDriverGL::createWindow(const GfxMode &mode)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
window = NL3D::MAC::createWindow(mode); // describe how the window should look like and behave
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
// create a cocoa window with the size provided by the mode parameter
NSWindow* cocoa_window = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
if(!cocoa_window)
{
nlerror("cannot create cocoa window");
return false;
}
// set the window to non transparent
[cocoa_window setOpaque:YES];
// enable mouse move events, NeL wants them
[cocoa_window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subviews, can use the magical optimization :)
[cocoa_window useOptimizedDrawing:YES];
// put the window to the front and make it the key window
[cocoa_window makeKeyAndOrderFront:nil];
// this is our main window
[cocoa_window makeMainWindow];
// create a dummy view which works like the window on other platforms
// the open gl view will be created as subview of this one.
window = [[NSView alloc] init];
[cocoa_window setContentView: (NSView*)window];
if(window == EmptyWindow) if(window == EmptyWindow)
{ {
nldebug("cannot create window"); nldebug("cannot create cocoa view for cocoa window");
return false; return false;
} }
@ -1368,6 +1449,7 @@ bool CDriverGL::createWindow(const GfxMode &mode)
} }
// *************************************************************************** // ***************************************************************************
bool CDriverGL::destroyWindow() bool CDriverGL::destroyWindow()
{ {
H_AUTO_OGL(CDriverGL_destroyWindow) H_AUTO_OGL(CDriverGL_destroyWindow)
@ -1404,13 +1486,12 @@ bool CDriverGL::destroyWindow()
if(_DestroyWindow) if(_DestroyWindow)
{ {
if(!NL3D::MAC::destroyWindow(_win)) [containerView() release];
{ [[containerView() window] release];
nldebug("cannot destroy window");
return false;
}
} }
_ctx = nil;
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
if (_DestroyWindow) if (_DestroyWindow)
@ -1436,6 +1517,8 @@ bool CDriverGL::destroyWindow()
return true; return true;
} }
// ***************************************************************************
CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const
{ {
H_AUTO_OGL(CDriverGL_getWindowStyle) H_AUTO_OGL(CDriverGL_getWindowStyle)
@ -1446,6 +1529,8 @@ CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const
return EWSWindowed; return EWSWindowed;
} }
// ***************************************************************************
bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
{ {
H_AUTO_OGL(CDriverGL_setWindowStyle) H_AUTO_OGL(CDriverGL_setWindowStyle)
@ -1500,10 +1585,57 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
if(!NL3D::MAC::setWindowStyle(_win, windowStyle == EWSFullscreen)) // leave fullscreen mode, enter windowed mode
if(windowStyle == EWSWindowed && [containerView() isInFullScreenMode])
{ {
nldebug("cannot set window style"); // disable manual setting of back buffer size, cocoa handles this
return false; // automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[_ctx CGLContextObj],
kCGLCESurfaceBackingSize);
if(error != kCGLNoError)
nlerror("cannot disable kCGLCESurfaceBackingSize (%s)",
CGLErrorString(error));
// pull the view back from fullscreen restoring window options
[containerView() exitFullScreenModeWithOptions:nil];
// let the gl view receive key events
[[containerView() window] makeFirstResponder:_glView];
// bring the window containing the gl view to the front
[[containerView() window] makeKeyAndOrderFront:nil];
}
// enter fullscreen, leave windowed mode
else if(windowStyle == EWSFullscreen && ![containerView() isInFullScreenMode])
{
// enable manual back buffer size for mode setting in fullscreen
CGLError error = CGLEnable((CGLContextObj)[_ctx CGLContextObj],
kCGLCESurfaceBackingSize);
if(error != kCGLNoError)
nlerror("cannot enable kCGLCESurfaceBackingSize (%s)",
CGLErrorString(error));
// put the view in fullscreen mode, hiding the dock but enabling the menubar
// to pop up if the mouse hits the top screen border.
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
[containerView() enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:
NSApplicationPresentationHideDock |
NSApplicationPresentationAutoHideMenuBar],
NSFullScreenModeApplicationPresentationOptions, nil]];
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
/*
TODO check if simply using NSView enterFullScreenMode is a good idea.
the context can be set to full screen as well, performance differences?
*/
// let the gl view receive key events
[[containerView() window] makeFirstResponder:_glView];
} }
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -1558,6 +1690,8 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
#endif // NL_OS_WINDOWS #endif // NL_OS_WINDOWS
_FullScreen = (windowStyle == EWSFullscreen);
return true; return true;
} }
@ -1575,14 +1709,49 @@ bool CDriverGL::setMode(const GfxMode& mode)
if (!mode.Windowed) if (!mode.Windowed)
_Depth = mode.Depth; _Depth = mode.Depth;
_FullScreen = !mode.Windowed;
setWindowSize(mode.Width, mode.Height); setWindowSize(mode.Width, mode.Height);
setWindowPos(_WindowX, _WindowY); setWindowPos(_WindowX, _WindowY);
return true; return true;
} }
#if defined(NL_OS_MAC) && defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER)
/// helper to extract bits per pixel value from screen mode, only 16 or 32 bits
static int bppFromDisplayMode(CGDisplayModeRef mode)
{
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
if(CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 32;
else if(CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 16;
return 0;
}
#elif defined(NL_OS_MAC) && !defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER)
long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
{
long value = 0;
CFNumberRef numRef;
numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
if (numRef != NULL)
CFNumberGetValue(numRef, kCFNumberLongType, &value);
return value;
}
// some macros to make code more readable.
#define GetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
#define GetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
#define GetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
#endif // defined(NL_OS_MAC)
// -------------------------------------------------- // --------------------------------------------------
bool CDriverGL::getModes(std::vector<GfxMode> &modes) bool CDriverGL::getModes(std::vector<GfxMode> &modes)
{ {
@ -1611,7 +1780,71 @@ bool CDriverGL::getModes(std::vector<GfxMode> &modes)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::getModes(modes); static const CGDisplayCount kMaxDisplays = 16;
CGDirectDisplayID display[kMaxDisplays];
CGDisplayCount numDisplays;
CGDisplayErr err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays);
if(err != CGDisplayNoErr)
{
nlwarning("Cannot get displays (%d)", err);
return false;
}
// nldebug("3D: %d displays found", (int)numDisplays);
for (CGDisplayCount i = 0; i < numDisplays; ++i)
{
CGDirectDisplayID dspy = display[i];
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
CFArrayRef modeList = CGDisplayCopyAllDisplayModes(dspy, NULL);
#else
CFArrayRef modeList = CGDisplayAvailableModes(dspy);
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
if (modeList == NULL)
{
nlwarning("Display is invalid");
continue;
}
for (CFIndex j = 0; j < CFArrayGetCount(modeList); ++j)
{
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, j);
uint8 bpp = bppFromDisplayMode(mode);
#else
CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(modeList, j);
uint8 bpp = (uint8)GetModeBitsPerPixel(mode);
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
if (bpp >= 16)
{
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
uint16 w = CGDisplayModeGetWidth(mode);
uint16 h = CGDisplayModeGetHeight(mode);
#else
uint16 w = (uint16)GetModeWidth(mode);
uint16 h = (uint16)GetModeHeight(mode);
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
// Add this mode
GfxMode mode;
mode.Width = w;
mode.Height = h;
mode.Depth = bpp;
// Frequency stays at 0 because on mac cocoa, display resolution
// is never really changed. if rendering res < display res,
// cocoa interpolates and keeps the display at it's original res.
mode.Frequency = 0;
modes.push_back (mode);
// nldebug(" Display 0x%x: Mode %dx%d, %d BPP", dspy, w, h, bpp);
}
}
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1722,7 +1955,30 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::getCurrentScreenMode(_win, mode); // the sceen with the menu bar
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
mode.OffScreen = false;
mode.Frequency = 0;
mode.Depth = NSBitsPerPixelFromDepth([screen depth]);
// in fullscreen mode
if([containerView() isInFullScreenMode])
{
// return the size of the back buffer (like having switched monitor mode)
mode.Windowed = false;
mode.Width = _backBufferWidth;
mode.Height = _backBufferHeight;
}
// in windowed mode
else
{
// return the size of the screen with menu bar
mode.Windowed = true;
mode.Width = (uint16)[screen frame].size.width;
mode.Height = (uint16)[screen frame].size.height;
}
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -1830,7 +2086,8 @@ void CDriverGL::setWindowTitle(const ucstring &title)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::setWindowTitle(_win, title); [[containerView() window] setTitle:
[NSString stringWithUTF8String:title.toUtf8().c_str()]];
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1862,7 +2119,19 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::setWindowPos(_win, x, y); nldebug("setting window pos to %d %d", x, y);
// get the rect (position, size) of the screen with menu bar
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
// get the rect (position, size) of the window
NSRect windowRect = [[containerView() window] frame];
// convert y from NeL coordinates to cocoa coordinates
y = screenRect.size.height - y;
// tell cocoa to move the window
[[containerView() window] setFrameTopLeftPoint:NSMakePoint(x, y)];
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1895,7 +2164,7 @@ void CDriverGL::showWindow(bool show)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
MAC::showWindow(show); // TODO implement me
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1940,11 +2209,8 @@ bool CDriverGL::activate()
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
if(!MAC::activate(_win)) if([NSOpenGLContext currentContext] != _ctx)
{ [_ctx makeCurrentContext];
nlwarning("cannot activate");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2024,7 +2290,28 @@ void CDriverGL::showCursor(bool b)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::showCursor(b); // Mac OS manages a show/hide counter for the cursor, so hiding the cursor
// twice requires two calls to "show" to make the cursor visible again.
// Since other platforms seem to not do this, the functionality is masked here
// by only calling hide if the cursor is visible and only calling show if
// the cursor was hidden.
CGDisplayErr error = kCGErrorSuccess;
static bool visible = true;
if(b && !visible)
{
error = CGDisplayShowCursor(kCGDirectMainDisplay);
visible = true;
}
else if(!b && visible)
{
error = CGDisplayHideCursor(kCGDirectMainDisplay);
visible = false;
}
if(error != kCGErrorSuccess)
nlerror("cannot show / hide cursor");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2077,7 +2364,30 @@ void CDriverGL::setMousePos(float x, float y)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::setMousePos(_win, x, y); // CG wants absolute coordinates related to first screen's top left
// get the first screen's (conaints menubar) rect (this is not mainScreen)
NSRect firstScreenRect = [[[NSScreen screens] objectAtIndex:0] frame];
// get the rect (position, size) of the window
NSRect windowRect;
if([containerView() isInFullScreenMode])
windowRect = [[[containerView() window] screen] frame];
else
windowRect = [[containerView() window] frame];
// get the view's rect for height and width
NSRect viewRect = [containerView() frame];
// set the cursor position
CGDisplayErr error = CGDisplayMoveCursorToPoint(
kCGDirectMainDisplay, CGPointMake(
windowRect.origin.x + (viewRect.size.width * x),
firstScreenRect.size.height - windowRect.origin.y -
viewRect.size.height + ((1.0 - y) * viewRect.size.height)));
if(error != kCGErrorSuccess)
nlerror("cannot set mouse position");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2092,7 +2402,32 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
#ifdef NL_OS_MAC #ifdef NL_OS_MAC
NL3D::MAC::getWindowSize(_win, width, height); // TODO set them in windowproc, so no special impl is needed here
// A cocoa fullscreen view stays at the native resolution of the display.
// When changing the rendering resolution, the size of the back buffer gets
// changed, but the view still stays at full resolution. So the scaling of
// the image from the rendered resolution to the view's resolution is done
// by cocoa automatically while flushing buffers.
// That's why, in fullscreen mode, return the resolution of the back buffer,
// not the one from the window.
// in fullscreen mode
if([containerView() isInFullScreenMode])
{
// use the size stored in setWindowSize()
width = _backBufferWidth;
height = _backBufferHeight;
}
// in windowed mode
else
{
// use the size of the view
NSRect rect = [containerView() frame];
width = rect.size.width;
height = rect.size.height;
}
#else // NL_OS_MAC #else // NL_OS_MAC
@ -2146,7 +2481,43 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::setWindowSize(_win, width, height); // for fullscreen mode, adjust the back buffer size to the desired resolution
if([containerView() isInFullScreenMode])
{
// disable and re-enable fullscreen
// fixes #1062 (http://dev.ryzom.com/issues/1062)
setWindowStyle(EWSWindowed);
setWindowStyle(EWSFullscreen);
// set the back buffer manually to match the desired rendering resolution
GLint dim[2] = { width, height };
CGLError error = CGLSetParameter(
(CGLContextObj)[_ctx CGLContextObj],
kCGLCPSurfaceBackingSize, dim);
if(error != kCGLNoError)
nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
CGLErrorString(error));
_backBufferWidth = width;
_backBufferHeight = height;
}
else
{
// only change the window size if the driver created the window itself
if(_DestroyWindow)
{
// get the windows current frame
NSRect rect = [[containerView() window] frame];
// convert the desired content size to window size
rect = [[containerView() window] frameRectForContentRect:
NSMakeRect(rect.origin.x, rect.origin.y, width, height)];
// update window dimensions
[[containerView() window] setFrame:rect display:YES];
}
}
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -2182,8 +2553,19 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y)
H_AUTO_OGL(CDriverGL_getWindowPos) H_AUTO_OGL(CDriverGL_getWindowPos)
#ifdef NL_OS_MAC #ifdef NL_OS_MAC
// TODO set them in window proc so no special impl is needed here
NL3D::MAC::getWindowPos(_win, x, y); // get the rect (position, size) of the screen with menu bar
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
// get the rect (position, size) of the window
NSRect windowRect = [[containerView() window] frame];
// simply return x
x = windowRect.origin.x;
// map y from cocoa to NeL coordinates before returning
y = screenRect.size.height - windowRect.size.height - windowRect.origin.y;
#else // NL_OS_MAC #else // NL_OS_MAC
@ -2219,9 +2601,7 @@ bool CDriverGL::isActive()
res = (IsWindow(_win) != FALSE); res = (IsWindow(_win) != FALSE);
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation" # warning "OpenGL Driver: Missing Mac Implementation for isActive"
// nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
@ -2264,7 +2644,7 @@ void CDriverGL::setCapture (bool b)
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
NL3D::MAC::setCapture(b); // no need to capture
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2316,11 +2696,7 @@ NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
#endif #endif
return res; return res;
@ -2358,11 +2734,7 @@ NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable)
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
#endif #endif
return res; return res;
@ -2381,11 +2753,7 @@ NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager()
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1)); res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
#endif #endif
return res; return res;
@ -2429,8 +2797,8 @@ uint CDriverGL::getDoubleClickDelay(bool hardwareMouse)
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation" # warning "OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay"
nlwarning("OpenGL Driver: Missing Mac Implementation"); nlwarning("OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -2492,11 +2860,10 @@ bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &proper
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
# warning "OpenGL Driver: Missing Mac Implementation" // TODO for Mac: implement CDriverGL::setMonitorColorProperties
nlwarning("OpenGL Driver: Missing Mac Implementation"); nlwarning ("CDriverGL::setMonitorColorProperties not implemented");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
// TODO for Linux: implement CDriverGL::setMonitorColorProperties // TODO for Linux: implement CDriverGL::setMonitorColorProperties
nlwarning ("CDriverGL::setMonitorColorProperties not implemented"); nlwarning ("CDriverGL::setMonitorColorProperties not implemented");
@ -2505,4 +2872,64 @@ bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &proper
return false; return false;
} }
#ifdef NL_OS_MAC
void CDriverGL::setupApplicationMenu()
{
NSMenu* menu;
NSMenuItem* menuItem;
NSString* title;
NSString* appName;
// get the applications name from it's process info
appName = [[NSProcessInfo processInfo] processName];
// create an empty menu object
menu = [[NSMenu alloc] initWithTitle:@""];
// add the about menu item
title = [@"About " stringByAppendingString:appName];
[menu addItemWithTitle:title
action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
// separator
[menu addItem:[NSMenuItem separatorItem]];
// add the hide application menu item
title = [@"Hide " stringByAppendingString:appName];
[menu addItemWithTitle:title
action:@selector(hide:) keyEquivalent:@"h"];
// add the hide others menu item
menuItem = [menu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
// add the show all menu item
[menu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:) keyEquivalent:@""];
// separator
[menu addItem:[NSMenuItem separatorItem]];
/*
TODO on quit send EventDestroyWindowId
*/
// add the quit menu item
title = [@"Quit " stringByAppendingString:appName];
[menu addItemWithTitle:title
action:@selector(terminate:) keyEquivalent:@"q"];
// create an empty menu item and put the new menu into it as a subitem
menuItem = [[NSMenuItem alloc] initWithTitle:@""
action:nil keyEquivalent:@""];
[menuItem setSubmenu:menu];
// create a menu for the application
[NSApp setMainMenu:[[NSMenu alloc] initWithTitle:@""]];
// attach the new menu to the applications menu
[[NSApp mainMenu] addItem:menuItem];
}
#endif
} // NL3D } // NL3D

View file

@ -16,103 +16,4 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef NL_DRIVER_OPENGL_MAC_COCOA_ADAPTER_H /* TODO remove this file */
#define NL_DRIVER_OPENGL_MAC_COCOA_ADAPTER_H
#include "nel/misc/types_nl.h"
#include "nel/misc/event_server.h"
#include "nel/3d/driver.h"
#include "cocoa_event_emitter.h"
/*
* this cocoa adapter is a helper to call functions executing obj-c code
* from driver_opengl.cpp
*
* please see this as a temporary solution... there is some stuff concerning
* driver refactoring going on anyway as far as i know
*
* this can as well be seen as a preparation to pull platform specific code
* out of driver_opengl.cpp ;)
*
* btw: we cannot simply use a c++ class here, because then NSWindow* and friends
* would be members, but then we would need to add obj-c code here using an
* include or a forward declaration. this again would break compiling cpp files
* including this one (eg. driver_opengl.cpp)
*/
namespace NL3D { namespace MAC {
/// mac specific stuff while calling CDriverGL::CDriverGL()
void ctor();
/// mac specific stuff while calling CDriverGL::~CDriverGL()
void dtor();
/// mac specific stuff while calling CDriverGL::init()
bool init(uint windowIcon = 0, emptyProc exitFunc = 0);
/// mac specific stuff while calling CDriverGL::unInit()
bool unInit();
/// mac specific stuff while calling CDriverGL::createWindow()
nlWindow createWindow(const GfxMode& mode);
/// mac specific stuff while calling CDriverGL::destroyWindow()
bool destroyWindow(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::setDisplay()
nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
/// mac specific stuff while calling CDriverGL::setWindowStyle()
bool setWindowStyle(nlWindow wnd, bool fullscreen);
/// mac specific stuff while calling CDriverGL::getCurrentScreenMode()
void getCurrentScreenMode(nlWindow wnd, GfxMode& mode);
/// mac specific stuff while calling CDriverGL::getModes()
bool getModes(std::vector<GfxMode> &modes);
/// mac specific stuff while calling CDriverGL::getWindowSize()
void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height);
/// mac specific stuff while calling CDriverGL::setWindowSize()
void setWindowSize(nlWindow wnd, uint32 width, uint32 height);
/// mac specific stuff while calling CDriverGL::getWindowPos()
void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y);
/// mac specific stuff while calling CDriverGL::setWindowPos()
void setWindowPos(nlWindow wnd, sint32 x, sint32 y);
/// mac specific stuff while calling CDriverGL::setWindowTitle()
void setWindowTitle(nlWindow wnd, const ucstring& title);
/// mac specific stuff while calling CDriverGL::showWindow()
void showWindow(bool show);
/// mac specific stuff while calling CDriverGL::activate()
bool activate(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::swapBuffers()
void swapBuffers(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::setCapture()
void setCapture(bool capture);
/// mac specific stuff while calling CDriverGL::showCursor()
void showCursor(bool show);
/// mac specific stuff while calling CDriverGL::setMousePos()
void setMousePos(nlWindow wnd, float x, float y);
/// mac specific stuff while calling CCocoaEventEmitter::submitEvents()
void submitEvents(NLMISC::CEventServer& server,
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);
/// mac specific stuff while calling CCocoaEventEmitter::emulateMouseRawMode()
void emulateMouseRawMode(bool enable);
}}
#endif

File diff suppressed because it is too large Load diff

View file

@ -16,21 +16,397 @@
#include "cocoa_event_emitter.h" #include "cocoa_event_emitter.h"
#include "cocoa_adapter.h" #include "nel/misc/event_server.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
namespace NLMISC namespace NLMISC
{ {
void CCocoaEventEmitter::submitEvents(CEventServer & server, bool allWindows) /// map from virtual key code to nel internal key code
static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode)
{ {
// just forwarding to our cocoa adapter switch(keycode)
NL3D::MAC::submitEvents(server, allWindows, this); {
case kVK_ANSI_0: return NLMISC::Key0;
case kVK_ANSI_1: return NLMISC::Key1;
case kVK_ANSI_2: return NLMISC::Key2;
case kVK_ANSI_3: return NLMISC::Key3;
case kVK_ANSI_4: return NLMISC::Key4;
case kVK_ANSI_5: return NLMISC::Key5;
case kVK_ANSI_6: return NLMISC::Key6;
case kVK_ANSI_7: return NLMISC::Key7;
case kVK_ANSI_8: return NLMISC::Key8;
case kVK_ANSI_9: return NLMISC::Key9;
case kVK_ANSI_A: return NLMISC::KeyA;
case kVK_ANSI_B: return NLMISC::KeyB;
case kVK_ANSI_C: return NLMISC::KeyC;
case kVK_ANSI_D: return NLMISC::KeyD;
case kVK_ANSI_E: return NLMISC::KeyE;
case kVK_ANSI_F: return NLMISC::KeyF;
case kVK_ANSI_G: return NLMISC::KeyG;
case kVK_ANSI_H: return NLMISC::KeyH;
case kVK_ANSI_I: return NLMISC::KeyI;
case kVK_ANSI_J: return NLMISC::KeyJ;
case kVK_ANSI_K: return NLMISC::KeyK;
case kVK_ANSI_L: return NLMISC::KeyL;
case kVK_ANSI_M: return NLMISC::KeyM;
case kVK_ANSI_N: return NLMISC::KeyN;
case kVK_ANSI_O: return NLMISC::KeyO;
case kVK_ANSI_P: return NLMISC::KeyP;
case kVK_ANSI_Q: return NLMISC::KeyQ;
case kVK_ANSI_R: return NLMISC::KeyR;
case kVK_ANSI_S: return NLMISC::KeyS;
case kVK_ANSI_T: return NLMISC::KeyT;
case kVK_ANSI_U: return NLMISC::KeyU;
case kVK_ANSI_V: return NLMISC::KeyV;
case kVK_ANSI_W: return NLMISC::KeyW;
case kVK_ANSI_X: return NLMISC::KeyX;
case kVK_ANSI_Y: return NLMISC::KeyY;
case kVK_ANSI_Z: return NLMISC::KeyZ;
case kVK_ANSI_Equal: return NLMISC::KeyEQUALS;
case kVK_ANSI_Minus: return NLMISC::KeySUBTRACT;
case kVK_ANSI_RightBracket: return NLMISC::KeyRBRACKET;
case kVK_ANSI_LeftBracket: return NLMISC::KeyLBRACKET;
case kVK_ANSI_Quote: return NLMISC::KeyAPOSTROPHE;
case kVK_ANSI_Grave: return NLMISC::KeyPARAGRAPH;
case kVK_ANSI_Slash: return NLMISC::KeySLASH;
case kVK_ANSI_Backslash: return NLMISC::KeyBACKSLASH;
case kVK_ANSI_Comma: return NLMISC::KeyCOMMA;
case kVK_ANSI_Period: return NLMISC::KeyPERIOD;
case kVK_ANSI_Semicolon: return NLMISC::KeySEMICOLON;
case kVK_ANSI_KeypadDecimal: return NLMISC::KeyDECIMAL;
case kVK_ANSI_KeypadMultiply: return NLMISC::KeyMULTIPLY;
case kVK_ANSI_KeypadPlus: return NLMISC::KeyADD;
case kVK_ANSI_KeypadClear: return NLMISC::KeyDELETE;
case kVK_ANSI_KeypadDivide: return NLMISC::KeyDIVIDE;
case kVK_ANSI_KeypadEnter: return NLMISC::KeyRETURN;
case kVK_ANSI_KeypadMinus: return NLMISC::KeySUBTRACT;
case kVK_ANSI_KeypadEquals: return NLMISC::KeySEPARATOR;
case kVK_ANSI_Keypad0: return NLMISC::KeyNUMPAD0;
case kVK_ANSI_Keypad1: return NLMISC::KeyNUMPAD1;
case kVK_ANSI_Keypad2: return NLMISC::KeyNUMPAD2;
case kVK_ANSI_Keypad3: return NLMISC::KeyNUMPAD3;
case kVK_ANSI_Keypad4: return NLMISC::KeyNUMPAD4;
case kVK_ANSI_Keypad5: return NLMISC::KeyNUMPAD5;
case kVK_ANSI_Keypad6: return NLMISC::KeyNUMPAD6;
case kVK_ANSI_Keypad7: return NLMISC::KeyNUMPAD7;
case kVK_ANSI_Keypad8: return NLMISC::KeyNUMPAD8;
case kVK_ANSI_Keypad9: return NLMISC::KeyNUMPAD9;
case kVK_Return: return NLMISC::KeyRETURN;
case kVK_Tab: return NLMISC::KeyTAB;
case kVK_Space: return NLMISC::KeySPACE;
case kVK_Delete: return NLMISC::KeyBACK;
case kVK_ForwardDelete: return NLMISC::KeyDELETE;
case kVK_Escape: return NLMISC::KeyESCAPE;
case kVK_Shift: return NLMISC::KeySHIFT;
case kVK_RightShift: return NLMISC::KeyRSHIFT;
case kVK_CapsLock: return NLMISC::KeyCAPITAL;
case kVK_Control: return NLMISC::KeyCONTROL;
case kVK_RightControl: return NLMISC::KeyRCONTROL;
case kVK_F1: return NLMISC::KeyF1;
case kVK_F2: return NLMISC::KeyF2;
case kVK_F3: return NLMISC::KeyF3;
case kVK_F4: return NLMISC::KeyF4;
case kVK_F5: return NLMISC::KeyF5;
case kVK_F6: return NLMISC::KeyF6;
case kVK_F7: return NLMISC::KeyF7;
case kVK_F8: return NLMISC::KeyF8;
case kVK_F9: return NLMISC::KeyF9;
case kVK_F11: return NLMISC::KeyF11;
case kVK_F13: return NLMISC::KeyF13;
case kVK_F16: return NLMISC::KeyF16;
case kVK_F14: return NLMISC::KeyF14;
case kVK_F10: return NLMISC::KeyF10;
case kVK_F12: return NLMISC::KeyF12;
case kVK_F15: return NLMISC::KeyF15;
case kVK_F17: return NLMISC::KeyF17;
case kVK_F18: return NLMISC::KeyF18;
case kVK_F19: return NLMISC::KeyF19;
case kVK_F20: return NLMISC::KeyF20;
case kVK_Home: return NLMISC::KeyHOME;
case kVK_End: return NLMISC::KeyEND;
case kVK_PageUp: return NLMISC::KeyPRIOR;
case kVK_PageDown: return NLMISC::KeyNEXT;
case kVK_LeftArrow: return NLMISC::KeyLEFT;
case kVK_RightArrow: return NLMISC::KeyRIGHT;
case kVK_DownArrow: return NLMISC::KeyDOWN;
case kVK_UpArrow: return NLMISC::KeyUP;
case kVK_Command:break;
case kVK_Option:break;
case kVK_RightOption:break;
case kVK_Function:break;
case kVK_VolumeUp:break;
case kVK_VolumeDown:break;
case kVK_Mute:break;
case kVK_Help:break;
case kVK_ISO_Section:break;
case kVK_JIS_Yen:break;
case kVK_JIS_Underscore:break;
case kVK_JIS_KeypadComma:break;
case kVK_JIS_Eisu:break;
case kVK_JIS_Kana:break;
default:break;
}
return NLMISC::KeyNOKEY;
}
/// convert modifier key state to nel internal modifier key state
static NLMISC::TKeyButton modifierFlagsToNelKeyButton(unsigned int modifierFlags)
{
unsigned int buttons = 0;
if (modifierFlags & NSControlKeyMask) buttons |= NLMISC::ctrlKeyButton;
if (modifierFlags & NSShiftKeyMask) buttons |= NLMISC::shiftKeyButton;
if (modifierFlags & NSAlternateKeyMask) buttons |= NLMISC::altKeyButton;
return (NLMISC::TKeyButton)buttons;
}
/// check whether a given event represents input text
static bool isTextKeyEvent(NSEvent* event)
{
// if there are no characters provided with this event, it is not a text event
if([[event characters] length] == 0)
return false;
NLMISC::TKey nelKey = virtualKeycodeToNelKey([event keyCode]);
// ryzom ui wants to have "escape key string" to leave text box
if(nelKey == NLMISC::KeyESCAPE)
return true;
// ryzom ui wants to have "return key string" to submit text box (send chat)
if(nelKey == NLMISC::KeyRETURN)
return true;
// get the character reported by cocoa
unsigned int character = [[event characters] characterAtIndex:0];
// printable ascii characters
if(isprint(character))
return true;
/*
TODO check why iswprint(character) does not solve it.
it always returns false, even for π, é, ...
*/
// characters > 127 but not printable
if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 ||
nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 ||
nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 ||
nelKey == NLMISC::KeyF7 || nelKey == NLMISC::KeyF8 ||
nelKey == NLMISC::KeyF9 || nelKey == NLMISC::KeyF10 ||
nelKey == NLMISC::KeyF11 || nelKey == NLMISC::KeyF12 ||
nelKey == NLMISC::KeyF13 || nelKey == NLMISC::KeyF14 ||
nelKey == NLMISC::KeyF15 || nelKey == NLMISC::KeyF16 ||
nelKey == NLMISC::KeyF17 || nelKey == NLMISC::KeyF18 ||
nelKey == NLMISC::KeyF19 || nelKey == NLMISC::KeyF20 ||
nelKey == NLMISC::KeyUP || nelKey == NLMISC::KeyDOWN ||
nelKey == NLMISC::KeyLEFT || nelKey == NLMISC::KeyRIGHT ||
nelKey == NLMISC::KeyHOME || nelKey == NLMISC::KeyEND ||
nelKey == NLMISC::KeyPRIOR || nelKey == NLMISC::KeyNEXT ||
nelKey == NLMISC::KeyDELETE)
return false;
// all the fancy wide characters
if(character > 127)
return true;
return false;
}
void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */)
{
// break if there was no event to handle
while(true)
{
// get the next event to handle
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil /*[NSDate distantFuture]*/
inMode:NSDefaultRunLoopMode dequeue:YES];
// stop, if there was no event
if(!event)
break;
NSView* glView = [[[[event window] contentView] subviews] lastObject];
NSRect viewRect = [glView frame];
// TODO this code assumes, that the view fills the window
// convert the mouse position to NeL style (relative)
float mouseX = event.locationInWindow.x / (float)viewRect.size.width;
float mouseY = event.locationInWindow.y / (float)viewRect.size.height;
// if the mouse event was placed outside the view, don't tell NeL :)
if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) &&
event.type != NSKeyDown && event.type != NSKeyUp)
{
[NSApp sendEvent:event];
continue;
}
// convert the modifiers for nel to pass them with the events
NLMISC::TKeyButton modifiers =
modifierFlagsToNelKeyButton([event modifierFlags]);
switch(event.type)
{
case NSLeftMouseDown:
{
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this));
}
break;
case NSLeftMouseUp:
{
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this));
break;
}
case NSRightMouseDown:
{
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this));
break;
}
case NSRightMouseUp:
{
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this));
break;
}
case NSMouseMoved:
{
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this);
server.postEvent(nelEvent);
break;
}
case NSLeftMouseDragged:
{
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this);
server.postEvent(nelEvent);
break;
}
case NSRightMouseDragged:
{
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
this, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this);
server.postEvent(nelEvent);
break;
}
case NSMouseEntered:break;
case NSMouseExited:break;
case NSKeyDown:
{
// push the key press event to the event server
server.postEvent(new NLMISC::CEventKeyDown(
virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]),
[event isARepeat] == NO, this));
// if this was a text event
if(isTextKeyEvent(event))
{
ucstring ucstr;
// get the string associated with the key press event
ucstr.fromUtf8([[event characters] UTF8String]);
// push the text event to event server as well
server.postEvent(new NLMISC::CEventChar(
ucstr[0], NLMISC::noKeyButton, this));
}
break;
}
case NSKeyUp:
{
// push the key release event to the event server
server.postEvent(new NLMISC::CEventKeyUp(
virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]), this));
break;
}
case NSFlagsChanged:break;
case NSAppKitDefined:break;
case NSSystemDefined:break;
case NSApplicationDefined:break;
case NSPeriodic:break;
case NSCursorUpdate:break;
case NSScrollWheel:
{
if(fabs(event.deltaY) > 0.1)
server.postEvent(new NLMISC::CEventMouseWheel(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers,
(event.deltaY > 0), this));
break;
}
case NSTabletPoint:break;
case NSTabletProximity:break;
case NSOtherMouseDown:break;
case NSOtherMouseUp:break;
case NSOtherMouseDragged:break;
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
case NSEventTypeGesture:break;
case NSEventTypeMagnify:break;
case NSEventTypeSwipe:break;
case NSEventTypeRotate:break;
case NSEventTypeBeginGesture:break;
case NSEventTypeEndGesture:break;
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
default:
{
nlwarning("Unknown event type. dropping.");
// NSLog(@"%@", event);
break;
}
}
[NSApp sendEvent:event];
}
} }
void CCocoaEventEmitter::emulateMouseRawMode(bool enable) void CCocoaEventEmitter::emulateMouseRawMode(bool enable)
{ {
// just forwarding to our cocoa adapter _emulateRawMode = enable;
NL3D::MAC::emulateMouseRawMode(enable);
} }
} }

View file

@ -24,7 +24,11 @@ namespace NLMISC
class CCocoaEventEmitter : public IEventEmitter class CCocoaEventEmitter : public IEventEmitter
{ {
bool _emulateRawMode;
public: public:
CCocoaEventEmitter() : _emulateRawMode(false) { }
virtual void submitEvents(CEventServer & server, bool allWindows); virtual void submitEvents(CEventServer & server, bool allWindows);
virtual void emulateMouseRawMode(bool enable); virtual void emulateMouseRawMode(bool enable);
}; };

View file

@ -18,9 +18,6 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
/**
* derived to configure the NSOpenGLView
*/
@interface CocoaOpenGLView : NSOpenGLView<NSTextInputClient> @interface CocoaOpenGLView : NSOpenGLView<NSTextInputClient>
{ {
NSMutableAttributedString* characterStorage; NSMutableAttributedString* characterStorage;

View file

@ -22,7 +22,7 @@
-(id)initWithFrame:(NSRect)frame -(id)initWithFrame:(NSRect)frame
{ {
if(self = [super initWithFrame:frame]) if((self = [super initWithFrame:frame]))
{ {
characterStorage = [[NSMutableAttributedString alloc] initWithString:@""]; characterStorage = [[NSMutableAttributedString alloc] initWithString:@""];
return self; return self;
@ -38,7 +38,9 @@
-(void)keyDown:(NSEvent*)event -(void)keyDown:(NSEvent*)event
{ {
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
[[self inputContext] handleEvent:event]; [[self inputContext] handleEvent:event];
#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
} }
/******************************************************************************/ /******************************************************************************/
@ -74,7 +76,8 @@
else else
{ {
markedRange = NSMakeRange(replacementRange.location, [aString length]); markedRange = NSMakeRange(replacementRange.location, [aString length]);
[characterStorage replaceCharactersInRange:replacementRange withString:aString]; [characterStorage replaceCharactersInRange:replacementRange
withString:aString];
} }
} }
@ -102,7 +105,8 @@
if(replacementRange.location == NSNotFound) if(replacementRange.location == NSNotFound)
replacementRange = markedRange; replacementRange = markedRange;
[characterStorage replaceCharactersInRange:replacementRange withString:aString]; [characterStorage replaceCharactersInRange:replacementRange
withString:aString];
} }
-(NSUInteger)characterIndexForPoint:(NSPoint)aPoint -(NSUInteger)characterIndexForPoint:(NSPoint)aPoint

View file

@ -29,7 +29,7 @@ typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e);
namespace NLMISC { namespace NLMISC {
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY), _emulateRawMode(false), _driver(NULL) CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _emulateRawMode(false), _driver(NULL)
{ {
_im = 0; _im = 0;
_ic = 0; _ic = 0;
@ -533,8 +533,14 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
if(key == KeyNOKEY) if(key == KeyNOKEY)
key = getKeyFromKeycode(keyCode); key = getKeyFromKeycode(keyCode);
server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), _PreviousKey != key, this)); // search for key in map
_PreviousKey = key; std::map<TKey, bool>::const_iterator it = _PressedKeys.find(key);
// if key is not found or value is false, that's the first time
bool firstTime = (it == _PressedKeys.end()) || !it->second;
server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), firstTime, this));
_PressedKeys[key] = true;
// don't send a control character when deleting // don't send a control character when deleting
if (key == KeyDELETE) if (key == KeyDELETE)
@ -568,7 +574,7 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
key = getKeyFromKeycode(event.xkey.keycode); key = getKeyFromKeycode(event.xkey.keycode);
server->postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this)); server->postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this));
_PreviousKey = KeyNOKEY; _PressedKeys[key] = false;
} }
break; break;
} }

View file

@ -91,7 +91,7 @@ private:
Display* _dpy; Display* _dpy;
Window _win; Window _win;
TKey _PreviousKey; std::map<TKey, bool> _PressedKeys;
XIM _im; XIM _im;
XIC _ic; XIC _ic;
bool _emulateRawMode; bool _emulateRawMode;

View file

@ -545,6 +545,10 @@ void CTextureFar::rebuildPatch (const CVector2s texturePos, const CPatchIdent &p
// ** Fill the struct for the tile fill method for each layers // ** Fill the struct for the tile fill method for each layers
NL3D_CComputeTileFar TileFar; NL3D_CComputeTileFar TileFar;
TileFar.SrcDiffusePixels = NULL;
TileFar.SrcAdditivePixels = NULL;
TileFar.SrcDeltaX = 0;
TileFar.SrcDeltaY = 0;
TileFar.AsmMMX= false; TileFar.AsmMMX= false;
#if defined(NL_OS_WINDOWS) && !defined(NL_NO_ASM) #if defined(NL_OS_WINDOWS) && !defined(NL_NO_ASM)
TileFar.AsmMMX= NLMISC::CSystemInfo::hasMMX(); TileFar.AsmMMX= NLMISC::CSystemInfo::hasMMX();

View file

@ -1411,7 +1411,7 @@ void CZone::setTileColor(bool monochrome, float factor)
void CZone::debugBinds(FILE *f) void CZone::debugBinds(FILE *f)
{ {
fprintf(f, "*****************************\n"); fprintf(f, "*****************************\n");
fprintf(f, "ZoneId: %d. NPatchs:%zu\n", ZoneId, PatchConnects.size()); fprintf(f, "ZoneId: %d. NPatchs:%u\n", ZoneId, (uint)PatchConnects.size());
sint i; sint i;
for(i=0;i<(sint)PatchConnects.size();i++) for(i=0;i<(sint)PatchConnects.size();i++)
{ {
@ -1420,10 +1420,10 @@ void CZone::debugBinds(FILE *f)
for(sint j=0;j<4;j++) for(sint j=0;j<4;j++)
{ {
CPatchInfo::CBindInfo &bd= pc.BindEdges[j]; CPatchInfo::CBindInfo &bd= pc.BindEdges[j];
fprintf(f, " edge%d: Zone:%d. NPatchs:%d. ", j, bd.ZoneId, bd.NPatchs); fprintf(f, " edge%d: Zone:%u. NPatchs:%u. ", j, (uint)bd.ZoneId, (uint)bd.NPatchs);
for(sint k=0;k<bd.NPatchs;k++) for(sint k=0;k<bd.NPatchs;k++)
{ {
fprintf(f, "p%de%d - ", bd.Next[k], bd.Edge[k]); fprintf(f, "p%ue%u - ", (uint)bd.Next[k], (uint)bd.Edge[k]);
} }
fprintf(f, "\n"); fprintf(f, "\n");
} }
@ -1432,9 +1432,9 @@ void CZone::debugBinds(FILE *f)
fprintf(f,"Vertices :\n"); fprintf(f,"Vertices :\n");
for(i=0;i<(sint)BorderVertices.size();i++) for(i=0;i<(sint)BorderVertices.size();i++)
{ {
fprintf(f,"current : %d -> (zone %d) vertex %d\n",BorderVertices[i].CurrentVertex, fprintf(f,"current : %u -> (zone %u) vertex %u\n", (uint)BorderVertices[i].CurrentVertex,
BorderVertices[i].NeighborZoneId, (uint)BorderVertices[i].NeighborZoneId,
BorderVertices[i].NeighborVertex); (uint)BorderVertices[i].NeighborVertex);
} }
} }

View file

@ -31,13 +31,52 @@ const ucstring CI18N::_NotTranslatedValue("<Not Translated>");
bool CI18N::_LanguagesNamesLoaded = false; bool CI18N::_LanguagesNamesLoaded = false;
string CI18N::_SelectedLanguageCode; string CI18N::_SelectedLanguageCode;
CI18N::ILoadProxy *CI18N::_LoadProxy = 0; CI18N::ILoadProxy *CI18N::_LoadProxy = 0;
vector<string> CI18N::_LanguageCodes;
vector<ucstring> CI18N::_LanguageNames;
void CI18N::setLoadProxy(ILoadProxy *loadProxy) void CI18N::setLoadProxy(ILoadProxy *loadProxy)
{ {
_LoadProxy = loadProxy; _LoadProxy = loadProxy;
} }
const std::vector<ucstring> &CI18N::getLanguageNames()
{
return _LanguageNames;
}
const std::vector<std::string> &CI18N::getLanguageCodes()
{
if (!_LanguagesNamesLoaded)
{
std::vector<std::string> files;
// search all .uxt files
CPath::getFileList("uxt", files);
// if not uxt found, use default languages
if (files.empty())
{
_LanguageCodes.clear();
_LanguageCodes.push_back("en");
_LanguageCodes.push_back("fr");
_LanguageCodes.push_back("de");
_LanguageCodes.push_back("ru");
}
else
{
// add all languages found
for(uint i = 0; i < files.size(); ++i)
{
_LanguageCodes.push_back(toLower(CFile::getFilenameWithoutExtension(files[i])));
}
_LanguagesNamesLoaded = true;
}
}
return _LanguageCodes;
}
void CI18N::load (const string &languageCode, const string &fallbackLanguageCode) void CI18N::load (const string &languageCode, const string &fallbackLanguageCode)
{ {
if (_StrMapLoaded) _StrMap.clear (); if (_StrMapLoaded) _StrMap.clear ();

View file

@ -177,14 +177,14 @@ void CAudioMixerUser::initClusteredSound(NL3D::CScene *scene, float minGain, flo
} }
void CAudioMixerUser::setPriorityReserve(TSoundPriority priorityChannel, size_t reserve) void CAudioMixerUser::setPriorityReserve(TSoundPriority priorityChannel, uint reserve)
{ {
_PriorityReserve[priorityChannel] = (uint32)min(_Tracks.size(), reserve); _PriorityReserve[priorityChannel] = (uint32)min((uint)_Tracks.size(), reserve);
} }
void CAudioMixerUser::setLowWaterMark(size_t value) void CAudioMixerUser::setLowWaterMark(uint value)
{ {
_LowWaterMark = (uint32)min(_Tracks.size(), value); _LowWaterMark = (uint32)min((uint)_Tracks.size(), value);
} }

View file

@ -489,7 +489,7 @@ public:
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
{ {
std::string id = getParam(sParams, "id"); std::string id = getParam(sParams, "id");
int intId; sint intId;
if (!fromString(id, intId)) return; if (!fromString(id, intId)) return;
//nlinfo("intId = %d", intId); //nlinfo("intId = %d", intId);
CBotChatManager::getInstance()->incrementSessionID(); CBotChatManager::getInstance()->incrementSessionID();
@ -1089,7 +1089,7 @@ public:
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
{ {
std::string id = getParam(sParams, "id"); std::string id = getParam(sParams, "id");
int idInDb; sint idInDb;
if (!fromString(id, idInDb)) return; if (!fromString(id, idInDb)) return;
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();

View file

@ -287,7 +287,7 @@ class CAHChangeDMOption : public IActionHandler
virtual void execute (CCtrlBase * /* pCaller */, const string &params) virtual void execute (CCtrlBase * /* pCaller */, const string &params)
{ {
//get id of choice //get id of choice
int id; sint id;
if (!NLMISC::fromString(getParam(params, "id"), id)) if (!NLMISC::fromString(getParam(params, "id"), id))
{ {
nlwarning("Bad choice list id"); nlwarning("Bad choice list id");

View file

@ -138,8 +138,10 @@ void CGroupHTML::checkImageDownload()
// check msg // check msg
CURLMsg *msg; CURLMsg *msg;
int msgs_left; int msgs_left;
while ((msg = curl_multi_info_read(MultiCurl, &msgs_left))) { while ((msg = curl_multi_info_read(MultiCurl, &msgs_left)))
if (msg->msg == CURLMSG_DONE) { {
if (msg->msg == CURLMSG_DONE)
{
for (vector<CImageDownload>::iterator it=Curls.begin(); it<Curls.end(); it++) for (vector<CImageDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
{ {
if(msg->easy_handle == it->curl) if(msg->easy_handle == it->curl)
@ -2597,7 +2599,8 @@ static int timer_called = 0;
static int static int
timer_callback(HTTimer * const timer , timer_callback(HTTimer * const timer ,
void * const user_data , void * const user_data ,
HTEventType const event ) { HTEventType const event )
{
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
A handy timer callback which cancels the running event loop. A handy timer callback which cancels the running event loop.
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
@ -2610,7 +2613,8 @@ timer_callback(HTTimer * const timer ,
return HT_OK; return HT_OK;
} }
static void handleLibwwwEvents() { static void handleLibwwwEvents()
{
HTTimer *timer; HTTimer *timer;
timer_called = 0; timer_called = 0;
timer = HTTimer_new(NULL, &timer_callback, NULL, timer = HTTimer_new(NULL, &timer_callback, NULL,

View file

@ -110,7 +110,8 @@ struct CWebigNotificationThread : public NLMISC::IRunnable
~CWebigNotificationThread() ~CWebigNotificationThread()
{ {
if(Curl) { if(Curl)
{
curl_easy_cleanup(Curl); curl_easy_cleanup(Curl);
Curl = 0; Curl = 0;
} }
@ -189,7 +190,8 @@ struct CWebigNotificationThread : public NLMISC::IRunnable
{ {
std::string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; std::string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string s; std::string s;
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++)
{
s += chars[uint(frand(float(chars.size())))]; s += chars[uint(frand(float(chars.size())))];
} }
return s; return s;

View file

@ -733,8 +733,8 @@ void CGroupSubMenu::updateCoords ()
sint32 limY = refElmYReal + refElmHReal/2 - _GroupList->getYReal(); sint32 limY = refElmYReal + refElmHReal/2 - _GroupList->getYReal();
// Setup the arrow at the right pos // Setup the arrow at the right pos
if(_GroupList->getMaxH()>=limY && limY>=0){ if(_GroupList->getMaxH()>=limY && limY>=0)
{
pVB->setY(refElmYReal + (refElmHReal - pVB->getHReal()) / 2 - _GroupList->getYReal()); pVB->setY(refElmYReal + (refElmHReal - pVB->getHReal()) / 2 - _GroupList->getYReal());
pVB->setActive(_Lines[CBLineNb].ViewText->getActive()); pVB->setActive(_Lines[CBLineNb].ViewText->getActive());
} }

View file

@ -392,7 +392,8 @@ int CGroupTab::luaGetTabButton(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1)); CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1));
if(tab != NULL){ if(tab != NULL)
{
CLuaIHM::pushUIOnStack(ls, tab); CLuaIHM::pushUIOnStack(ls, tab);
return 1; return 1;
} }
@ -722,7 +723,8 @@ int CGroupTab::luaGetGroup(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CInterfaceGroup* group = getGroup((uint) ls.toNumber(1)); CInterfaceGroup* group = getGroup((uint) ls.toNumber(1));
if(group != NULL){ if(group != NULL)
{
CLuaIHM::pushUIOnStack(ls, group); CLuaIHM::pushUIOnStack(ls, group);
return 1; return 1;
} }

View file

@ -2633,7 +2633,8 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event)
// Hide menu (or popup menu) is ESCAPE pressed // Hide menu (or popup menu) is ESCAPE pressed
if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == KeyESCAPE ) if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == KeyESCAPE )
{ {
if(_ModalStack.size() > 0) { if(_ModalStack.size() > 0)
{
CModalWndInfo mwi = _ModalStack.back(); CModalWndInfo mwi = _ModalStack.back();
if (mwi.ModalExitKeyPushed) if (mwi.ModalExitKeyPushed)
disableModalWindow(); disableModalWindow();
@ -5571,6 +5572,7 @@ public:
{ {
ucstr = ucstring("&EMT&") + UserEntity->getDisplayName() + ucstring(" ") + ucstr; ucstr = ucstring("&EMT&") + UserEntity->getDisplayName() + ucstring(" ") + ucstr;
} }
out.serialEnum(behavToSend); out.serialEnum(behavToSend);
out.serial(ucstr); out.serial(ucstr);
NetMngr.push(out); NetMngr.push(out);

View file

@ -89,7 +89,8 @@ PRIVATE int FileCleanup (HTRequest *req, int status)
HTStream * input = HTRequest_inputStream(req); HTStream * input = HTRequest_inputStream(req);
/* Free stream with data TO Local file system */ /* Free stream with data TO Local file system */
if (input) { if (input)
{
if (status == HT_INTERRUPTED) if (status == HT_INTERRUPTED)
(*input->isa->abort)(input, NULL); (*input->isa->abort)(input, NULL);
else else
@ -100,15 +101,18 @@ PRIVATE int FileCleanup (HTRequest *req, int status)
/* /*
** Remove if we have registered a timer function as a callback ** Remove if we have registered a timer function as a callback
*/ */
if (file->timer) { if (file->timer)
{
HTTimer_delete(file->timer); HTTimer_delete(file->timer);
file->timer = NULL; file->timer = NULL;
} }
if (file) { if (file)
{
HT_FREE(file->local); HT_FREE(file->local);
HT_FREE(file); HT_FREE(file);
} }
HTNet_delete(net, status); HTNet_delete(net, status);
return YES; return YES;
} }
@ -181,7 +185,9 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
HTRequest * request = HTNet_request(net); HTRequest * request = HTNet_request(net);
HTParentAnchor * anchor = HTRequest_anchor(request); HTParentAnchor * anchor = HTRequest_anchor(request);
if (type == HTEvent_CLOSE) { /* Interrupted */ if (type == HTEvent_CLOSE)
{
/* Interrupted */
HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED, HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED,
NULL, 0, "HTLoadFile"); NULL, 0, "HTLoadFile");
FileCleanup(request, HT_INTERRUPTED); FileCleanup(request, HT_INTERRUPTED);
@ -190,20 +196,23 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
/* Now jump into the machine. We know the state from the previous run */ /* Now jump into the machine. We know the state from the previous run */
for(;;) { for(;;)
switch (file->state) { {
switch (file->state)
{
case FS_BEGIN: case FS_BEGIN:
/* We only support safe (GET, HEAD, etc) methods for the moment */ /* We only support safe (GET, HEAD, etc) methods for the moment */
if (!HTMethod_isSafe(HTRequest_method(request))) { if (!HTMethod_isSafe(HTRequest_method(request))) {
HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_ALLOWED, HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_ALLOWED,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_ERROR; file->state = FS_ERROR;
break; break;
} }
/* Check whether we have access to local disk at all */ /* Check whether we have access to local disk at all */
if (HTLib_secure()) { if (HTLib_secure())
{
HTTRACE(PROT_TRACE, "LoadFile.... No access to local file system\n"); HTTRACE(PROT_TRACE, "LoadFile.... No access to local file system\n");
file->state = FS_TRY_FTP; file->state = FS_TRY_FTP;
break; break;
@ -220,7 +229,8 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
StrAllocCopy(file->local, tmp.c_str()); StrAllocCopy(file->local, tmp.c_str());
} }
if (!file->local) { if (!file->local)
{
file->state = FS_TRY_FTP; file->state = FS_TRY_FTP;
break; break;
} }
@ -228,7 +238,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
/* Create a new host object and link it to the net object */ /* Create a new host object and link it to the net object */
{ {
HTHost * host = NULL; HTHost * host = NULL;
if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR; if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR;
HTNet_setHost(net, host); HTNet_setHost(net, host);
if (HTHost_addNet(host, net) == HT_PENDING) { if (HTHost_addNet(host, net) == HT_PENDING) {
HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n");
@ -243,7 +253,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
case FS_PENDING: case FS_PENDING:
{ {
HTHost * host = NULL; HTHost * host = NULL;
if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR; if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR;
HTNet_setHost(net, host); HTNet_setHost(net, host);
if (HTHost_addNet(host, net) == HT_PENDING) { if (HTHost_addNet(host, net) == HT_PENDING) {
HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n");
@ -265,7 +275,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
if (HT_STAT(file->local, &file->stat_info) == -1) { if (HT_STAT(file->local, &file->stat_info) == -1) {
HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local); HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local);
HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND, HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_ERROR; file->state = FS_ERROR;
break; break;
} }
@ -276,7 +286,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
file->state = FS_PARSE_DIR; file->state = FS_PARSE_DIR;
else { else {
HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_NO_DATA; file->state = FS_NO_DATA;
} }
break; break;
@ -305,7 +315,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
/* Check to see if we can edit it */ /* Check to see if we can edit it */
if (!editable && !file->stat_info.st_size) { if (!editable && !file->stat_info.st_size) {
HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_NO_DATA; file->state = FS_NO_DATA;
} else { } else {
file->state = (HTRequest_method(request)==METHOD_GET) ? file->state = (HTRequest_method(request)==METHOD_GET) ?
@ -334,7 +344,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request)) if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request))
return HT_OK; return HT_OK;
HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0,
"HTLoadFile"); (char*)"HTLoadFile");
file->state = FS_NEED_BODY; file->state = FS_NEED_BODY;
if (HTEvent_isCallbacksRegistered()) { if (HTEvent_isCallbacksRegistered()) {
@ -354,7 +364,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
return HT_OK; return HT_OK;
else { else {
HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL, HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_ERROR; /* Error or interrupt */ file->state = FS_ERROR; /* Error or interrupt */
} }
break; break;
@ -367,7 +377,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type)
file->state = FS_GOT_DATA; file->state = FS_GOT_DATA;
} else { } else {
HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN, HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN,
NULL, 0, "HTLoadFile"); NULL, 0, (char*)"HTLoadFile");
file->state = FS_ERROR; file->state = FS_ERROR;
} }
break; break;
@ -550,7 +560,7 @@ PRIVATE int HTNeLReader_abort (HTInputStream * me, HTList * /* e */)
PRIVATE const HTInputStreamClass HTNeLReader = PRIVATE const HTInputStreamClass HTNeLReader =
{ {
"SocketReader", (char*)"SocketReader",
HTNeLReader_flush, HTNeLReader_flush,
HTNeLReader_free, HTNeLReader_free,
HTNeLReader_abort, HTNeLReader_abort,

View file

@ -115,12 +115,11 @@ namespace STRING_MANAGER
{ {
try try
{ {
std::string filename(_ShardId.substr(0, _ShardId.find(":")) + ".string_cache"); _CacheFilename = std::string("save/") + _ShardId.substr(0, _ShardId.find(":")) + ".string_cache";
nlinfo("SM : Try to open the string cache : %s", filename.c_str()); nlinfo("SM : Try to open the string cache : %s", _CacheFilename.c_str());
_CacheFilename = NLMISC::CPath::lookup(filename, false, false); if (CFile::fileExists(_CacheFilename))
if (!_CacheFilename .empty())
{ {
// there is a cache file, check date reset it if needed // there is a cache file, check date reset it if needed
{ {
@ -143,7 +142,6 @@ namespace STRING_MANAGER
else else
{ {
nlinfo("SM: Creating string cache"); nlinfo("SM: Creating string cache");
_CacheFilename = std::string("data/")+filename;
// cache file don't exist, create it with the timestamp // cache file don't exist, create it with the timestamp
NLMISC::COFile file(_CacheFilename); NLMISC::COFile file(_CacheFilename);
file.serial(timestamp); file.serial(timestamp);

View file

@ -1994,7 +1994,7 @@ void CUserEntity::updatePos(const TTime &t, CEntityCL *target)
// Compute the Time Step. // Compute the Time Step.
double frameTimeRemaining = computeTimeStep(((double)t)*0.001); double frameTimeRemaining = computeTimeStep(((double)t)*0.001);
// Do not update animation if Client Light // Do not update animation if Client Light
if(ClientCfg.Light == false) if (!ClientCfg.Light)
{ {
// Attack Animation. // Attack Animation.
if(_AnimAttackOn) if(_AnimAttackOn)

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9,00"
Name="entities_game_service" Name="entities_game_service"
ProjectGUID="{739A60A6-232B-4334-B597-57C61FB93760}" ProjectGUID="{739A60A6-232B-4334-B597-57C61FB93760}"
RootNamespace="entities_game_service" RootNamespace="entities_game_service"
@ -43,6 +43,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="-Zm1000"
Optimization="4" Optimization="4"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../../../common/src;.;.." AdditionalIncludeDirectories="../../../common/src;.;.."
@ -121,6 +122,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="-Zm1000"
Optimization="4" Optimization="4"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../../../common/src;.;.." AdditionalIncludeDirectories="../../../common/src;.;.."
@ -200,6 +202,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="-Zm1000"
Optimization="3" Optimization="3"
InlineFunctionExpansion="2" InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
@ -286,6 +289,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="-Zm1000"
Optimization="3" Optimization="3"
InlineFunctionExpansion="2" InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"

View file

@ -78,40 +78,54 @@ void printCheck(const std::string &str)
void printDownload(const std::string &str) void printDownload(const std::string &str)
{ {
static uint previousLength = 0; static char spaces[80];
static const uint maxLength = 160; uint maxLength = 80;
static char spaces[maxLength];
// if "COLUMNS" environnement variable is defined, use it
if (getenv("COLUMNS"))
{
NLMISC::fromString(std::string(getenv("COLUMNS")), maxLength);
}
// only use 79 columns to not wrap
--maxLength;
// temporary modified string
std::string nstr = str;
uint length = 0; uint length = 0;
if (useUtf8) if (useUtf8)
{ {
ucstring utf8Str; ucstring ucstr;
utf8Str.fromUtf8(str); ucstr.fromUtf8(nstr);
length = (uint)utf8Str.length(); length = (uint)ucstr.length();
if (length > maxLength)
{
ucstr = ucstr.luabind_substr(length - maxLength - 3);
nstr = std::string("...") + ucstr.toUtf8();
length = maxLength;
}
} }
else else
{ {
length = (uint)str.length(); length = (uint)nstr.length();
} if (length > maxLength)
sint diff = length - previousLength;
if (diff > 0 && length < maxLength)
{ {
memset(spaces, ' ', length); nstr = std::string("...") + nstr.substr(length - maxLength - 3);
spaces[length] = '\0'; length = maxLength;
// "erase" previous line
printf("%s\r", spaces);
fflush(stdout);
} }
}
// add padding with spaces
memset(spaces, ' ', maxLength);
spaces[maxLength - length] = '\0';
// display download in purple // display download in purple
if (useEsc) if (useEsc)
{ {
printf("\033[1;35m%s\033[0m\r", str.c_str()); printf("\033[1;35m%s%s\033[0m\r", nstr.c_str(), spaces);
} }
else else
{ {
@ -120,7 +134,7 @@ void printDownload(const std::string &str)
SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY); SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
#endif #endif
printf("%s\r", str.c_str()); printf("%s%s\r", nstr.c_str(), spaces);
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
if (hStdout != INVALID_HANDLE_VALUE && hStdout) if (hStdout != INVALID_HANDLE_VALUE && hStdout)
@ -129,8 +143,6 @@ void printDownload(const std::string &str)
} }
fflush(stdout); fflush(stdout);
previousLength = length;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])