Index: cpp/common/Convert.cpp
===================================================================
--- cpp/common/Convert.cpp	(revision 246)
+++ cpp/common/Convert.cpp	(revision 247)
@@ -8,11 +8,11 @@
 
 #if defined __ANDROID__ || defined __BORLANDC__
- #include <ctype.h> //toupper, tolower
+#include <ctype.h> //toupper, tolower
 #endif
 
 #ifdef SHP
- #include <cstdlib>
+#include <cstdlib>
 #else
- #include <stdlib.h>
+#include <stdlib.h>
 #endif
 
@@ -20,29 +20,27 @@
 
 
-int Convert::toInt(string s) {return atoi(s.c_str());}
-float Convert::toFloat(string s) {return (float)atof(s.c_str());}
-#ifndef __BORLANDC__ //the borland compiler compiles this file in GUI and CLI, but not in the theater app. Somehow it cannot find ::tolower and ::toupper; maybe this is because of various #defines in <cctype>, but why only in the theater app??
-string Convert::toLowerCase(string s) {std::transform(s.begin(), s.end(), s.begin(), ::tolower);  return s;}
-string Convert::toUpperCase(string s) {std::transform(s.begin(), s.end(), s.begin(), ::toupper);  return s;}
-#endif
-char Convert::toLowerCase(char c) {return (char)tolower(c);}
-char Convert::toUpperCase(char c) {return (char)toupper(c);}
+int Convert::toInt(string s) { return atoi(s.c_str()); }
+float Convert::toFloat(string s) { return (float)atof(s.c_str()); }
+string Convert::toLowerCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::tolower);  return s; }
+string Convert::toUpperCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::toupper);  return s; }
+char Convert::toLowerCase(char c) { return (char)tolower(c); }
+char Convert::toUpperCase(char c) { return (char)toupper(c); }
 
-template<class T> const char* printf_format_for(const T& value) {return "unknown type";}
-template<> const char* printf_format_for(const unsigned int& value) {return "%u";}
-template<> const char* printf_format_for(const int& value) {return "%d";}
-template<> const char* printf_format_for(const short& value) {return "%d";}
-template<> const char* printf_format_for(const float& value) {return "%g";}
-template<> const char* printf_format_for(const double& value) {return "%g";}
+template<class T> const char* printf_format_for(const T& value) { return "unknown type"; }
+template<> const char* printf_format_for(const unsigned int& value) { return "%u"; }
+template<> const char* printf_format_for(const int& value) { return "%d"; }
+template<> const char* printf_format_for(const short& value) { return "%d"; }
+template<> const char* printf_format_for(const float& value) { return "%g"; }
+template<> const char* printf_format_for(const double& value) { return "%g"; }
 
 template<class T> string Convert::_toString(const T& value)
 {
-char buf[30];
-sprintf(buf,printf_format_for(value),value);
-return string(buf);
-/*
-#ifndef MULTITHREADED
+	char buf[30];
+	sprintf(buf, printf_format_for(value), value);
+	return string(buf);
+	/*
+	#ifndef MULTITHREADED
 	static
-#endif
+	#endif
 	std::ostringstream oss; //pod VS tworzenie go trwa dlugo nawet w wersji release (szczegolnie jak np konwertuje sie cos setki tysiecy razy)
 	//dlatego robimy go raz (static) i potem tylko czyscimy
@@ -51,14 +49,22 @@
 	oss.clear(); //clear error flag
 	oss.str(""); //set empty string
-  oss << value;
-  return oss.str();
-*/
+	oss << value;
+	return oss.str();
+	*/
 }
 
-string Convert::toString(unsigned int v) {return _toString(v);}
-string Convert::toString(int v) {return _toString(v);}
-string Convert::toString(short v) {return _toString(v);}
-string Convert::toString(float v) {return _toString(v);}
-string Convert::toString(double v) {return _toString(v);}
+string Convert::toString(unsigned int v) { return _toString(v); }
+string Convert::toString(int v) { return _toString(v); }
+string Convert::toString(short v) { return _toString(v); }
+string Convert::toString(float v) { return _toString(v); }
+string Convert::toString(double v) { return _toString(v); }
+
+uint32_t Convert::hexToInt(const string& col)
+{
+	uint32_t value;
+	std::istringstream iss(col);
+	iss >> std::hex >> value;
+	return value;
+}
 
 #ifdef MULTITHREADED
