Explorar o código

Improved SDL platform support, 'ar' lib reworking

Brian Fiete %!s(int64=2) %!d(string=hai) anos
pai
achega
d20b53b187

+ 11 - 2
BeefRT/CMakeLists.txt

@@ -45,6 +45,10 @@ if (HAVE_BACKTRACE_HEADERS)
    add_definitions(-DBFP_HAS_BACKTRACE)
 endif ()
 
+if (DEFINED BF_DISABLE_FFI)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBF_DISABLE_FFI")
+endif()
+
 if (${IOS})
   include_directories(
     .
@@ -255,7 +259,7 @@ elseif (${ANDROID})
         ../BeefySysLib/platform/android/BFPlatform.cpp
         ../BeefySysLib/platform/android/AndroidCommon.cpp
     )
-else()
+elseif ((${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64") AND (NOT DEFINED BF_DISABLE_FFI))
     file(GLOB SRC_FILES_OS
         ../BeefySysLib/platform/linux/BFPlatform.cpp
         ../BeefySysLib/platform/linux/LinuxCommon.cpp
@@ -266,8 +270,13 @@ else()
         ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/src/closures.o
         ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/src/x86/ffi64.o
         ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/src/x86/unix64.o
-        ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/src/x86/ffiw64.o
+        ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/src/x86/ffiw64.o        
     )
+else()
+  file(GLOB SRC_FILES_OS
+    ../BeefySysLib/platform/linux/BFPlatform.cpp
+    ../BeefySysLib/platform/linux/LinuxCommon.cpp    
+  )
 endif()
 
 # Add library to build.

+ 14 - 2
BeefySysLib/CMakeLists.txt

@@ -106,6 +106,10 @@ if(NOT MSVC)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar")
 endif(NOT MSVC)
 
+if (DEFINED BF_ENABLE_SDL)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBF_ENABLE_SDL")
+endif()
+
 ################ Files ################
 #   --   Add files to project.   --   #
 #######################################
@@ -117,8 +121,7 @@ file(GLOB SRC_FILES
     CachedDataStream.cpp
     Common.cpp
     DataStream.cpp
-    FileStream.cpp
-    HeadlessApp.cpp
+    FileStream.cpp    
     MemStream.cpp
     ResLib.cpp
     Startup.cpp
@@ -308,11 +311,20 @@ if (${APPLE})
     file(GLOB SRC_FILES_OS
         platform/darwin/BFPlatform.cpp
         platform/darwin/DarwinCommon.cpp
+        HeadlessApp.cpp
     )
 else()
     file(GLOB SRC_FILES_OS
         platform/linux/BFPlatform.cpp
         platform/linux/LinuxCommon.cpp
+        HeadlessApp.cpp
+    )
+endif()
+
+if (DEFINED BF_ENABLE_SDL)
+    file(GLOB SRC_FILES_OS
+        platform/sdl/SdlBFApp.cpp
+        platform/sdl/GLRenderDevice.cpp
     )
 endif()
 

+ 6 - 2
BeefySysLib/platform/linux/LinuxCommon.h

@@ -28,6 +28,10 @@
 
 //#define offsetof(type, member)  __builtin_offsetof (type, member)
 
+#ifdef __arm__
+#define BF_PLATFORM_OPENGL_ES2
+#endif
+
 extern "C"
 {
 //#define FFI_BUILDING
@@ -136,7 +140,7 @@ typedef void* HMODULE;
 #if defined _DEBUG || defined BF_DEBUG_ASSERTS
 #define BF_DBG_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
 #else
-#define BF_DBG_FATAL(msg) 
+#define BF_DBG_FATAL(msg)
 #endif
 
 #define BF_NOINLINE __attribute__ ((noinline))
@@ -159,7 +163,7 @@ static char* itoa(int value, char* str, int base)
 
 inline uint32 InterlockedCompareExchange(volatile uint32* dest, uint32 exch, uint32 comp)
 {
-	return __sync_val_compare_and_swap(dest, comp, exch);    
+	return __sync_val_compare_and_swap(dest, comp, exch);
 }
 
 inline uint64 InterlockedCompareExchange64(volatile int64* dest, int64 exch, int64 comp)

+ 6 - 1
BeefySysLib/platform/linux/PlatformApp.h

@@ -1,9 +1,14 @@
 #pragma once
 
-#include "../../HeadlessApp.h"
+#include "../sdl/SdlBFApp.h"
+#include "../HeadlessApp.h"
 
 NS_BF_BEGIN;
 
+#ifdef BF_ENABLE_SDL
+typedef SdlBFApp PlatformBFApp;
+#else
 typedef HeadlessApp PlatformBFApp;
+#endif
 
 NS_BF_END;

+ 126 - 123
BeefySysLib/platform/posix/PosixCommon.cpp

@@ -59,28 +59,28 @@ struct BfpPipeInfo
 };
 
 struct BfpFile
-{	
+{
 	BfpPipeInfo* mPipeInfo;
-	int mHandle;	
+	int mHandle;
 	bool mNonBlocking;
-	bool mAllowTimeout;	
+	bool mAllowTimeout;
 	bool mIsStd;
 
 	BfpFile()
 	{
 		mPipeInfo = NULL;
-		mHandle = -1;		
+		mHandle = -1;
 		mNonBlocking = false;
-		mAllowTimeout = false;		
+		mAllowTimeout = false;
 		mIsStd = false;
 	}
 
 	BfpFile(int handle)
-	{	
+	{
 		mPipeInfo = NULL;
-		mHandle = handle;		
+		mHandle = handle;
 		mNonBlocking = false;
-		mAllowTimeout = false;		
+		mAllowTimeout = false;
 		mIsStd = false;
 	}
 
@@ -130,7 +130,7 @@ BfpTimeStamp BfpToTimeStamp(const timespec& ts)
 int gBFPlatformLastError = 0;
 
 uint32 Beefy::BFTickCount()
-{    
+{
     struct timespec now;
     if (clock_gettime(CLOCK_MONOTONIC, &now))
         return 0;
@@ -166,7 +166,7 @@ int64 Beefy::EndianSwap(int64 val)
         logType = LOG_WARNING;
     else if (hFile == (int*)STDERR_FILENO)
         logType = LOG_ERR;
-    
+
     if (logType != -1)
     {
         static std::string strOut;
@@ -176,7 +176,7 @@ int64 Beefy::EndianSwap(int64 val)
             syslog(LOG_WARNING, "%s", strOut.c_str());
     }
 #endif
-    
+
     int writeCount = (int)::write((int)(intptr)hFile, lpBuffer, nNumberOfBytesToWrite);
     if (writeCount == -1)
     {
@@ -184,7 +184,7 @@ int64 Beefy::EndianSwap(int64 val)
         lpNumberOfBytesWritten = 0;
         return false;
     }
-    
+
     *lpNumberOfBytesWritten = (uint32)writeCount;
     return true;
 }*/
@@ -195,7 +195,7 @@ int64 Beefy::GetFileTimeWrite(const StringImpl& path)
     int result = stat(path.c_str(), &statbuf);
     if (result == -1)
         return 0;
-        
+
     return statbuf.st_mtime;
 }
 
@@ -203,40 +203,40 @@ int64 Beefy::GetFileTimeWrite(const StringImpl& path)
 {
     std::wstring tzName0 = Beefy::UTF8Decode(tzname[0]);
     std::wstring tzName1 = Beefy::UTF8Decode(tzname[1]);
-    
+
     bool isDST = false;
-    
+
     time_t timeNow;
     time(&timeNow);
     tm tmNow = *gmtime(&timeNow);
     isDST = tmNow.tm_isdst;
-    
+
     struct tm checkTM;
     memset(&checkTM, 0, sizeof(tm));
     checkTM.tm_mday = 1;
     checkTM.tm_year = tmNow.tm_year;
     time_t checkTime = mktime(&checkTM);
-    
+
     time_t lastOffset = 0;
     time_t minOffset = 0;
     time_t maxOffset = 0;
-    
+
     for (int pass = 0; pass < 2; pass++)
     {
         int searchDir = 60*60*24;
         int thresholdCount = 0;
-        
+
         while (true)
         {
             checkTime += searchDir;
-            
+
             tm checkTM = *gmtime(&checkTime);
-            
+
             if (checkTM.tm_year != tmNow.tm_year)
                 break; // No DST
-            
+
             mktime(&checkTM);
-            
+
             time_t offset = checkTM.tm_gmtoff;
             if (lastOffset != offset)
             {
@@ -250,12 +250,12 @@ int64 Beefy::GetFileTimeWrite(const StringImpl& path)
                     SYSTEMTIME* sysTimeP = (offset == minOffset) ?
                     &lpTimeZoneInformation->StandardDate :
                     &lpTimeZoneInformation->DaylightDate;
-                    
+
                     if (offset == minOffset)
                         tzName0 = Beefy::UTF8Decode(checkTM.tm_zone);
                     else
                         tzName1 = Beefy::UTF8Decode(checkTM.tm_zone);
-                    
+
                     sysTimeP->wDay = 0;
                     sysTimeP->wDayOfWeek = 0;
                     sysTimeP->wYear = checkTM.tm_year + 1900;
@@ -265,7 +265,7 @@ int64 Beefy::GetFileTimeWrite(const StringImpl& path)
                     sysTimeP->wMinute = checkTM.tm_min;
                     sysTimeP->wSecond = checkTM.tm_sec;
                     sysTimeP->wMilliseconds = 0;
-                    
+
                     break;
                 }
                 else
@@ -282,13 +282,13 @@ int64 Beefy::GetFileTimeWrite(const StringImpl& path)
             }
         }
     }
-	
+
     wcsncpy(lpTimeZoneInformation->StandardName, tzName0.c_str(), 32);
     wcsncpy(lpTimeZoneInformation->DaylightName, tzName1.c_str(), 32);
-    
+
     lpTimeZoneInformation->DaylightBias = (int32)maxOffset;
     lpTimeZoneInformation->StandardBias = (int32)minOffset;
-    
+
     if (minOffset == maxOffset)
         return 0;
     return isDST ? 2 : 1;
@@ -444,14 +444,14 @@ static String gUnwindExecStr;
 static int gUnwindIdx = 0;
 
 static _Unwind_Reason_Code UnwindHandler(struct _Unwind_Context* context, void* ref)
-{       
+{
     gUnwindIdx++;
     if (gUnwindIdx < 2)
         return _URC_NO_REASON;
-    
+
     void* addr = (void*)_Unwind_GetIP(context);
 
-#if BFP_HAS_ATOS    
+#if BFP_HAS_ATOS
     gUnwindExecStr += StrFormat(" %p", addr);
 #else
     Dl_info info;
@@ -470,11 +470,11 @@ static _Unwind_Reason_Code UnwindHandler(struct _Unwind_Context* context, void*
 
 static bool FancyBacktrace()
 {
-    gUnwindExecStr += StrFormat("atos -p %d", getpid());    
+    gUnwindExecStr += StrFormat("atos -p %d", getpid());
     _Unwind_Backtrace(&UnwindHandler, NULL);
 #if BFP_HAS_ATOS
     return system(gUnwindExecStr.c_str()) == 0;
-#else    
+#else
     return true;
 #endif
 }
@@ -503,7 +503,7 @@ static void Crashed()
 
     if (!FancyBacktrace())
     {
-#ifdef BFP_HAS_EXECINFO        
+#ifdef BFP_HAS_EXECINFO
         void* array[64];
         size_t size;
         char** strings;
@@ -511,7 +511,7 @@ static void Crashed()
 
         size = backtrace(array, 64);
         strings = backtrace_symbols(array, size);
-      
+
         for (i = 0; i < size; i++)
             BFP_ERRPRINTF("%s\n", strings[i]);
 
@@ -524,7 +524,7 @@ static void Crashed()
 
 static void SigHandler(int sig)
 {
-	//printf("SigHandler paused...\n");	
+	//printf("SigHandler paused...\n");
 
     const char* sigName = NULL;
     switch (sig)
@@ -559,6 +559,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
         BfpSystem_FatalError(StrFormat("Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version).c_str(), "BFP FATAL ERROR");
     }
 
+    struct sigaction ignoreAction = { SIG_IGN };
+    sigaction(SIGPIPE, &ignoreAction, NULL);
+
     //if (ptrace(PTRACE_TRACEME, 0, 1, 0) != -1)
     {
         //ptrace(PTRACE_DETACH, 0, 1, 0);
@@ -576,7 +579,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
-{	
+{
     char exePath[PATH_MAX] = { 0 };
     int nchar = readlink("/proc/self/exe", exePath, PATH_MAX);
     if (nchar > 0)
@@ -589,8 +592,8 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
         char* cwd = getcwd(NULL, 0);
         gExePath = GetAbsPath(relPath, cwd);
         free(cwd);
-    }    
-	
+    }
+
 	for (int i = 0; i < argc; i++)
 	{
 		if (i != 0)
@@ -628,7 +631,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) // Can do a
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str)
-{    
+{
 }
 
 void BfpSystem_Shutdown()
@@ -676,7 +679,7 @@ BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedExchange32(uint32* ptr, uint
 	// __sync_lock_test_and_set only has Acquire semantics, so we need a __sync_synchronize to enforce a full barrier
 	uint32 prevVal = __sync_lock_test_and_set(ptr, val);
 	__sync_synchronize();
-	return prevVal;	
+	return prevVal;
 }
 
 BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedExchange64(uint64* ptr, uint64 val)
@@ -684,7 +687,7 @@ BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedExchange64(uint64* ptr, uint
 	// __sync_lock_test_and_set only has Acquire semantics, so we need a __sync_synchronize to enforce a full barrier
 	uint64 prevVal = __sync_lock_test_and_set(ptr, val);
 	__sync_synchronize();
-	return prevVal;	
+	return prevVal;
 }
 
 BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedExchangeAdd32(uint32* ptr, uint32 val)
@@ -730,7 +733,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetExecutablePath(char* outStr, int* inOu
             gExePath = path;
 
         // When when running with a './file', we end up with an annoying '/./' in our path
-        gExePath.Replace("/./", "/");        
+        gExePath.Replace("/./", "/");
     }
 #endif
 
@@ -758,7 +761,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetEnvironmentStrings(char* outStr, int*
 }
 
 BFP_EXPORT int BFP_CALLTYPE BfpSystem_GetNumLogicalCPUs(BfpSystemResult* outResult)
-{	
+{
 #ifdef BF_PLATFORM_ANDROID
     //TODO: Handle this
     OUTRESULT(BfpSystemResult_Ok);
@@ -789,8 +792,8 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq()
 
 BFP_EXPORT void BFP_CALLTYPE BfpSystem_CreateGUID(BfpGUID* outGuid)
 {
-// 	uuid_t guid;	
-// 	uuid_generate(guid);	
+// 	uuid_t guid;
+// 	uuid_generate(guid);
 // 	BfpGUID bfpGuid;
 // 	memcpy(&bfpGuid, guid, 16);
 // 	return bfpGuid;
@@ -879,7 +882,7 @@ BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* inTargetPath, cons
 {
     Beefy::Array<Beefy::StringView> stringViews;
 
-    //printf("BfpSpawn_Create: %s %s %x\n", inTargetPath, args, flags);    
+    //printf("BfpSpawn_Create: %s %s %x\n", inTargetPath, args, flags);
 
     char* prevWorkingDir = NULL;
 
@@ -966,7 +969,7 @@ BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* inTargetPath, cons
 		{
 			verb = targetPath.Substring(barPos + 1);
 			targetPath.RemoveToEnd(barPos);
-		}				
+		}
 	}
 
     int32 i = 0;
@@ -1097,9 +1100,9 @@ BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* inTargetPath, cons
     {
         if ((flags & BfpSpawnFlag_RedirectStdInput) != 0)
         {
-            close(stdInFD[1]);            
+            close(stdInFD[1]);
             while ((dup2(stdInFD[0], STDIN_FILENO) == -1) && (errno == EINTR)) {}
-            close(stdInFD[0]);            
+            close(stdInFD[0]);
         }
 
         if ((flags & BfpSpawnFlag_RedirectStdOutput) != 0)
@@ -1114,7 +1117,7 @@ BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* inTargetPath, cons
             while ((dup2(stdErrFD[1], STDERR_FILENO) == -1) && (errno == EINTR)) {}
             close(stdErrFD[0]);
         }
-        
+
         // If successful then this shouldn't return at all:
         int result;
 
@@ -1245,18 +1248,18 @@ struct BfpThread
     void* mThreadParam;
 #ifndef BFP_HAS_PTHREAD_TIMEDJOIN_NP
     BfpEvent* mDoneEvent;
-#endif    
+#endif
 
     pthread_t mPThread;
     int mRefCount;
-    int mPriority;   
+    int mPriority;
 
     BfpThread()
     {
     }
 
     ~BfpThread()
-    {     
+    {
     }
 
     void Release()
@@ -1280,13 +1283,13 @@ static __thread BfpThreadInfo gCurrentThreadInfo;
 void* ThreadFunc(void* threadParam)
 {
     BfpThread* thread = (BfpThread*)threadParam;
-    
+
     gCurrentThread = thread;
     thread->mStartProc(thread->mThreadParam);
 #ifndef BFP_HAS_PTHREAD_TIMEDJOIN_NP
     BfpEvent_Set(thread->mDoneEvent, true);
-#endif    
-    
+#endif
+
     thread->Release();
     return NULL;
 }
@@ -1301,9 +1304,9 @@ BFP_EXPORT BfpThread* BFP_CALLTYPE BfpThread_Create(BfpThreadStartProc startProc
     thread->mPriority = 0;
 #ifndef BFP_HAS_PTHREAD_TIMEDJOIN_NP
     thread->mDoneEvent = BfpEvent_Create(BfpEventFlag_None);
-#endif    
+#endif
 
-    BF_ASSERT(sizeof(pthread_t) <= sizeof(void*));    
+    BF_ASSERT(sizeof(pthread_t) <= sizeof(void*));
     pthread_attr_t params;
     pthread_attr_init(&params);
     pthread_attr_setstacksize(&params, stackSize);
@@ -1312,7 +1315,7 @@ BFP_EXPORT BfpThread* BFP_CALLTYPE BfpThread_Create(BfpThreadStartProc startProc
     pthread_create(&thread->mPThread, &params, ThreadFunc, (void*)thread);
 
     pthread_attr_destroy(&params);
-    
+
     if (outThreadId != NULL)
         *outThreadId = (BfpThreadId)thread->mPThread;
 
@@ -1342,7 +1345,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpThread_Release(BfpThread* thread)
         pthread_detach(thread->mPThread);
         thread->mPThreadReleased = true;
     }
-    
+
     thread->Release();
 }
 
@@ -1402,7 +1405,7 @@ BFP_EXPORT bool BFP_CALLTYPE BfpThread_WaitFor(BfpThread* thread, int waitMS)
 #else
     if (thread == NULL)
         BF_FATAL("Invalid thread with non-infinite wait");
-    return BfpEvent_WaitFor(thread->mDoneEvent, waitMS);    
+    return BfpEvent_WaitFor(thread->mDoneEvent, waitMS);
 #endif
 }
 
@@ -1463,7 +1466,7 @@ BFP_EXPORT BfpThreadInfo* BFP_CALLTYPE BfpThreadInfo_Create()
 {
 	BfpThreadInfo* threadInfo = new BfpThreadInfo();
 	threadInfo->mStackBase = 0;
-	threadInfo->mStackLimit = 0;	
+	threadInfo->mStackLimit = 0;
 	threadInfo->mPThread = pthread_self();
     return threadInfo;
 }
@@ -1516,7 +1519,7 @@ BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create()
 {
     BfpCritSect* critSect = new BfpCritSect();
 
-    pthread_mutexattr_t     attributes;        
+    pthread_mutexattr_t     attributes;
     pthread_mutexattr_init(&attributes);
     pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
     pthread_mutex_init(&critSect->mPMutex, &attributes);
@@ -1547,12 +1550,12 @@ BFP_EXPORT bool BFP_CALLTYPE BfpCritSect_TryEnter(BfpCritSect* critSect, int wai
     {
         return pthread_mutex_trylock(&critSect->mPMutex) == 0;
     }
-    
+
     uint32 start = Beefy::BFTickCount();
     while ((int)(Beefy::BFTickCount() - start) < waitMS)
     {
         if (pthread_mutex_trylock(&critSect->mPMutex) == 0)
-        {                
+        {
             return true;
         }
     }
@@ -1646,22 +1649,22 @@ BFP_EXPORT bool BFP_CALLTYPE BfpEvent_WaitFor(BfpEvent* event, int waitMS)
             clock_gettime(CLOCK_REALTIME, &ts);
             ts.tv_sec += waitMS / 1000;
             ts.tv_nsec += (waitMS % 1000) * 1000000;
-            
+
             result = pthread_cond_timedwait(&event->mCondVariable, &event->mMutex, &ts);
-            
+
             if (waitMS == (uint32)-1)
                 BF_ASSERT(result == 0);
-            
+
             if (result != 0)
             {
-                // Timeout                
+                // Timeout
                 pthread_mutex_unlock(&event->mMutex);
                 return false;
             }
         }
     }
     if (!event->mManualReset)
-        event->mSet = false;        
+        event->mSet = false;
     pthread_mutex_unlock(&event->mMutex);
     return true;
 }
@@ -1669,17 +1672,17 @@ BFP_EXPORT bool BFP_CALLTYPE BfpEvent_WaitFor(BfpEvent* event, int waitMS)
 BFP_EXPORT BfpDynLib* BFP_CALLTYPE BfpDynLib_Load(const char* fileName)
 {
     BfpDynLib* mod = NULL;
-    
+
     static const char* prefixes[] = {NULL, "lib"};
     static const char* suffixes[] = {NULL, ".so", ".dylib"};
-    
+
     for (int prefixIdx = 0; prefixIdx < sizeof(prefixes)/sizeof(prefixes[0]); prefixIdx++)
     {
         for (int suffixIdx = 0; suffixIdx < sizeof(suffixes)/sizeof(suffixes[0]); suffixIdx++)
         {
             const char* prefix = prefixes[prefixIdx];
             const char* suffix = suffixes[suffixIdx];
-            
+
             Beefy::String checkName = fileName;
             if (prefix != NULL)
                 checkName = Beefy::String(prefix) + checkName;
@@ -1690,13 +1693,13 @@ BFP_EXPORT BfpDynLib* BFP_CALLTYPE BfpDynLib_Load(const char* fileName)
                     checkName.RemoveToEnd(dotPos);
                 checkName += suffix;
             }
-            
+
             mod = (BfpDynLib*)dlopen(checkName.c_str(), RTLD_LAZY);
             if (mod != NULL)
                 return mod;
         }
     }
-    
+
      /*mod = (BfpDynLib*)dlopen("/var/Beef/qt-build/Debug/bin/libIDEHelper.so", RTLD_LAZY);;
      if (mod == NULL)
      {
@@ -1725,16 +1728,16 @@ BFP_EXPORT void BFP_CALLTYPE BfpDynLib_GetFilePath(BfpDynLib* lib, char* outPath
         return;
     }
 
-    path = linkMap->l_name;    
+    path = linkMap->l_name;
 #else
-    Dl_info info;    
+    Dl_info info;
     if (dladdr((void*)lib, &info) == 0)
     {
         OUTRESULT(BfpLibResult_UnknownError);
         return;
     }
 
-    path = info.dli_fname;    
+    path = info.dli_fname;
 #endif
 
     TryStringOut(path, outPath, inOutPathSize, (BfpResult*)outResult);
@@ -1762,7 +1765,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_Create(const char* path, BfpFileResult
             break;
         }
     }
-    else    
+    else
         OUTRESULT(BfpFileResult_Ok);
 }
 
@@ -1785,7 +1788,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_Delete(const char* path, BfpFileResult
             break;
         }
     }
-    else    
+    else
         OUTRESULT(BfpFileResult_Ok);
 }
 
@@ -1798,10 +1801,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetCurrent(char* outPath, int* inOutPa
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpDirectory_SetCurrent(const char* path, BfpFileResult* outResult)
-{    
+{
     if (chdir(path) != 0)
-        OUTRESULT(BfpFileResult_NotFound);  
-    else    
+        OUTRESULT(BfpFileResult_NotFound);
+    else
         OUTRESULT(BfpFileResult_Ok);
 }
 
@@ -1811,7 +1814,7 @@ BFP_EXPORT bool BFP_CALLTYPE BfpDirectory_Exists(const char* path)
     int result = stat(path, &statbuf);
     if (result != 0)
         return false;
-    return S_ISDIR(statbuf.st_mode);   
+    return S_ISDIR(statbuf.st_mode);
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sysDirKind, char* outPath, int* inOutPathLen, BfpFileResult* outResult)
@@ -1821,7 +1824,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sy
 }
 
 BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* inName, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult)
-{    
+{
 	auto _DoCreate = [&](String& name)
 	{
 		int flags = 0;
@@ -1903,14 +1906,14 @@ BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* inName, BfpFileCreat
 		}
         return result;
 	};
-    
+
     // POSIX doesn't need the OpenAlways kind.
     if (createKind == BfpFileCreateKind_OpenAlways)
         createKind = BfpFileCreateKind_CreateAlways;
 
 	BfpFile* bfpFile = NULL;
 
-	int result;	
+	int result;
 	if ((createFlags & BfpFileCreateFlag_Pipe) != 0)
 	{
 		int readHandle;
@@ -1938,11 +1941,11 @@ BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* inName, BfpFileCreat
 			OUTRESULT(BfpFileResult_Ok);
 
 			BfpPipeInfo* pipeInfo = new BfpPipeInfo();
-			pipeInfo->mWriteHandle = writeHandle;		
+			pipeInfo->mWriteHandle = writeHandle;
 			if (isCreating)
 				pipeInfo->mPipePath = name;
 			bfpFile = new BfpFile();
-			bfpFile->mHandle = readHandle;			
+			bfpFile->mHandle = readHandle;
 			bfpFile->mPipeInfo = pipeInfo;
 		}
 		else
@@ -1967,11 +1970,11 @@ BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* inName, BfpFileCreat
 		bfpFile->mHandle = handle;
 	}
 
-	OUTRESULT(BfpFileResult_Ok);	
+	OUTRESULT(BfpFileResult_Ok);
 	if ((createFlags & (BfpFileCreateFlag_NonBlocking | BfpFileCreateFlag_AllowTimeouts)) != 0)
         bfpFile->mNonBlocking = true;
-	if ((createFlags & BfpFileCreateFlag_AllowTimeouts) != 0)       
-        bfpFile->mAllowTimeout = true;	
+	if ((createFlags & BfpFileCreateFlag_AllowTimeouts) != 0)
+        bfpFile->mAllowTimeout = true;
     return bfpFile;
 }
 
@@ -2009,21 +2012,21 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_GetSystemHandle(BfpFile* file)
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpFile_Release(BfpFile* file)
-{	
+{
 	if ((file->mHandle != -1) && (!file->mIsStd))
 		close(file->mHandle);
 	if (file->mPipeInfo != NULL)
 	{
 		if (file->mPipeInfo->mWriteHandle != -1)
 			close(file->mPipeInfo->mWriteHandle);
-		
+
 		if (!file->mPipeInfo->mPipePath.IsEmpty())
 		{
 			int worked = remove(file->mPipeInfo->mPipePath.c_str());
 			remove((file->mPipeInfo->mPipePath + "__").c_str());
 			//printf("Removing %s %d\n", file->mPipeInfo->mPipePath.c_str(), worked);
 		}
-	}	
+	}
 
 	delete file;
 }
@@ -2047,7 +2050,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_Close(BfpFile* file, BfpFileResult* outResu
 }
 
 BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Write(BfpFile* file, const void* buffer, intptr size, int timeoutMS, BfpFileResult* outResult)
-{   
+{
 	int writeHandle = file->mHandle;
 	if (file->mPipeInfo != NULL)
 		writeHandle = file->mPipeInfo->mWriteHandle;
@@ -2071,9 +2074,9 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
 {
 	if (file->mNonBlocking)
 	{
-		if (!file->mAllowTimeout)		
-			timeoutMS = -1;		
-		
+		if (!file->mAllowTimeout)
+			timeoutMS = -1;
+
 		timeval timeout;
 		timeout.tv_sec = 0;
 		timeout.tv_usec = timeoutMS * 1000;
@@ -2119,7 +2122,7 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpFile_GetFileSize(BfpFile* file)
 BFP_EXPORT int64 BFP_CALLTYPE BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind)
 {
     int whence;
-    if (seekKind == BfpFileSeekKind_Absolute)        
+    if (seekKind == BfpFileSeekKind_Absolute)
         whence = SEEK_SET;
     else if (seekKind == BfpFileSeekKind_Relative)
         whence = SEEK_CUR;
@@ -2144,7 +2147,7 @@ BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFile_GetTime_LastWrite(const char* path)
     struct stat statbuf = {0};
     int result = stat(path, &statbuf);
     if (result != 0)
-        return 0;    
+        return 0;
     return statbuf.st_mtime;
 }
 
@@ -2163,7 +2166,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_Copy(const char* oldPath, const char* newPa
 {
     int fd_to, fd_from;
     char buf[4096];
-    ssize_t nread;  
+    ssize_t nread;
 
     fd_from = open(oldPath, O_RDONLY);
     if (fd_from < 0)
@@ -2228,7 +2231,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_Copy(const char* oldPath, const char* newPa
 out_error:
     close(fd_from);
     if (fd_to >= 0)
-        close(fd_to);   
+        close(fd_to);
 }
 
 BFP_EXPORT void BFP_CALLTYPE BfpFile_Rename(const char* oldPath, const char* newPath, BfpFileResult* outResult)
@@ -2250,7 +2253,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_Delete(const char* path, BfpFileResult* out
             break;
         }
     }
-    else    
+    else
         OUTRESULT(BfpFileResult_Ok);
 }
 
@@ -2327,7 +2330,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_GetActualPath(const char* inPath, char* out
 
 struct BfpFindFileData
 {
-    BfpFindFileFlags mFlags;    
+    BfpFindFileFlags mFlags;
     DIR* mDirStruct;
     Beefy::String mWildcard;
     Beefy::String mDirPath;
@@ -2341,7 +2344,7 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha
 {
     Beefy::String findStr = path;
     Beefy::String wildcard;
-    
+
     int lastSlashPos = std::max((int)findStr.LastIndexOf('/'), (int)findStr.LastIndexOf('\\'));
     if (lastSlashPos != -1)
     {
@@ -2350,7 +2353,7 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha
     }
     if (wildcard == "*.*")
         wildcard = "*";
-    
+
     DIR* dir = opendir(findStr.c_str());
     if (dir == NULL)
     {
@@ -2361,18 +2364,18 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha
     BfpFindFileData* findData = new BfpFindFileData();
     findData->mFlags = flags;
     findData->mDirPath = findStr;
-    findData->mDirStruct = dir;    
+    findData->mDirStruct = dir;
     findData->mWildcard = wildcard;
     findData->mHasStat = false;
     findData->mDirEnt = NULL;
-        
+
     if (!BfpFindFileData_FindNextFile(findData))
-    {            
+    {
         OUTRESULT(BfpFileResult_NoResults);
         closedir(findData->mDirStruct);
         delete findData;
         return NULL;
-    }    
+    }
 
     OUTRESULT(BfpFileResult_Ok);
     return findData;
@@ -2384,7 +2387,7 @@ static void GetStat(BfpFindFileData* findData)
         return;
 
     Beefy::String filePath = findData->mDirPath + "/" + findData->mDirEnt->d_name;
-    
+
     findData->mStat = { 0 };
     int result = stat(filePath.c_str(), &findData->mStat);
 
@@ -2404,11 +2407,11 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
 
     if (isDir)
     {
-        if ((findData->mFlags & BfpFindFileFlag_Directories) == 0)          
+        if ((findData->mFlags & BfpFindFileFlag_Directories) == 0)
+            return false;
+
+        if ((strcmp(findData->mDirEnt->d_name, ".") == 0) || (strcmp(findData->mDirEnt->d_name, "..") == 0))
             return false;
-        
-        if ((strcmp(findData->mDirEnt->d_name, ".") == 0) || (strcmp(findData->mDirEnt->d_name, "..") == 0))        
-            return false;        
     }
     else
     {
@@ -2423,10 +2426,10 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
 }
 
 BFP_EXPORT bool BFP_CALLTYPE BfpFindFileData_FindNextFile(BfpFindFileData* findData)
-{    
+{
     while (true)
     {
-        findData->mHasStat = false;        
+        findData->mHasStat = false;
         findData->mDirEnt = readdir(findData->mDirStruct);
         if (findData->mDirEnt == NULL)
             return false;
@@ -2446,8 +2449,8 @@ BFP_EXPORT void BFP_CALLTYPE BfpFindFileData_GetFileName(BfpFindFileData* findDa
 
 BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData)
 {
-    GetStat(findData);    
-#ifdef BF_PLATFORM_DARWIN    
+    GetStat(findData);
+#ifdef BF_PLATFORM_DARWIN
     return BfpToTimeStamp(findData->mStat.st_mtimespec);
 #else
     return BfpToTimeStamp(findData->mStat.st_mtim);
@@ -2457,7 +2460,7 @@ BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_LastWrite(BfpFindFi
 BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_Created(BfpFindFileData* findData)
 {
     GetStat(findData);
-#ifdef BF_PLATFORM_DARWIN        
+#ifdef BF_PLATFORM_DARWIN
     return BfpToTimeStamp(findData->mStat.st_ctimespec);
 #else
     return BfpToTimeStamp(findData->mStat.st_ctim);

+ 3 - 58
BeefySysLib/platform/sdl/GLRenderDevice.cpp

@@ -7,7 +7,9 @@
 
 USING_NS_BF;
 
+#ifndef NOT_IMPL
 #define NOT_IMPL throw "Not implemented"
+#endif
 
 #pragma comment(lib, "SDL2.lib")
 
@@ -138,7 +140,7 @@ static void CreateOrthographicOffCenter(float left, float right, float bottom, f
 
 GLShaderParam::GLShaderParam()
 {
-	mGLVariable = NULL;
+	mGLVariable = 0;
 }
 
 GLShaderParam::~GLShaderParam()
@@ -229,9 +231,6 @@ GLDrawBatch::GLDrawBatch() : DrawBatch()
 
 GLDrawBatch::~GLDrawBatch()
 {
-	delete mVertices;
-	delete mIndices;
-	//mGLBuffer->Release();
 }
 
 extern int gBFDrawBatchCount;
@@ -311,60 +310,6 @@ void GLDrawLayer::SetShaderConstantData(int usageIdx, int slotIdx, void* constDa
 {
 }
 
-
-/*void GLDrawLayer::FreeBatch(DrawBatch* drawBatch)
-{
-	//delete drawBatch;
-
-	GLDrawBatch* batch = (GLDrawBatch*) drawBatch;
-	batch->Clear();
-
-	//GLDrawBatchVector* pool = &((GLRenderDevice*) gBFApp->mRenderDevice)->mDrawBatchPool;
-	//pool->push_back(batch);
-    GLRenderDevice* glRenderDevice = (GLRenderDevice*)gBFApp->mRenderDevice;
-    drawBatch->mNext = glRenderDevice->mFreeBatchHead;
-    glRenderDevice->mFreeBatchHead = batch;
-}*/
-
-//void GLRenderDevice::PhysSetShader(Shader* shader)
-//{
-//	GLRenderDevice* aRenderDevice = (GLRenderDevice*) gBFApp->mRenderDevice;
-//
-//	//TODO: Cache more
-//
-//	GLShader* glShader = (GLShader*)shader;
-//
-//	GLfloat matrix[4][4];
-//	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
-//	GLint matrixLoc = bf_glGetUniformLocation(glShader->mGLProgram, "screenMatrix");
-//	//BF_ASSERT(matrixLoc >= 0);
-//	if (matrixLoc >= 0)
-//        bf_glUniformMatrix4fv(matrixLoc, 1, false, (float*)matrix);
-//
-//	/*mPhysShaderPass = shaderPass;
-//	GLShaderPass* dXShaderPass = (GLShaderPass*) mPhysShaderPass;
-//	mGLDevice->IASetInputLayout(dXShaderPass->mGLLayout);
-//
-//	if (mCurShader->mLastResizeCount != mCurRenderTarget->mResizeNum)
-//	{
-//		ShaderParam* shaderParam = mCurShader->GetShaderParam(L"WindowSize");
-//		if (shaderParam != NULL)
-//		{
-//			shaderParam->SetFloat2((float) mCurRenderTarget->mWidth, (float) mCurRenderTarget->mHeight);
-//		}
-//
-//		mCurShader->mLastResizeCount = mCurRenderTarget->mResizeNum;
-//	}
-//
-//	GLCHECK(dXShaderPass->mGLEffectPass->Apply(0));*/
-//
-//	/*GLfloat matrix[4][4];
-//	CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix);
-//	GLint uniformLocation = bf_glGetUniformLocation(((GLShader*)shaderPass->mTechnique->mShader)->mGLProgram, "screenMatrix");
-//	if (uniformLocation != -1)
-//		bf_glUniformMatrix4fv(uniformLocation, 1, false, (GLfloat*)matrix);*/
-//}
-
 void GLRenderDevice::PhysSetRenderWindow(RenderWindow* renderWindow)
 {
 	mCurRenderTarget = renderWindow;

+ 0 - 13
BeefySysLib/platform/sdl/GLRenderDevice.h

@@ -117,9 +117,6 @@ class GLRenderWindow : public RenderWindow
 public:
 	SDL_Window*				mSDLWindow;
 	GLRenderDevice*			mRenderDevice;
-	//IGLGISwapChain*			mGLSwapChain;
-	//IGL10Texture2D*		mGLBackBuffer;
-	//IGL10RenderTargetView*	mGLRenderTargetView;
 	bool					mResizePending;
 	int						mPendingWidth;
 	int						mPendingHeight;
@@ -138,18 +135,9 @@ public:
 	void					CopyBitsTo(uint32* dest, int width, int height);
 };
 
-typedef std::vector<GLDrawBatch*> GLDrawBatchVector;
-
 class GLRenderDevice : public RenderDevice
 {
 public:
-	//IGLGIFactory*			mGLGIFactory;
-	//IGL10Device*			mGLDevice;
-	//IGL10BlendState*		mGLNormalBlendState;
-	//IGL10BlendState*		mGLAdditiveBlendState;
-	//IGL10RasterizerState*	mGLRasterizerStateClipped;
-	//IGL10RasterizerState*	mGLRasterizerStateUnclipped;
-
 	GLuint					mGLVAO;
 	GLuint					mGLVertexBuffer;
 	GLuint					mGLIndexBuffer;
@@ -158,7 +146,6 @@ public:
 
 	bool					mHasVSync;
 
-	GLDrawBatchVector		mDrawBatchPool;
     GLDrawBatch*            mFreeBatchHead;
 
 public:

+ 10 - 2
BeefySysLib/platform/sdl/SdlBFApp.cpp

@@ -24,13 +24,21 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
 
 	mSDLWindow = SDL_CreateWindow(title.c_str(), x, y, width, height, sdlWindowFlags);
 
+#ifndef BF_PLATFORM_OPENGL_ES2
 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+#endif
 
 	if (!SDL_GL_CreateContext(mSDLWindow))
 	{
-		BF_FATAL(StrFormat("Unable to create OpenGL context: %s", SDL_GetError()).c_str());
+		BF_FATAL(StrFormat(
+#ifdef BF_PLATFORM_OPENGL_ES2
+			"Unable to create OpenGLES context: %s"
+#else
+			"Unable to create OpenGL context: %s"
+#endif
+			, SDL_GetError()).c_str());
 		SDL_Quit();
 		exit(2);
 	}
@@ -324,7 +332,7 @@ void SdlBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis
 
 uint32 SdlBFApp::GetClipboardFormat(const StringImpl& format)
 {
-	return CF_TEXT;
+	return /*CF_TEXT*/1;
 }
 
 void* SdlBFApp::GetClipboardData(const StringImpl& format, int* size)

+ 77 - 77
BeefySysLib/platform/win/CrashCatcher.cpp

@@ -164,7 +164,7 @@ static HWND gNoButtonWindow = NULL;
 static bool gExiting = false;
 
 static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{	
+{
 	switch (uMsg)
 	{
 	case WM_COMMAND:
@@ -189,21 +189,21 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			if (::GetSaveFileNameW(&openFileName))
 			{
 				CreateMiniDump(CrashCatcher::Get()->mExceptionPointers, UTF8Encode(fileName));
-			}			
+			}
 		}
 		else if (hwndCtl == gNoButtonWindow)
 		{
 			if (!CrashCatcher::Get()->mRelaunchCmd.IsEmpty())
 			{
 				SHELLEXECUTEINFOW shellExecuteInfo = { 0 };
-				shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW);				
-				shellExecuteInfo.nShow = SW_SHOWNORMAL;	
+				shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
+				shellExecuteInfo.nShow = SW_SHOWNORMAL;
 
 				String cmd = CrashCatcher::Get()->mRelaunchCmd;
-				String file;				
+				String file;
 
 				bool nameQuoted = cmd[0] == '\"';
-				
+
 				int i;
 				for (i = (nameQuoted ? 1 : 0); cmd[i] != 0; i++)
 				{
@@ -224,11 +224,11 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 					useParamsPtr++;
 
 				auto fileW = UTF8Decode(file);
-				shellExecuteInfo.lpFile = fileW.c_str();				
+				shellExecuteInfo.lpFile = fileW.c_str();
 				auto paramsW = UTF8Decode(useParamsPtr);
 				shellExecuteInfo.lpParameters = paramsW.c_str();
-				
-				BOOL success = ::ShellExecuteExW(&shellExecuteInfo);					
+
+				BOOL success = ::ShellExecuteExW(&shellExecuteInfo);
 			}
 
 			CrashCatcher::Get()->mCloseRequested = true;
@@ -261,7 +261,7 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
 	GetVersionEx(&aVersionInfo);
 
 	// Setting fonts on 98 causes weirdo crash things in GDI upon the second crash.
-	//  That's no good.	
+	//  That's no good.
 	gUseDefaultFonts = aVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT;
 
 	int aHeight = -MulDiv(8, 96, 72);
@@ -302,7 +302,7 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
 
 	RECT windowRect = aRect;
 	BOOL worked = AdjustWindowRect(&windowRect, aWindowStyle, FALSE);
-	
+
 	HWND aHWnd = ::CreateWindowExW(0, L"SEHWindow", L"Fatal Error!",
 		aWindowStyle,
 		64, 64,
@@ -332,7 +332,7 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
 		DEFAULT_PITCH | FF_DONTCARE, "Arial");
 
 	if (!gUseDefaultFonts)
-		SendMessage(aLabelWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);	
+		SendMessage(aLabelWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);
 
 	HWND anEditWindow = CreateWindowA("EDIT", errorText.c_str(),
 		WS_VISIBLE | WS_CHILD | ES_MULTILINE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_READONLY,
@@ -403,7 +403,7 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
 
 		aCurX += aButtonWidth + 8;
 	}
-	
+
 	gNoButtonWindow = CreateWindowA("BUTTON", relaunchCmd.IsEmpty() ? "Close Now" : "Relaunch",
 		WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_PUSHBUTTON,
 		aCurX, aRect.bottom - 24 - 8,
@@ -437,7 +437,7 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
 static bool GetLogicalAddress(void* addr, char* szModule, DWORD len, uintptr& section, uintptr& offset)
 {
 	MEMORY_BASIC_INFORMATION mbi;
-	
+
 	if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
 		return false;
 
@@ -495,7 +495,7 @@ static BOOL CALLBACK MyMiniDumpCallback(
 	BOOL bRet = FALSE;
 
 
-	// Check parameters 
+	// Check parameters
 
 	if (pInput == 0)
 		return FALSE;
@@ -504,29 +504,29 @@ static BOOL CALLBACK MyMiniDumpCallback(
 		return FALSE;
 
 
-	// Process the callbacks 
+	// Process the callbacks
 
 	switch (pInput->CallbackType)
 	{
 		case IncludeModuleCallback:
 		{
-			// Include the module into the dump 
+			// Include the module into the dump
 			bRet = TRUE;
 		}
 		break;
 	case IncludeThreadCallback:
 		{
-			// Include the thread into the dump 
+			// Include the thread into the dump
 			bRet = TRUE;
 		}
 		break;
 	case ModuleCallback:
 		{
-			// Does the module have ModuleReferencedByMemory flag set ? 
+			// Does the module have ModuleReferencedByMemory flag set ?
 
 			if (!(pOutput->ModuleWriteFlags & ModuleReferencedByMemory))
 			{
-				// No, it does not - exclude it 
+				// No, it does not - exclude it
 
 				//wprintf(L"Excluding module: %s \n", pInput->Module.FullPath);
 
@@ -538,19 +538,19 @@ static BOOL CALLBACK MyMiniDumpCallback(
 		break;
 	case ThreadCallback:
 		{
-			// Include all thread information into the minidump 
+			// Include all thread information into the minidump
 			bRet = TRUE;
 		}
 		break;
 	case ThreadExCallback:
 		{
-			// Include this information 
+			// Include this information
 			bRet = TRUE;
 		}
 		break;
 	case MemoryCallback:
 		{
-			// We do not include any information here -> return FALSE 
+			// We do not include any information here -> return FALSE
 			bRet = FALSE;
 		}
 		break;
@@ -564,7 +564,7 @@ static BOOL CALLBACK MyMiniDumpCallback(
 
 static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath)
 {
-	// Open the file 
+	// Open the file
 	typedef BOOL(*PDUMPFN)(
 		HANDLE hProcess,
 		DWORD ProcessId,
@@ -587,7 +587,7 @@ static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath)
 	if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
 		return false;
 
-	// Create the minidump 
+	// Create the minidump
 
 	MINIDUMP_EXCEPTION_INFORMATION mdei;
 
@@ -615,9 +615,9 @@ static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath)
 
 	BOOL rv = (*pFn)(GetCurrentProcess(), GetCurrentProcessId(),
 		hFile, mdt, (pep != 0) ? &mdei : 0, &user_stream_info, &mci);
-				
-	// Close the file 
-	CloseHandle(hFile);	
+
+	// Close the file
+	CloseHandle(hFile);
 	return true;
 }
 
@@ -638,7 +638,7 @@ static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
 	sf.AddrStack.Mode = AddrModeFlat;
 	sf.AddrFrame.Offset = theContext->Rbp;
 	sf.AddrFrame.Mode = AddrModeFlat;
-#else	
+#else
 	sf.AddrPC.Offset = theContext->Eip;
 	sf.AddrPC.Mode = AddrModeFlat;
 	sf.AddrStack.Offset = theContext->Esp;
@@ -676,7 +676,7 @@ static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
 			//aDebugDump += aBuffer;
 			break;
 		}
-		
+
 		if ((aLevelCount > 0) && ((sf.AddrFrame.Offset == 0) || (sf.AddrPC.Offset == 0)))
 			break;
 
@@ -693,7 +693,7 @@ static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
 
 		// Displacement of the input address, relative to the start of the symbol
 #ifdef BF64
-		DWORD64 symDisplacement = 0;  
+		DWORD64 symDisplacement = 0;
 #else
 		DWORD symDisplacement = 0;
 #endif
@@ -706,7 +706,7 @@ static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
 
 		GetLogicalAddress((PVOID)sf.AddrPC.Offset, szModule, sizeof(szModule), section, offset);
 
-		bool forceFail = false;		
+		bool forceFail = false;
 		if ((gSymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol)) && (!forceFail))
 		{
 			char aUDName[256];
@@ -735,26 +735,26 @@ static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
 #else
 			IMAGEHLP_LINE lineInfo = { 0 };
 			lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE);
-#endif			
+#endif
 			if (gSymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &displacement, &lineInfo))
-			{				
+			{
 				aDebugDump += StrFormat("    at %s:%d\r\n", lineInfo.FileName, lineInfo.LineNumber);
 			}
 		}
 		else // No symbol found.  Print out the logical address instead.
 		{
-			
+
 
 // 			ModuleInfo* moduleInfo = NULL;
 // 			if (moduleInfoMap.TryAdd(szModule, NULL, &moduleInfo))
 // 			{
-// 
+//
 // 			}
 
 			aDebugDump += StrFormat("%@ %@ %04X:%@ %s\r\n", sf.AddrFrame.Offset, sf.AddrPC.Offset, section, offset, GetFileName(szModule).c_str());
-		}		
+		}
 
-		aDebugDump += StrFormat("    Params: %@ %@ %@ %@\r\n", sf.Params[0], sf.Params[1], sf.Params[2], sf.Params[3]);		
+		aDebugDump += StrFormat("    Params: %@ %@ %@ %@\r\n", sf.Params[0], sf.Params[1], sf.Params[2], sf.Params[3]);
 		aDebugDump += "\r\n";
 
 		aLevelCount++;
@@ -792,7 +792,7 @@ static String GetVersion(const StringImpl& fileName)
 			nFixedLength = 0;
 			LPSTR       lpVersion = NULL;
 			void*       lpFixedPointer;
-			TRANSARRAY* lpTransArray;			
+			TRANSARRAY* lpTransArray;
 
 			GetFileVersionInfoA(fileName.c_str(),
 				dwReserved,
@@ -850,7 +850,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	crashCatcher->mCrashed = true;
 
 	HMODULE hMod = GetModuleHandleA(NULL);
-		
+
 	PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
 	PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
 	bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
@@ -858,7 +858,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 		isCLI = false;
 	else if ((CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_Console) || (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_PrintOnly))
 		isCLI = true;
-	
+
 	bool hasImageHelp = LoadImageHelp();
 
 	String anErrorTitle;
@@ -869,7 +869,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 
 	if (isCLI)
 		aDebugDump += "**** FATAL APPLICATION ERROR ****\n";
-		
+
 	for (auto func : CrashCatcher::Get()->mCrashInfoFuncs)
 		func();
 
@@ -878,10 +878,10 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	crashInfo += "\nExecutable: ";
 	crashInfo += path;
 	crashInfo += "\r\n";
-	crashInfo += GetVersion(path);	
+	crashInfo += GetVersion(path);
 
 	aDebugDump.Append(crashInfo);
-	
+
 	for (int i = 0; i < (int)aDebugDump.length(); i++)
 	{
 		char c = aDebugDump[i];
@@ -898,7 +898,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	}
 
 // 	aDebugDump.Replace("\n", "\r\n");
-// 	aDebugDump.Replace("\t", "  ");		
+// 	aDebugDump.Replace("\t", "  ");
 
 	if (!aDebugDump.IsEmpty())
 	{
@@ -907,7 +907,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 
 		aDebugDump += "\r\n";
 	}
-		
+
 	WCHAR exeFilePathW[MAX_PATH];
 	exeFilePathW[0] = 0;
 	::GetModuleFileNameW(hMod, exeFilePathW, MAX_PATH);
@@ -934,7 +934,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	}
 
 	///////////////////////////
-	// first name the exception	
+	// first name the exception
 	char  *szName = NULL;
 	for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
 	{
@@ -962,16 +962,16 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	// Get logical address of the module where exception occurs
 	uintptr section, offset;
 	GetLogicalAddress(lpEP->ExceptionRecord->ExceptionAddress, aBuffer, sizeof(aBuffer), section, offset);
-	
 
-	aDebugDump += StrFormat("Logical Address: %04X:%@\r\n", section, offset);	
+
+	aDebugDump += StrFormat("Logical Address: %04X:%@\r\n", section, offset);
 
 	aDebugDump += "\r\n";
 
 	anErrorTitle = StrFormat("Exception at %04X:%08X", section, offset);
 
 	String aWalkString;
-	
+
 	if (hasImageHelp)
 		aWalkString = ImageHelpWalk(lpEP->ContextRecord, 0);
 
@@ -992,10 +992,10 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 	aDebugDump += StrFormat("Flags:%@\r\n", lpEP->ContextRecord->EFlags);
 #else
 	aDebugDump += StrFormat("EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X\r\n",
-		lpEP->ContextRecord->Eax, lpEP->ContextRecord->Ebx, lpEP->ContextRecord->Ecx, lpEP->ContextRecord->Edx, lpEP->ContextRecord->Esi, lpEP->ContextRecord->Edi);	
-	aDebugDump += StrFormat("EIP:%08X ESP:%08X  EBP:%08X\r\n", lpEP->ContextRecord->Eip, lpEP->ContextRecord->Esp, lpEP->ContextRecord->Ebp);	
-	aDebugDump += StrFormat("CS:%04X SS:%04X DS:%04X ES:%04X FS:%04X GS:%04X\r\n", lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs, lpEP->ContextRecord->SegDs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegGs);	
-	aDebugDump += StrFormat("Flags:%08X\r\n", lpEP->ContextRecord->EFlags);	
+		lpEP->ContextRecord->Eax, lpEP->ContextRecord->Ebx, lpEP->ContextRecord->Ecx, lpEP->ContextRecord->Edx, lpEP->ContextRecord->Esi, lpEP->ContextRecord->Edi);
+	aDebugDump += StrFormat("EIP:%08X ESP:%08X  EBP:%08X\r\n", lpEP->ContextRecord->Eip, lpEP->ContextRecord->Esp, lpEP->ContextRecord->Ebp);
+	aDebugDump += StrFormat("CS:%04X SS:%04X DS:%04X ES:%04X FS:%04X GS:%04X\r\n", lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs, lpEP->ContextRecord->SegDs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegGs);
+	aDebugDump += StrFormat("Flags:%08X\r\n", lpEP->ContextRecord->EFlags);
 #endif
 
 	aDebugDump += "\r\n";
@@ -1015,12 +1015,12 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 
 	if (hasImageHelp)
 		GetSymbolsFromMapFile(aDebugDump);*/
-	
+
 	if (isCLI)
-	{		
+	{
 		aDebugDump += "\n";
-		//fwrite(aDebugDump.c_str(), 1, aDebugDump.length(), stderr);		
-		//fflush(stderr);		
+		//fwrite(aDebugDump.c_str(), 1, aDebugDump.length(), stderr);
+		//fflush(stderr);
 		DWORD bytesWritten;
 		::WriteFile(::GetStdHandle(STD_ERROR_HANDLE), aDebugDump.c_str(), (DWORD)aDebugDump.length(), &bytesWritten, NULL);
 	}
@@ -1031,7 +1031,7 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
 CrashCatcher::CrashCatcher()
 {
 	mCrashed = false;
-	mInitialized = false;	
+	mInitialized = false;
 	mExceptionPointers = NULL;
 	mPreviousFilter = NULL;
 	mDebugError = false;
@@ -1040,11 +1040,11 @@ CrashCatcher::CrashCatcher()
 }
 
 static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr)
-{	
+{
  	OutputDebugStrF("SEH Filter! CraskReportKind:%d\n", CrashCatcher::Get()->mCrashReportKind);
 
 	if (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_None)
-	{	
+	{
 		OutputDebugStrF("Silent Exiting\n");
 		::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
 	}
@@ -1059,17 +1059,17 @@ static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr)
 		//CreateMiniDump(lpExceptPtr);
 		DoHandleDebugEvent(lpExceptPtr);
 	}
- 
+
  	//if (!gDebugError)
- 		//SetErrorMode(SEM_NOGPFAULTERRORBOX);		
-	
+ 		//SetErrorMode(SEM_NOGPFAULTERRORBOX);
+
 	if (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_PrintOnly)
 	{
 		::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
 	}
 
 	//return EXCEPTION_CONTINUE_SEARCH;
-	return (CrashCatcher::Get()->mCloseRequested) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;	
+	return (CrashCatcher::Get()->mCloseRequested) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
 }
 
 //PVECTORED_EXCEPTION_HANDLER(
@@ -1082,7 +1082,7 @@ static long __stdcall VectorExceptionHandler(LPEXCEPTION_POINTERS lpExceptPtr)
 
 
 void CrashCatcher::Init()
-{	
+{
 	if (mInitialized)
 		return;
 
@@ -1105,7 +1105,7 @@ void CrashCatcher::Test()
 	}
 	__except (SEHFilter(GetExceptionInformation()))
 	{
-		
+
 	}
 }
 
@@ -1125,7 +1125,7 @@ void CrashCatcher::AddInfo(const StringImpl& str)
 }
 
 void CrashCatcher::Crash(const StringImpl& str)
-{	
+{
 	OutputDebugStrF("CrashCatcher::Crash\n");
 
 	mBfpCritSect.Lock();
@@ -1148,17 +1148,17 @@ void CrashCatcher::Crash(const StringImpl& str)
 	// When we catch the exception information like this, it displays the dump correctly but
 	//  the minidump doesn't contain a valid callstack, so we need to rely on SetUnhandledExceptionFilter
 	/*__try
-	{		
+	{
 		::MessageBoxA(NULL, "A", "B", MB_ICONERROR);
-		__debugbreak();		
+		__debugbreak();
 	}
 	__except (SEHFilter(GetExceptionInformation()))
 	{
 
 	}*/
-		
+
 	for (auto func : CrashCatcher::Get()->mCrashInfoFuncs)
-		func();	
+		func();
 
 	exit(1);
 }
@@ -1205,7 +1205,7 @@ CrashCatcher* CrashCatcher::Get()
 			{
 				if (sharedMem->mABIVersion == 0 && sharedMem->mBpManager == NULL && sharedMem->mCounter == 0)
 				{
-					sCrashCatcher = new CrashCatcher();					
+					sCrashCatcher = new CrashCatcher();
 					sharedMem->mBpManager = sCrashCatcher;
 					sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION;
 					sharedMem->mCounter = 1;
@@ -1216,7 +1216,7 @@ CrashCatcher* CrashCatcher::Get()
 					sCrashCatcher = sharedMem->mBpManager;
 				}
 				::UnmapViewOfFile(sharedMem);
-			}			
+			}
 			::CloseHandle(fileMapping);
 		}
 		else
@@ -1227,7 +1227,7 @@ CrashCatcher* CrashCatcher::Get()
 				CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory));
 				if (sharedMem != NULL)
 				{
-					sCrashCatcher = new CrashCatcher();					
+					sCrashCatcher = new CrashCatcher();
 					sharedMem->mBpManager = sCrashCatcher;
 					sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION;
 					sharedMem->mCounter = 1;
@@ -1235,11 +1235,11 @@ CrashCatcher* CrashCatcher::Get()
 					::ReleaseMutex(mutex);
 				}
 				else
-				{					
+				{
 					::CloseHandle(fileMapping);
 					::CloseHandle(mutex);
 				}
-			}			
+			}
 		}
 	}
 

+ 2 - 2
CMakeLists.txt

@@ -6,8 +6,8 @@ if(NOT CMAKE_BUILD_TYPE)
   message(STATUS "Build type not specified: Use Debug by default.")
 endif(NOT CMAKE_BUILD_TYPE)
 
-add_subdirectory(extern/hunspell)
+add_subdirectory(BeefRT)
 add_subdirectory(BeefySysLib)
+add_subdirectory(extern/hunspell)
 add_subdirectory(IDEHelper)
 add_subdirectory(BeefBoot)
-add_subdirectory(BeefRT)

+ 75 - 32
IDE/src/BuildContext.bf

@@ -195,50 +195,91 @@ namespace IDE
 			gApp.GetProjectBuildDir(project, projectBuildDir);
 			File.WriteAll(scope $"{projectBuildDir}/ObjectArgs.txt", .((.)objectsArg.Ptr, objectsArg.Length)).IgnoreError();
 
-		    String arCmds = scope String(""); //-O2 -Rpass=inline 
+		    String arCmds = null; //-O2 -Rpass=inline 
 															 //(doClangCPP ? "-lc++abi " : "") +
 
-		    arCmds.AppendF("CREATE {}\n", targetPath);
+			String arArgs = scope .();
 
-			void AddObject(StringView obj)
+			bool useArCmds = false;
+
+			if (useArCmds)
 			{
-				if (obj.IsEmpty)
-					return;
+				arCmds = scope:: String("");
+			    arCmds.AppendF("CREATE {}\n", targetPath);
 
-				if (obj.EndsWith(".lib", .OrdinalIgnoreCase))
-					arCmds.AppendF("ADDLIB {}\n", obj);
-				else
-					arCmds.AppendF("ADDMOD {}\n", obj);
-			}
+				void AddObject(StringView obj)
+				{
+					if (obj.IsEmpty)
+						return;
 
-			bool inQuote = false;
-			int lastEnd = -1;
-			for (int i < objectsArg.Length)
-			{
-				var c = objectsArg[i];
-				if (c == '"')
+					if (obj.EndsWith(".lib", .OrdinalIgnoreCase))
+						arCmds.AppendF("ADDLIB {}\n", obj);
+					else
+						arCmds.AppendF("ADDMOD {}\n", obj);
+				}
+
+				bool inQuote = false;
+				int lastEnd = -1;
+				for (int i < objectsArg.Length)
 				{
-					if (inQuote)
+					var c = objectsArg[i];
+					if (c == '"')
+					{
+						if (inQuote)
+							AddObject(objectsArg.Substring(lastEnd + 1, i - lastEnd - 1));
+						inQuote = !inQuote;
+						lastEnd = i;
+					}
+					else if ((c == ' ') && (!inQuote))
+					{
 						AddObject(objectsArg.Substring(lastEnd + 1, i - lastEnd - 1));
-					inQuote = !inQuote;
-					lastEnd = i;
+						lastEnd = i;
+					}
 				}
-				else if ((c == ' ') && (!inQuote))
+				AddObject(objectsArg.Substring(lastEnd + 1));
+
+				for (let obj in objectsArg.Split(' '))
 				{
-					AddObject(objectsArg.Substring(lastEnd + 1, i - lastEnd - 1));
-					lastEnd = i;
+					if (!obj.IsEmpty)
+					{
+						
+					}
 				}
+				arCmds.AppendF("SAVE\n");
 			}
-			AddObject(objectsArg.Substring(lastEnd + 1));
-
-			for (let obj in objectsArg.Split(' '))
+			else
 			{
-				if (!obj.IsEmpty)
+				arArgs.AppendF($"-qc {targetPath}");
+
+				void AddObject(StringView obj)
 				{
-					
+					if (obj.IsEmpty)
+						return;
+
+					arArgs.Append(" ");
+					arArgs.Append(obj);
 				}
+
+				bool inQuote = false;
+				int lastEnd = -1;
+				for (int i < objectsArg.Length)
+				{
+					var c = objectsArg[i];
+					if (c == '"')
+					{
+						if (inQuote)
+							AddObject(objectsArg.Substring(lastEnd + 1, i - lastEnd - 1));
+						inQuote = !inQuote;
+						lastEnd = i;
+					}
+					else if ((c == ' ') && (!inQuote))
+					{
+						AddObject(objectsArg.Substring(lastEnd + 1, i - lastEnd - 1));
+						lastEnd = i;
+					}
+				}
+				AddObject(objectsArg.Substring(lastEnd + 1));
 			}
-			arCmds.AppendF("SAVE\n");
 
 			UpdateCacheStr(project, "", workspaceOptions, options, null, null);
 
@@ -275,13 +316,15 @@ namespace IDE
 					return false;
 				}
 
-				String cmdLine = scope .();
-				cmdLine.AppendF("-M");
 
-		        var runCmd = gApp.QueueRun(arPath, cmdLine, workingDir, .UTF8);
+				if (arCmds != null)
+					arArgs.Append("-M");
+
+		        var runCmd = gApp.QueueRun(arPath, arArgs, workingDir, .UTF8);
 				runCmd.mReference = new String(project.mProjectName);
 		        runCmd.mOnlyIfNotFailed = true;
-				runCmd.mStdInData = new .(arCmds);
+				if (arCmds != null)
+					runCmd.mStdInData = new .(arCmds);
 		        var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
 		        tagetCompletedCmd.mOnlyIfNotFailed = true;
 		        gApp.mExecutionQueue.Add(tagetCompletedCmd);

+ 5 - 3
IDE/src/IDEApp.bf

@@ -827,7 +827,7 @@ namespace IDE
 				mExecutionPaused = false;
 			}
 
-            base.Shutdown();                       
+            base.Shutdown();
         }
 
         public override void Run()
@@ -8547,14 +8547,14 @@ namespace IDE
 			if (executionInstance.mProcess.AttachStandardInput(fileStream) case .Err)
 				return;
 			
-			while (!executionInstance.mStdInData.IsEmpty)
+			WriteLoop: while (!executionInstance.mStdInData.IsEmpty)
 			{
 				switch (fileStream.TryWrite(.((.)executionInstance.mStdInData.Ptr, executionInstance.mStdInData.Length)))
 				{
 				case .Ok(int len):
 					executionInstance.mStdInData.Remove(0, len);
 				case .Err:
-					break;
+					break WriteLoop;
 				}
 			}
 		}
@@ -8712,6 +8712,8 @@ namespace IDE
 
                 	if ((mVerbosity >= .Diagnostic) && (useArgsFile != .None))
                 		OutputLine("Arg file contents: {0}", args);
+					if ((mVerbosity >= .Diagnostic) && (stdInData != null))
+						OutputLine("StdIn data: {0}", stdInData);
                 }
 				else
 					OutputLine("Executing: {0}", showArgs);

+ 57 - 57
IDE/src/ui/HoverWatch.bf

@@ -13,7 +13,7 @@ using Beefy.theme;
 using IDE.Debugger;
 
 namespace IDE.ui
-{    
+{
     public class HoverWatch : Widget, IWatchOwner
     {
         public class PendingWatch
@@ -25,7 +25,7 @@ namespace IDE.ui
 
 			public ~this()
 			{
-				
+
 			}
         }
 
@@ -38,7 +38,7 @@ namespace IDE.ui
             public HoverListView mChildrenListView;
 
 			static int32 sHLVItemId = -1;
-			int32 mHLVItemId = ++sHLVItemId;			
+			int32 mHLVItemId = ++sHLVItemId;
 
             public this(IWatchOwner watchOwner, HoverListView listView) : base(watchOwner, listView)
             {
@@ -77,7 +77,7 @@ namespace IDE.ui
                     if (mWatchEntry.mResultTypeStr != null)
                         DarkTooltipManager.ShowTooltip(mWatchEntry.mResultTypeStr, this, LabelX + GS!(8), mSelfHeight + mBottomPadding);
                     return;
-                }                
+                }
 
                 base.ShowTooltip(mouseX, mouseY);
             }
@@ -128,7 +128,7 @@ namespace IDE.ui
 			}
         }
 
-        public class HoverListView : WatchListView        
+        public class HoverListView : WatchListView
         {
             public HoverWatch mHoverWatch;
             public bool mSizeDirty;
@@ -168,7 +168,7 @@ namespace IDE.ui
 
             public override void Draw(Graphics g)
             {
-                
+
                 base.Draw(g);
             }
 
@@ -185,7 +185,7 @@ namespace IDE.ui
 			}
 
             public override void Update()
-            {                
+            {
                 base.Update();
 
                 if (mSizeDirty)
@@ -220,7 +220,7 @@ namespace IDE.ui
                 Resize(mX, mY, listView.mColumns[1].mWidth - adjust, mHeight);
                 HorzScrollTo(0);
             }
-        }        
+        }
 
 		class ContentWidget : Widget
 		{
@@ -317,7 +317,7 @@ namespace IDE.ui
         }
 
         void IWatchOwner.UpdateWatch(WatchListViewItem watchEntry)
-        {            
+        {
         }
 
         public void Clear()
@@ -364,7 +364,7 @@ namespace IDE.ui
                 mWidgetWindow = null;
             }
 
-            
+
 			Widget.RemoveAndDelete(mEditWidget);
             mEditWidget = null;
 
@@ -398,13 +398,13 @@ namespace IDE.ui
             if (mCloseHandler != null)
                 mCloseHandler();
 
-            Clear();    
+            Clear();
 
 			if (!mCreatedWindow)
 				delete this;
         }
-		
-        void HandleMouseWheel(MouseEvent evt)        
+
+        void HandleMouseWheel(MouseEvent evt)
         {
 			if (mListViews.Count > 1)
 			{
@@ -470,7 +470,7 @@ namespace IDE.ui
 					}
 				}
 			}
-   
+
             if (mCloseDelay > 1)
                mCloseDelay--;
 			if (mCloseCountdown > 0)
@@ -514,8 +514,8 @@ namespace IDE.ui
                     var beforeLastListView = mChildWidgets[mChildWidgets.Count - 2] as HoverListView;
                     if (beforeLastListView != null)
                     {
-                        if (mEditWidget != null)                        
-                            mEditWidget.LostFocus();                        
+                        if (mEditWidget != null)
+                            mEditWidget.LostFocus();
                         CloseChildren(beforeLastListView);
                     }
                 }
@@ -526,11 +526,11 @@ namespace IDE.ui
         {
             base.MouseMove(x, y);
 
-           
+
         }
 
         void CloseChildren(HoverListView hoverListView)
-        {            
+        {
             for (HoverListViewItem childItem in hoverListView.GetRoot().mChildItems)
             {
 				var childrenListView = childItem.mChildrenListView;
@@ -539,14 +539,14 @@ namespace IDE.ui
                     CloseChildren(childrenListView);
                     mListViews.Remove(childrenListView);
                     childrenListView.RemoveSelf();
-                    childItem.mChildrenListView = null;                    
+                    childItem.mChildrenListView = null;
 
 					if (childItem.mOpenButton != null)
                     	childItem.mOpenButton.mIsOpen = false;
 					//delete childrenListView;
 					gApp.DeferDelete(childrenListView);
                 }
-            }            
+            }
         }
 
         void OpenButtonClicked(HoverListViewItem listViewItem)
@@ -572,7 +572,7 @@ namespace IDE.ui
 				childrenListView.mParentHoverListViewItem = listViewItem;
                 mContentWidget.AddWidget(childrenListView);
                 mListViews.Add(childrenListView);
-                listViewItem.mChildrenListView = childrenListView;                
+                listViewItem.mChildrenListView = childrenListView;
                 for (var pendingEntry in listViewItem.mPendingWatches)
                 {
                     var watchListViewItem = DoListViewItem(listViewItem.mChildrenListView, null, pendingEntry.mName, pendingEntry.mEvalStr, false, listViewItem.mWatchEntry);
@@ -709,10 +709,10 @@ namespace IDE.ui
 
             HoverListViewItem valueSubItem = null;
 			var useListViewItem = listViewItem;
-            if (useListViewItem == null)            
+            if (useListViewItem == null)
                 useListViewItem = (HoverListViewItem)listView.GetRoot().CreateChildItem();
 
-            if (useListViewItem.mWatchEntry == null)            
+            if (useListViewItem.mWatchEntry == null)
             {
                 useListViewItem.mWatchEntry = new WatchEntry();
                 valueSubItem = (HoverListViewItem)useListViewItem.CreateSubItem(1);
@@ -724,7 +724,7 @@ namespace IDE.ui
             }
 
 			bool isLiteral = displayString.StartsWith("'") || displayString.StartsWith("\"");
-			
+
             var watch = useListViewItem.mWatchEntry;
             String.NewOrSet!(watch.mName, displayString);
             String.NewOrSet!(watch.mEvalStr, evalString);
@@ -819,12 +819,12 @@ namespace IDE.ui
 				valueSubItem.Label = "";
 			}
             else if (valueSubItem.mLabel.StartsWith("!", StringComparison.Ordinal))
-            {                
+            {
                 var errorVals = scope List<StringView>(scope String(valueSubItem.mLabel, 1).Split('\t'));
                 if (errorVals.Count > 1)
-                {                    
+                {
                     String.NewOrSet!(valueSubItem.mLabel, errorVals[2]);
-                }                
+                }
                 else
                     String.NewOrSet!(valueSubItem.mLabel, errorVals[0]);
                 valueSubItem.mFailed = true;
@@ -834,7 +834,7 @@ namespace IDE.ui
 
             if ((vals.Count > 1) && (!vals[1].IsEmpty))
                 String.NewOrSet!(watch.mResultTypeStr, vals[1]);
-            else            
+            else
                 DeleteAndNullify!(watch.mResultTypeStr);
 
             int cmdStringCount = Math.Max(0, vals.Count - 2);
@@ -876,7 +876,7 @@ namespace IDE.ui
 							String.NewOrSet!(watch.mEditInitialize, scope String(memberVals[1]));
                     }
                     else if (memberVals0 == ":editVal")
-                    {                        
+                    {
                         String.NewOrSet!(watch.mEditInitialize, scope String(memberVals[1]));
                     }
 					else if (memberVals0 == ":break")
@@ -949,7 +949,7 @@ namespace IDE.ui
 						if (int32.Parse(memberVals[1]) case .Ok(out language))
 						{
 							watch.mLanguage = (.)language;
-						}	
+						}
 					}
 					else if (memberVals0 == ":warn")
 					{
@@ -963,7 +963,7 @@ namespace IDE.ui
                 }
 
                 if (memberVals.Count >= 2)
-                {                    
+                {
                     if (useListViewItem.mOpenButton == null)
                     {
                         useListViewItem.MakeParent();
@@ -998,11 +998,11 @@ namespace IDE.ui
             }
 
             if ((memberCount == 0) && (useListViewItem.mOpenButton != null))
-            {                
+            {
 				Widget.RemoveAndDelete(useListViewItem.mOpenButton);
                 useListViewItem.mOpenButton = null;
 				delete useListViewItem.mChildItems;
-                useListViewItem.mChildItems = null;                
+                useListViewItem.mChildItems = null;
             }
             //if (valueSubItem.mFailed)
                 //return null;
@@ -1010,7 +1010,7 @@ namespace IDE.ui
         }
 
         HoverListView CreateListView()
-        {            
+        {
             //var font = DarkTheme.sDarkTheme.mSmallFont;
             var listView = new HoverListView(this);
 
@@ -1018,18 +1018,18 @@ namespace IDE.ui
 
             listView.mHoverWatch = this;
             listView.SetShowHeader(false);
-            listView.mShowColumnGrid = true;            
+            listView.mShowColumnGrid = true;
 
 #unwarn
             var nameColumn = listView.AddColumn(100, "Name");
 #unwarn
             var valueColumn = listView.AddColumn(100, "Value");
-            
+
             return listView;
         }
 
 		int32 mResizeCount = 0;
-		
+
 		Widget GetParentWidget()
 		{
 			Widget parentWidget = null;
@@ -1118,7 +1118,7 @@ namespace IDE.ui
 
             var font = DarkTheme.sDarkTheme.mSmallFont;
             float nameWidth = 0;
-            float valueWidth = 0;            
+            float valueWidth = 0;
 
             bool hadMembers = false;
 
@@ -1151,7 +1151,7 @@ namespace IDE.ui
 				if (listViewItem.mWatchRefreshButton != null)
 					thisNameWidth += GS!(18);
                 nameWidth = Math.Max(nameWidth, thisNameWidth);
-                
+
                 float addHeight = nameHeight - listView.mFont.GetLineSpacing();
                 childHeights += addHeight;
                 listViewItem.mSelfHeight += addHeight;
@@ -1172,7 +1172,7 @@ namespace IDE.ui
                 if (listViewItem.mWatchEntry.mResultType != WatchResultType.None)
                     hasLeftIcon = true;
             }
-            
+
             if (!hadMembers)
                 listView.mLabelX -= GS!(14);
             if (!hasRightValues)
@@ -1191,7 +1191,7 @@ namespace IDE.ui
             float height = childHeights + GS!(6);
 
             float maxHeight = font.GetLineSpacing() * 12 + 6.001f;
-            if (height > maxHeight)            
+            if (height > maxHeight)
             {
                 if (listView.mVertScrollbar == null)
 				{
@@ -1387,17 +1387,17 @@ namespace IDE.ui
             else
                 width = listView.mWidth - x - GS!(4);
 
-            
+
             //editWidget.Resize(x - GS!(1), y - GS!(2), width, GS!(24));
 			editWidget.ResizeAround(x, y, width);
-            
+
             listView.AddWidget(editWidget);
 
             editWidget.mOnLostFocus.Add(new => HandleEditLostFocus);
             editWidget.mOnSubmit.Add(new => HandleRenameSubmit);
             editWidget.mOnCancel.Add(new => HandleRenameCancel);
             WidgetWindow.sOnMouseWheel.Add(new => HandleMouseWheel);
-            
+
             editWidget.SetFocus();
 			mActionIdx++;
         }
@@ -1446,7 +1446,7 @@ namespace IDE.ui
 					flags |= DebugManager.EvalExpressionFlags.DeselectCallStackIdx;
 				flags |= .AllowCalls | .AllowSideEffects;
                 gApp.DebugEvaluate(null, evalStr, val, -1, headListViewItem.mWatchEntry.mLanguage, flags);
-                //IDEApp.sApp.OutputLine(val);                
+                //IDEApp.sApp.OutputLine(val);
 
                 if (val.StartsWith("!", StringComparison.Ordinal))
                 {
@@ -1469,7 +1469,7 @@ namespace IDE.ui
                 IDEApp.sApp.MemoryEdited();
             }
 
-			editWidget.RemoveSelf();            
+			editWidget.RemoveSelf();
 			BFApp.sApp.DeferDelete(editWidget);
             mEditWidget = null;
             mEditingItem = null;
@@ -1480,7 +1480,7 @@ namespace IDE.ui
                 var childListView = childWidget as HoverListView;
                 RefreshListView(childListView);
             }
-            
+
             mEditLostFocusTick = mUpdateCnt;
             FinishListView(listView, listView.mX, listView.mY);
 
@@ -1513,7 +1513,7 @@ namespace IDE.ui
             if (theEvent.mBtn == 0)
             {
                 //PropertyEntry aPropertyEntry = mPropertyEntryMap[item];
-                //EditValue(aPropertyEntry);            
+                //EditValue(aPropertyEntry);
                 EditListViewItem(item);
             }
             else if (theEvent.mBtn == 1)
@@ -1522,7 +1522,7 @@ namespace IDE.ui
 				clickedItem.SelfToOtherTranslate(clickedItem.mListView.GetRoot(), theEvent.mX, theEvent.mY, out aX, out aY);
                 ShowRightClickMenu(item, aX, aY);
             }
-                        
+
             theEvent.mHandled = true;
         }
 
@@ -1570,7 +1570,7 @@ namespace IDE.ui
 					mDisplayString.Append('\n');
 					mDisplayString.Append(useStr);
 				}
-				
+
 				Rehup();
 				return true;
 			}
@@ -1599,8 +1599,8 @@ namespace IDE.ui
 
             mTextPanel = textPanel;
 			mTextPanel.mOnRemovedFromParent.Add(new => PanelRemovedFromParent);
-            if (mTextPanel.mHoverWatch != null)            
-                Debug.Assert(mTextPanel.mHoverWatch == this);            
+            if (mTextPanel.mHoverWatch != null)
+                Debug.Assert(mTextPanel.mHoverWatch == this);
             mTextPanel.mHoverWatch = this;
 			if (displayString == null)
 				mDisplayString.Clear();
@@ -1615,7 +1615,7 @@ namespace IDE.ui
             mOrigY = y;
 
 			Widget parentWidget = GetParentWidget();
-			
+
             //var parentWidget = textPanel.EditWidget.Content;
 
             if (evalString != null)
@@ -1664,7 +1664,7 @@ namespace IDE.ui
                 (int)screenWidth, (int)screenHeight,
                 windowFlags,
                 this);
-            
+
             WidgetWindow.sMouseDownHandler.Add(new => HandleMouseDown);
             WidgetWindow.sMouseWheelDelegate.Add(new => HandleMouseWheel);
             WidgetWindow.sMenuItemSelectedDelegate.Add(new => HandleSysMenuItemSelected);
@@ -1695,9 +1695,9 @@ namespace IDE.ui
                 openYList.Add(openY);
             }
 
