blitz_app.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #include "blitz.h"
  2. #include <stdio.h>
  3. BBString* bbAppDir=BBNULLSTRING;
  4. BBString* bbAppFile=BBNULLSTRING;
  5. BBString* bbAppTitle=BBNULLSTRING;
  6. BBString* bbLaunchDir=BBNULLSTRING;
  7. BBArray* bbAppArgs=BBNULLSTRING;
  8. void **bbGCStackTop;
  9. void bbEnd(){
  10. exit(0);
  11. }
  12. void bbOnEnd( void (*f)() ){
  13. atexit( f );
  14. }
  15. void bbWriteStdout( BBString *t ){
  16. char *p=bbStringToCString( t );
  17. fprintf( stdout,"%s",p );
  18. fflush( stdout );
  19. bbMemFree(p);
  20. }
  21. void bbWriteStderr( BBString *t ){
  22. char *p=bbStringToCString( t );
  23. fprintf( stderr,"%s",p );
  24. fflush( stderr );
  25. bbMemFree(p);
  26. }
  27. BBString *bbReadStdin(){
  28. #define BUF_SIZE 256
  29. int sz=0;
  30. char *str=0;
  31. BBString *t;
  32. for(;;){
  33. int t_sz;
  34. char buf[BUF_SIZE],*p;
  35. fgets( buf,BUF_SIZE,stdin );
  36. buf[BUF_SIZE-1]=0;
  37. if( p=strchr( buf,'\n' ) ){
  38. t_sz=p-buf;
  39. if( t_sz && isspace(buf[t_sz-1]) ) --t_sz;
  40. }else{
  41. t_sz=strlen( buf );
  42. }
  43. str=(char*)bbMemExtend( str,sz,sz+t_sz );
  44. bbMemCopy( str+sz,buf,t_sz );
  45. sz+=t_sz;
  46. if( t_sz<BUF_SIZE-1 ) break;
  47. }
  48. if( sz ) t=bbStringFromBytes( str,sz );
  49. else t=&bbEmptyString;
  50. bbMemFree( str );
  51. return t;
  52. }
  53. #if __APPLE__
  54. #include <CoreServices/CoreServices.h>
  55. #include <limits.h>
  56. #include <unistd.h>
  57. #include <pthread.h>
  58. static pthread_t _mainThread;
  59. static void startup(){
  60. _mainThread=pthread_self();
  61. }
  62. void bbDelay( int millis ){
  63. if (millis<0) return;
  64. usleep( millis*1000 );
  65. }
  66. int bbMilliSecs(){
  67. double t;
  68. UnsignedWide uw;
  69. Microseconds( &uw );
  70. t=(uw.hi<<(32-9))|(uw.lo>>9); //divide by 512...!
  71. return (int) (long long) ( t/(1000.0/512.0) );
  72. }
  73. int bbIsMainThread(){
  74. return pthread_self()==_mainThread;
  75. }
  76. #elif _WIN32
  77. #include <direct.h>
  78. #include <windows.h>
  79. int _bbusew; //internal 'use unicode' flag
  80. static DWORD _mainThread;
  81. static void startup(){
  82. _mainThread=GetCurrentThreadId();
  83. }
  84. void bbDelay( int millis ){
  85. if (millis<0) return;
  86. Sleep( millis );
  87. }
  88. int bbMilliSecs(){
  89. return timeGetTime();
  90. }
  91. int bbIsMainThread(){
  92. return GetCurrentThreadId()==_mainThread;
  93. }
  94. #elif __linux
  95. #include <unistd.h>
  96. #include <pthread.h>
  97. #include <limits.h>
  98. #include <signal.h>
  99. #include <sys/time.h>
  100. #include <sys/sysinfo.h>
  101. static int base_time;
  102. static pthread_t _mainThread;
  103. static void startup(){
  104. struct sysinfo info;
  105. _mainThread=pthread_self();
  106. sysinfo( &info );
  107. base_time=bbMilliSecs()-info.uptime*1000;
  108. }
  109. //***** ThreadSafe! *****
  110. void bbDelay( int millis ){
  111. int i,e;
  112. if( millis<0 ) return;
  113. e=bbMilliSecs()+millis;
  114. for( i=0;;++i ){
  115. int t=e-bbMilliSecs();
  116. if( t<=0 ){
  117. if( !i ) usleep( 0 ); //always sleep at least once.
  118. break;
  119. }
  120. usleep( t*1000 );
  121. }
  122. }
  123. //***** ThreadSafe! *****
  124. int bbMilliSecs(){
  125. int t;
  126. struct timeval tv;
  127. gettimeofday(&tv,0);
  128. t=tv.tv_sec*1000;
  129. t+=tv.tv_usec/1000;
  130. return t-base_time;
  131. }
  132. int bbIsMainThread(){
  133. return pthread_self()==_mainThread;
  134. }
  135. #endif
  136. void bbStartup( int argc,char *argv[],void *dummy1,void *dummy2 ){
  137. int i,k;
  138. BBString **p;
  139. //Start up GC and create bbAppFile, bbAppDir and bbLaunchDir
  140. #if _WIN32
  141. char *ebp;
  142. OSVERSIONINFO os={ sizeof(os) };
  143. asm( "movl %%ebp,%0;":"=r"(ebp) );//::"%ebp" );
  144. bbGCStackTop=ebp+28;
  145. bbThreadStartup();
  146. bbGCStartup();
  147. if( GetVersionEx( &os ) ){
  148. if( os.dwPlatformId==VER_PLATFORM_WIN32_NT ){
  149. _bbusew=1;
  150. }
  151. }
  152. if( _bbusew ){
  153. int e=0;
  154. wchar_t buf[MAX_PATH];
  155. _wgetcwd( buf,MAX_PATH );
  156. for( i=0;buf[i];++i ){
  157. if( buf[i]=='\\' ) buf[i]='/';
  158. }
  159. bbLaunchDir=bbStringFromWString( buf );
  160. GetModuleFileNameW( GetModuleHandleW(0),buf,MAX_PATH );
  161. for( i=0;buf[i];++i ){
  162. if( buf[i]=='\\' ) buf[i]='/';
  163. if( buf[i]=='/' ) e=i;
  164. }
  165. bbAppFile=bbStringFromWString( buf );
  166. if( e ){
  167. if( buf[e-1]==':' ) ++e;
  168. bbAppDir=bbStringFromShorts( buf,e );
  169. }else{
  170. bbAppDir=&bbEmptyString;
  171. }
  172. _wchdir( bbTmpWString( bbAppDir ) );
  173. }else{
  174. int e=0;
  175. char buf[MAX_PATH];
  176. _getcwd( buf,MAX_PATH );
  177. for( i=0;buf[i];++i ){
  178. if( buf[i]=='\\' ) buf[i]='/';
  179. }
  180. bbLaunchDir=bbStringFromCString( buf );
  181. GetModuleFileNameA( GetModuleHandleA(0),buf,MAX_PATH );
  182. for( i=0;buf[i];++i ){
  183. if( buf[i]=='\\' ) buf[i]='/';
  184. if( buf[i]=='/' ) e=i;
  185. }
  186. bbAppFile=bbStringFromCString( buf );
  187. if( e ){
  188. if( buf[e-1]==':' ) ++e;
  189. bbAppDir=bbStringFromBytes( buf,e );
  190. }else{
  191. bbAppDir=&bbEmptyString;
  192. }
  193. _chdir( bbTmpCString( bbAppDir ) );
  194. }
  195. #elif __linux
  196. char *ebp;
  197. char buf[PATH_MAX];
  198. char lnk[PATH_MAX];
  199. pid_t pid;
  200. asm( "movl %%ebp,%0;":"=r"(ebp) );//::"%ebp" );
  201. bbGCStackTop=ebp+28;
  202. bbThreadStartup();
  203. bbGCStartup();
  204. getcwd( buf,PATH_MAX );
  205. bbLaunchDir=bbStringFromUTF8String( buf );
  206. pid=getpid();
  207. sprintf( lnk,"/proc/%i/exe",pid );
  208. i=readlink( lnk,buf,PATH_MAX );
  209. if( i>0 ){
  210. char *p;
  211. buf[i]=0;
  212. bbAppFile=bbStringFromUTF8String( buf );
  213. p=strrchr( buf,'/' );
  214. if( p ){
  215. *p=0;
  216. bbAppDir=bbStringFromUTF8String( buf );
  217. }else{
  218. bbAppDir=&bbEmptyString;
  219. }
  220. }else{
  221. bbAppFile=&bbEmptyString;
  222. bbAppDir=&bbEmptyString;
  223. }
  224. chdir( bbTmpUTF8String( bbAppDir ) );
  225. #elif __APPLE__
  226. CFURLRef url;
  227. char buf[PATH_MAX],*e;
  228. #if BB_ARGP
  229. bbGCStackTop=bbArgp(0);
  230. #else
  231. bbGCStackTop=&argc;
  232. #endif
  233. bbThreadStartup();
  234. bbGCStartup();
  235. getcwd( buf,PATH_MAX );
  236. bbLaunchDir=bbStringFromUTF8String( buf );
  237. url=CFBundleCopyExecutableURL( CFBundleGetMainBundle() );
  238. CFURLGetFileSystemRepresentation( url,true,(UInt8*)buf,PATH_MAX );
  239. CFRelease( url );
  240. bbAppFile=bbStringFromUTF8String( buf );
  241. if( e=strstr( buf,".app/Contents/MacOS/" ) ){
  242. *e=0;
  243. }
  244. if( e=strrchr( buf,'/' ) ){
  245. *e=0;
  246. bbAppDir=bbStringFromUTF8String( buf );
  247. }else{
  248. bbAppDir=&bbEmptyString;
  249. }
  250. chdir( bbTmpUTF8String( bbAppDir ) );
  251. #endif
  252. BBINCREFS( bbLaunchDir );
  253. BBINCREFS( bbAppDir );
  254. BBINCREFS( bbAppFile );
  255. bbAppTitle=bbStringFromCString( "BlitzMax Application" );
  256. BBINCREFS( bbAppTitle );
  257. bbAppArgs=bbArrayNew1D( "$",argc );
  258. BBINCREFS( bbAppArgs );
  259. p=(BBString**)BBARRAYDATA( bbAppArgs,1 );
  260. for( k=0;k<argc;++k ){
  261. BBString *arg=bbStringFromCString( argv[k] );
  262. BBINCREFS( arg );
  263. *p++=arg;
  264. }
  265. startup();
  266. }
  267. void bbLibStartup(){
  268. startup();
  269. }