@@ -69,5 +75,5 @@
 //z mutexa gdy drugi dalej by go inicjalizowal
 #include "threads.h"
-static pthread_mutex_t fix_unsafe_mutex=PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t fix_unsafe_mutex = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
@@ -76,20 +82,20 @@
 #ifndef MULTITHREADED
 
-return *::localtime(&timep);
+	return *::localtime(&timep);
 
 #else
 
-struct tm ret;
+	struct tm ret;
 
 #if defined LINUX // || android?
-return *::localtime_r(&timep,&ret);
+	return *::localtime_r(&timep,&ret);
 #elif defined _WIN32 && !defined __BORLANDC__ // and not bada?
-::localtime_s(&ret,&timep);
-return ret;
+	::localtime_s(&ret, &timep);
+	return ret;
 #else //borland?
-pthread_mutex_lock(&fix_unsafe_mutex);
-ret=*::localtime(&timep);
-pthread_mutex_unlock(&fix_unsafe_mutex);
-return ret;
+	pthread_mutex_lock(&fix_unsafe_mutex);
+	ret=*::localtime(&timep);
+	pthread_mutex_unlock(&fix_unsafe_mutex);
+	return ret;
 #endif
 
@@ -99,26 +105,25 @@
 string Convert::asctime(const struct tm &tm)
 {
-char *ret;
+	char *ret;
 #ifndef MULTITHREADED
 
-ret=::asctime(&tm);
+	ret=::asctime(&tm);
 
 #else //MULTITHREADED
 
-char buf[26];
+	char buf[26];
 #if defined LINUX // || android?
-ret=::asctime_r(&tm,buf);
+	ret=::asctime_r(&tm,buf);
 #elif defined _WIN32 && !defined __BORLANDC__ // and not bada?
-asctime_s(buf,sizeof(buf),&tm);
-ret=buf;
+	asctime_s(buf, sizeof(buf), &tm);
+	ret = buf;
 #else //borland?
-pthread_mutex_lock(&fix_unsafe_mutex);
-strcpy(buf,::asctime(&tm));
-ret=buf;
-pthread_mutex_unlock(&fix_unsafe_mutex);
+	pthread_mutex_lock(&fix_unsafe_mutex);
+	strcpy(buf,::asctime(&tm));
+	ret=buf;
+	pthread_mutex_unlock(&fix_unsafe_mutex);
 #endif
 #endif
 
-return string(ret,24); //24 znaki z pominieciem ostatniego \n
+	return string(ret, 24); //24 znaki z pominieciem ostatniego \n
 }
-
Index: cpp/common/Convert.h
===================================================================
--- cpp/common/Convert.h	(revision 246)
+++ cpp/common/Convert.h	(revision 247)
@@ -10,4 +10,6 @@
 #include "nonstd_stl.h"
 #include "2d.h"
+#include <stdint.h>
+
 
 typedef XY<double> Pt2D;