-            var sourceViewPanel = mTextPanel;			
+            var sourceViewPanel = mTextPanel;
 			var widgetWindow = mWidgetWindow;
-            Close();            
+            Close();
 			if (widgetWindow != null)
 				widgetWindow.mRootWidget = null; // Detach root
 			//Debug.WriteLine("Hoverwatch showing");
@@ -1726,7 +1726,7 @@ namespace IDE.ui
                         OpenButtonClicked(hoverListViewItem);
                         break;
                     }
-                }                
+                }
             }
 
 			mRehupEvent();

+ 1 - 1
IDEHelper/Tests/src/Comptime.bf

@@ -523,7 +523,7 @@ namespace Tests
 			iSer.Serialize(serCtx);
 			Test.Assert(serCtx.mStr == "x 10\ny 2\n");
 
-			Test.Assert(cTest0 == "Test\n0");
+			Test.Assert(cTest0 == "Test\n0" || cTest0 == "Test\r\n0");
 			Test.Assert(cTest1 == "AAAAAAAAAAAA");
 			Test.Assert((Object)cTest1 == (Object)"AAAAAAAAAAAA");
 			Test.Assert((cTest0Binary[0] == (.)'T') && ((cTest0Binary.Count == 6) || (cTest0Binary.Count == 7)));

+ 25 - 6
bin/build.sh

@@ -7,10 +7,25 @@ ROOTPATH="$(dirname "$SCRIPTPATH")"
 echo Building from $SCRIPTPATH
 cd $SCRIPTPATH
 
-if [[ $1 == "clean" ]]; then
-	rm -rf ../jbuild
-	rm -rf ../jbuild_d
-fi
+for i in "$@"
+do
+	if [[ $i == "clean" ]]; then
+		echo "Cleaning..."
+		rm -rf ../jbuild
+		rm -rf ../jbuild_d
+		exit
+	fi
+
+	if [[ $i == "sdl" ]]; then
+		echo "Using SDL"
+		USE_SDL="-DBF_ENABLE_SDL=1"
+	fi
+
+	if [[ $i == "no_ffi" ]]; then
+		echo "Disabling FFI"
+		USE_FFI="-DBF_DISABLE_FFI=1"
+	fi
+done
 
 if command -v ninja >/dev/null 2>&1 ; then
 	CAN_USE_NINJA=1
@@ -55,11 +70,15 @@ if [ ! -d jbuild_d ]; then
 	mkdir jbuild_d
 	mkdir jbuild
 fi
+
 cd jbuild_d
-cmake $USE_NINJA -DCMAKE_BUILD_TYPE=Debug ../
+
+echo cmake $USE_NINJA $USE_SDL -DCMAKE_BUILD_TYPE=Debug ../
+
+cmake $USE_NINJA $USE_SDL $USE_FFI -DCMAKE_BUILD_TYPE=Debug ../
 cmake --build .
 cd ../jbuild