@@ -17,59 +19,98 @@
 {
 public:
-  static int toInt(string s);
-  static float toFloat(string s);
-  static string toLowerCase(string s);
-  static string toUpperCase(string s);
-  static char toLowerCase(char c);
-  static char toUpperCase(char c);
-  template<class T> static string _toString(const T& value);
-  static string toString(unsigned int v);
-  static string toString(int v);
-  static string toString(short v);
-  static string toString(float v);
-  static string toString(double v);// ze niby w badzie ma nie byc? ale w frams na pewno ma byc bo tu same double
-  static string zeroPad(string s,int l) {while((int)s.length()<l) s=string("0")+s; return s;}
+	static int toInt(string s);
+	static float toFloat(string s);
+	static string toLowerCase(string s);
+	static string toUpperCase(string s);
+	static char toLowerCase(char c);
+	static char toUpperCase(char c);
+	template<class T> static string _toString(const T& value);
+	static string toString(unsigned int v);
+	static string toString(int v);
+	static string toString(short v);
+	static string toString(float v);
+	static string toString(double v);
+	static string zeroPad(string s, int l) { while ((int)s.length() < l) s = string("0") + s; return s; }
+	static uint32_t hexToInt(const string& col);
 
-  static double toRadians(double kat) {return kat*M_PI/180;}
-  static double toDegrees(double kat) {return kat/M_PI*180;}
-  static double atan_2(double y,double x) {if (x==0 && y==0) return 0; else return atan2(y,x);} //needed by borland 5/6 only?
+	static double toRadians(double angle) { return angle*M_PI / 180; }
+	static double toDegrees(double angle) { return angle / M_PI * 180; }
+	static double atan_2(double y, double x) { if (x == 0 && y == 0) return 0; else return atan2(y, x); } //needed by borland 5/6 only?
 
-	static double odleglosc_sq(double x1,double y1,double x2,double y2) //odleglosc do kwadratu, wystarczy do porownywania
-	{double dx=x2-x1, dy=y2-y1; return dx*dx+dy*dy;}
-	static double odleglosc_sq(const Pt2D& p1,const Pt2D& p2) //odleglosc do kwadratu
-	{return odleglosc_sq(p1.x,p1.y,p2.x,p2.y);}
+	static double odleglosc_sq(double x1, double y1, double x2, double y2) //odleglosc do kwadratu, wystarczy do porownywania
+	{
+		double dx = x2 - x1, dy = y2 - y1; return dx*dx + dy*dy;
+	}
+	static double odleglosc_sq(const Pt2D& p1, const Pt2D& p2) //odleglosc do kwadratu
+	{
+		return odleglosc_sq(p1.x, p1.y, p2.x, p2.y);
+	}
 
-	static double odleglosc(double x1,double y1,double x2,double y2)	{return sqrt(odleglosc_sq(x1,y1,x2,y2));}
-	static double odleglosc(const Pt2D& p1,const Pt2D& p2)
-	{return sqrt(odleglosc_sq(p1,p2));}
-	
-  //static float odleglosc(int x1,int y1,int x2,int y2) {float dx=x1-x2; float dy=y1-y2; return sqrt(dx*dx+dy*dy);}
-  //static float odleglosc(float x1,float y1,float x2,float y2) {return sqrt(odleglosc_sq(x1,y1,x2,y2));}
-  //static float odleglosc_sq(float x1,float y1,float x2,float y2) {float dx=x1-x2; float dy=y1-y2; return dx*dx+dy*dy;}
+	static double odleglosc(double x1, double y1, double x2, double y2)	{ return sqrt(odleglosc_sq(x1, y1, x2, y2)); }
+	static double odleglosc(const Pt2D& p1, const Pt2D& p2)
+	{
+		return sqrt(odleglosc_sq(p1, p2));
+	}
 
-  static struct tm localtime(const time_t &timep);//jak ::localtime ale zwraca strukture zamiast wskaznika, ref w parametrze dla wygodnego wywolywania
-  static string asctime(const struct tm &tm);//jak ::asctime ale thread safe i bez glupiego \n na koncu, ref w parametrze dla wygodnego wywolywania
+	//static float odleglosc(int x1,int y1,int x2,int y2) {float dx=x1-x2; float dy=y1-y2; return sqrt(dx*dx+dy*dy);}
+	//static float odleglosc(float x1,float y1,float x2,float y2) {return sqrt(odleglosc_sq(x1,y1,x2,y2));}
+	//static float odleglosc_sq(float x1,float y1,float x2,float y2) {float dx=x1-x2; float dy=y1-y2; return dx*dx+dy*dy;}
+
+	static struct tm localtime(const time_t &timep);//jak ::localtime ale zwraca strukture zamiast wskaznika, ref w parametrze dla wygodnego wywolywania
+	static string asctime(const struct tm &tm);//jak ::asctime ale thread safe i bez glupiego \n na koncu, ref w parametrze dla wygodnego wywolywania
+
+	static std::wstring strTOwstr(const char *s)
+	{
+		string str(s);
+		return std::wstring(str.begin(), str.end());
+	}
+
+	static string wstrTOstr(const wchar_t *s)
+	{
+		wstring str(s);
+		return string(str.begin(), str.end());
+	}
+
+	static string wstrTOutf8(const wchar_t *s)
+	{
+		if (s == NULL) return "";
+		string res;
+		wchar_t *wcp = (wchar_t*)s;
+		while (*wcp != 0)
+		{
+			int c = *wcp;
+			if (c < 0x80) res += c;
+			else if (c < 0x800) { res += 192 + c / 64; res += 128 + c % 64; }
+			else if (c - 0xd800u < 0x800) res += "<ERR-CHAR>";
+			else if (c < 0x10000) { res += 224 + c / 4096; res += 128 + c / 64 % 64; res += 128 + c % 64; }
+			else if (c < 0x110000) { res += 240 + c / 262144; res += 128 + c / 4096 % 64; res += 128 + c / 64 % 64; res += 128 + c % 64; }
+			else res += "<ERR-CHAR>";
+			wcp++;
+		}
+		return res;
+	}
+	//#endif
 };
 
 
 