-cmake $USE_NINJA -DCMAKE_BUILD_TYPE=RelWithDebInfo ../
+cmake $USE_NINJA $USE_SDL $USE_FFI -DCMAKE_BUILD_TYPE=RelWithDebInfo ../
 cmake --build .
 
 cd ../IDE/dist

+ 66 - 0
bin/build_sdl.sh

@@ -0,0 +1,66 @@
+#!/bin/bash
+echo Starting build.sh
+
+PATH=/usr/local/bin:$PATH:$HOME/bin
+SCRIPTPATH=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
+ROOTPATH="$(dirname "$SCRIPTPATH")"
+echo Building from $SCRIPTPATH
+cd $SCRIPTPATH
+
+if [[ $1 == "clean" ]]; then
+	rm -rf ../jbuild_sdl
+	rm -rf ../jbuild_sdl_d
+	exit
+fi
+
+if [[ $1 == "sdl" ]]; then
+	echo "Using SDL"
+	USE_SDL="-DBF_ENABLE_SDL=1"
+fi
+
+if command -v ninja >/dev/null 2>&1 ; then
+	CAN_USE_NINJA=1
+	if [ -d ../jbuild_sdl_d ] && [ ! -f ../jbuild_sdl_d/build.ninja ]; then
+		CAN_USE_NINJA=0
+	fi
+
+	if [ $CAN_USE_NINJA == 1 ]; then
+		echo "Ninja is enabled for this build."
+		USE_NINJA="-GNinja"
+	else
+		echo "Ninja couldn't be enabled for this build, consider doing a clean build to start using Ninja for faster build speeds."
+	fi
+else
+	echo "Ninja isn't installed, consider installing it for faster build speeds."
+fi
+
+# exit when any command fails
+set -e
+
+### Dependencies ###
+
+if [ ! -f ../BeefySysLib/third_party/libffi/Makefile ]; then
+	echo Building libffi...
+	cd ../BeefySysLib/third_party/libffi
+	./configure
+	make
+	cd $SCRIPTPATH
+fi
+
+### LIBS ###
+
+cd ..
+if [ ! -d jbuild_sdl_d ]; then
+	mkdir jbuild_sdl_d
+	mkdir jbuild_sdl
+fi
+
+cd jbuild_sdl_d
+
+echo cmake $USE_NINJA $USE_SDL -DCMAKE_BUILD_TYPE=Debug ../
+
+cmake $USE_NINJA -DBF_ENABLE_SDL=1 -DCMAKE_BUILD_TYPE=Debug ../
+cmake --build .
+cd ../jbuild_sdl
+cmake $USE_NINJA -DBF_ENABLE_SDL=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ../
+cmake --build .