-struct Kat //znormalizowany k¹t w radianach [0,2pi) i stopniach [0,360) z obliczonymi sinus i cosinus oraz intem [0,359]
+struct Angle //normalized angle in radians [0,2pi) and degrees [0,360) with pre-computed sine and cosine and degree as integer [0,359]
 {
 private:
-	double kat; //w radianach, read-only
+	double angle; //in radians, read-only
 public:
-	double kat_stopnie; //read-only
-	int kat_stopnie_int; //read-only
+	double angle_deg; //read-only
+	int angle_deg_int; //read-only
 
-	Kat() {set(0);}
-	Kat(double k) {set(k);}
-	Kat(Kat &kt) {set(kt.get());}
-	Kat(double dy,double dx) {set(dy,dx);}
-	void set(double k) {k=fmod(k,M_PI*2); if (k<0) k+=M_PI*2; kat=k; sinus=sin(k); cosinus=cos(k); kat_stopnie=Convert::toDegrees(kat); kat_stopnie_int=roundToInt(kat_stopnie); kat_stopnie_int%=360; }
-	void set(double dy,double dx) {set(Convert::atan_2(dy,dx));}
-	void add(double dk) {set(kat+dk);}
-	void add(Kat &kt) {set(kat+kt.get());}
-	double get() {return kat;}
-	double sinus,cosinus;
+	Angle() { set(0); }
+	Angle(double k) { set(k); }
+	Angle(Angle &kt) { set(kt.get()); }
+	Angle(double dy, double dx) { set(dy, dx); }
+	void set(double k) { k = fmod(k, M_PI * 2); if (k < 0) k += M_PI * 2; angle = k; sine = sin(k); cosine = cos(k); angle_deg = Convert::toDegrees(angle); angle_deg_int = roundToInt(angle_deg); angle_deg_int %= 360; }
+	void set(double dy, double dx) { set(Convert::atan_2(dy, dx)); }
+	void add(double dk) { set(angle + dk); }
+	void add(Angle &kt) { set(angle + kt.get()); }
+	double get() { return angle; }
+	double sine, cosine;
 };
 
Index: cpp/common/nonstd.h
===================================================================
--- cpp/common/nonstd.h	(revision 246)
+++ cpp/common/nonstd.h	(revision 247)
@@ -57,5 +57,5 @@
 #endif
 
-#if defined MACOS || defined __ANDROID__
+#if defined MACOS || defined __ANDROID__ || defined IPHONE
  #define stricmp(a,b) strcasecmp(a,b)
 #endif
@@ -86,4 +86,15 @@
 #ifdef LINUX
  #define GET_APP_HOME "./"
+ #define GET_APP_RESOURCES "./"
+#endif
+
+#ifdef MACOS
+#ifdef MACOS_APP_DIR //separate home/resources
+ #include <string>
+ std::string getAppHome();
+ #define GET_APP_HOME getAppHome()
+#else //old style
+ #define GET_APP_HOME "./"
+#endif
  #define GET_APP_RESOURCES "./"
 #endif
Index: cpp/common/nonstd_math.cpp
===================================================================
--- cpp/common/nonstd_math.cpp	(revision 246)
+++ cpp/common/nonstd_math.cpp	(revision 247)
@@ -22,7 +22,18 @@
 
 
+#ifdef IPHONE
+//TODO! -> ? http://stackoverflow.com/questions/12762418/how-to-enable-sigfpe-signal-on-division-by-zero-in-ios-app
+void fpExceptInit()
+{}
+
+void fpExceptEnable()
+{}
+
+void fpExceptDisable()
+{}
+#endif
 
 
-#if defined LINUX || defined TIZEN || defined __ANDROID__ || defined IPHONE
+#if defined LINUX || defined TIZEN || defined __ANDROID__
 
 #include <fenv.h>
Index: cpp/common/nonstd_stdio.cpp
===================================================================
--- cpp/common/nonstd_stdio.cpp	(revision 246)
+++ cpp/common/nonstd_stdio.cpp	(revision 247)
@@ -5,9 +5,11 @@
 #include "nonstd_stdio.h"
 #include "nonstd.h"
+#include "Convert.h" //strTOwstr()
+#include <common/stl-util.h>
 
 #if defined _WIN32 && !defined SHP
  //<unistd.h> not needed for unlink()
  #include "Shlwapi.h" //PathIsRelative()
- #include "Util.h" //strTOwstr()
+ #include <sys/stat.h> //_stat
 #else
  #include <unistd.h>
@@ -23,4 +25,47 @@
 }
 
+bool directoryExists(const char* path)
+{
+struct _stat s;
+if (_stat(path,&s)!=0) return false;
+return S_ISDIR(s.st_mode);
+}
+
+bool makeDirectory(const char* path)
+{
+#ifdef _WIN32
+return mkdir(path)==0;
+#else
+return mkdir(path,0777)==0;
+#endif
+}
+
+bool makeDirectories(const char* path)
+{
+if (directoryExists(path)) return true;
+string parentdir=getFileDir(path);
+if (!makeDirectories(parentdir.c_str())) return false;
+return makeDirectory(path);
+}
+
+int getFileSize(const char* path)
+{
+int size;
+MFILE *f=mfopen(path,FOPEN_READ_BINARY);
+if (f==NULL) return -1;
+size=getFileSize(f);
+mfclose(f);
+return size;
+}
+
+int getFileSize(MFILE *f)
+{
+  int saved_pos = mftell(f);
+  mfseek(f, 0, SEEK_END);
+  int size = mftell(f);
+  mfseek(f, saved_pos, SEEK_SET);
+  return size;
+}
+
 bool removeFile(const char* path)
 {
@@ -35,5 +80,5 @@
 	return PathIsRelative(fname) == FALSE; //no wide char for old borland compiler
  #else
-	return PathIsRelative(Util::strTOwstr(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
+	return PathIsRelative(Convert::strTOwstr(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
  #endif
 #else
Index: cpp/common/nonstd_stdio.h
===================================================================
--- cpp/common/nonstd_stdio.h	(revision 246)
+++ cpp/common/nonstd_stdio.h	(revision 247)
@@ -7,6 +7,10 @@
 
 bool fileExists(const char* path);
+bool directoryExists(const char* path);
+bool makeDirectory(const char* path);
+bool makeDirectories(const char* path);
 bool removeFile(const char* path);
 bool isAbsolutePath(const char* fname);
+int getFileSize(const char* path);
 
 #ifdef _WIN32
@@ -24,7 +28,8 @@
 #ifndef MOBILE2D
  #include <io.h> //borland compiler: include <io.h> before <dir.h> causes the SimWorld class in "simul.h" be unrecognized, for unknown reason :O moreover, this problem is only pertinent to the CLI project, not GUI. Maybe this is caused by global defines like NOVCL, NO_STRICT etc.?
- #define makeDirectory(name) mkdir(name) 
+// #define makeDirectory(name) mkdir(name)
 #endif
 
+ #define S_ISDIR(x) ((x & _S_IFDIR)==_S_IFDIR)
 
 #else
@@ -32,7 +37,7 @@
  #include <unistd.h>
  #include <sys/stat.h>
- #define makeDirectory(name) mkdir(name,0777)
+// #define makeDirectory(name) mkdir(name,0777)
  #define _unlink unlink //_unlink jest ISO-conformant, unlink jest POSIX-deprecated
-
+ #define _stat stat
 #endif
 
@@ -95,3 +100,5 @@
 #endif
 
+int getFileSize(MFILE *f);
+
 #endif
Index: cpp/common/random.h
===================================================================
--- cpp/common/random.h	(revision 246)
+++ cpp/common/random.h	(revision 247)
@@ -12,4 +12,7 @@
  #include <sys/stat.h>
  #include <fcntl.h>
+#endif
+#ifdef __BORLANDC__
+ #include <stdint.h> //uintptr_t in borland
 #endif
 #ifdef _WIN32
@@ -76,7 +79,7 @@
 		{
 			counter++;
-			seed = time(NULL);              //time (seconds); could use hi-res timer but then we would depend on common/timer.h
-			seed ^= counter;                //incremented value, possibly randomly initialized
-			seed ^= (unsigned int)&counter; //memory address
+			seed = time(NULL);                         //time (seconds); could use hi-res timer but then we would depend on common/timer.h
+			seed ^= counter;                           //incremented value, possibly randomly initialized
+			seed ^= (unsigned int)(uintptr_t)&counter; //memory address
 		}
 #ifdef _WIN32 //add more randomness from uuid
Index: cpp/common/stl-util.cpp
===================================================================
--- cpp/common/stl-util.cpp	(revision 246)
+++ cpp/common/stl-util.cpp	(revision 247)
@@ -10,4 +10,10 @@
 #include "framsg.h"
 #include <assert.h>
+#ifdef USE_VIRTFILE
+ #include <frams/virtfile/virtfile.h>
+#endif
+#ifdef __BORLANDC__
+ #define va_copy(to,from) to=from //borland does not have va_copy() at all; va_list is just a pointer in borland
+#endif
 
 string ssprintf_va(const char* format, va_list ap)
@@ -16,8 +22,12 @@
 	long size = 256;
 	char* buf;
+	va_list ap_copy; // "va_list ap" can only by used once by printf-type functions as they advance the current argument pointer (crashed on linux x86_64)
+	// (does not apply to SString::sprintf, it does not have the va_list variant)
 
 	//almost like SString::sprintf, but there is no common code to share because SString can use its directWrite to avoid double allocating/copying
 #ifdef USE_VSCPRINTF
-	size = _vscprintf(format, ap) + 1; //+1 for terminating null character
+	va_copy(ap_copy,ap);
+	size = _vscprintf(format, ap_copy) + 1; //+1 for terminating null character
+	va_end(ap_copy);
 #endif
 
@@ -26,5 +36,7 @@
 		buf = (char*)malloc(size);
 		assert(buf != NULL);
-		int n = vsnprintf(buf, size, format, ap);
+		va_copy(ap_copy,ap);
+		int n = vsnprintf(buf, size, format, ap_copy);
+		va_end(ap_copy);
 		if (n > -1 && n < size)
 		{
@@ -54,15 +66,30 @@
 bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
 {
+    bool ok=false;
+#ifdef USE_VIRTFILE
+	if (!isAbsolutePath(filename))
+		{
+		VirtFILE *f=Vfopen(filename,FOPEN_READ_BINARY);
+		if (f)
+			{
+			int size=f->getSize();
+			data.resize(size);
+			int przeczytane = f->Vread(&data[0], size, 1);
+			ok = przeczytane == 1;
+			delete f;
+			}
+		}
+	else
+#endif
+	{
 	MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
-	bool ok = f != NULL;
 	if (f)
 	{
-		mfseek(f, 0, SEEK_END);
-		long size = mftell(f);
-		mfseek(f, 0, SEEK_SET);
+		int size=getFileSize(f);
 		data.resize(size);
 		int przeczytane = mfread(&data[0], size, 1, f);
 		mfclose(f);
-		ok &= przeczytane == 1;
+		ok = przeczytane == 1;
+	}
 	}
 	if (warn_on_missing_file && !ok)
