bbgraphics.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. #include "std.h"
  2. #include "bbgraphics.h"
  3. #include "bbinput.h"
  4. gxGraphics *gx_graphics;
  5. gxCanvas *gx_canvas;
  6. struct GfxMode{
  7. int w,h,d,caps;
  8. };
  9. class bbImage{
  10. public:
  11. bbImage( const vector<gxCanvas*> &f ):frames(f){
  12. }
  13. ~bbImage(){
  14. for( int k=0;k<frames.size();++k ){
  15. gx_graphics->freeCanvas( frames[k] );
  16. }
  17. }
  18. const vector<gxCanvas*> &getFrames()const{
  19. return frames;
  20. }
  21. void replaceFrame( int n,gxCanvas *c ){
  22. gx_graphics->freeCanvas( frames[n] );
  23. frames[n]=c;
  24. }
  25. private:
  26. vector<gxCanvas*> frames;
  27. };
  28. //degrees to radians
  29. static const float dtor=0.0174532925199432957692369076848861f;
  30. static int gx_driver; //current graphics driver
  31. static bool filter;
  32. static bool auto_dirty;
  33. static bool auto_midhandle;
  34. static set<bbImage*> image_set;
  35. static int curs_x,curs_y;
  36. static gxCanvas *p_canvas;
  37. static gxFont *curr_font;
  38. static unsigned curr_color;
  39. static unsigned curr_clsColor;
  40. static vector<GfxMode> gfx_modes;
  41. static inline void debugImage( bbImage *i,int frame=0 ){
  42. if( debug ){
  43. if( !image_set.count(i) ) RTEX( "Image does not exist" );
  44. if( frame>=i->getFrames().size() ) RTEX( "Image frame out of range" );
  45. }
  46. }
  47. static inline void debugFont( gxFont *f ){
  48. if( debug ){
  49. if( !gx_graphics->verifyFont( f ) ) RTEX( "Font does not exist" );
  50. }
  51. }
  52. static inline void debugCanvas( gxCanvas *c ){
  53. if( debug ){
  54. if( !gx_graphics->verifyCanvas( c ) ) RTEX( "Buffer does not exist" );
  55. }
  56. }
  57. static inline void debugDriver( int n ){
  58. if( debug ){
  59. if( n<1 || n>gx_runtime->numGraphicsDrivers() ){
  60. RTEX( "Illegal graphics driver index" );
  61. }
  62. }
  63. }
  64. static inline void debugMode( int n ){
  65. if( debug ){
  66. if( n<1 || n>gfx_modes.size() ){
  67. RTEX( "Illegal graphics mode index" );
  68. }
  69. }
  70. }
  71. void bbFreeImage( bbImage *i );
  72. static void freeGraphics(){
  73. #ifdef PRO
  74. extern void blitz3d_close();
  75. blitz3d_close();
  76. #endif
  77. while( image_set.size() ) bbFreeImage( *image_set.begin() );
  78. if( p_canvas ){
  79. gx_graphics->freeCanvas( p_canvas );
  80. p_canvas=0;
  81. }
  82. }
  83. #define RED(_X_) ( ((_X_)>>16) & 0xff )
  84. #define GRN(_X_) ( ((_X_)>>8) & 0xff )
  85. #define BLU(_X_) ( (_X_) & 0xff )
  86. static int getPixel( gxCanvas *c,float x,float y ){
  87. debugCanvas( c );
  88. x-=.5f;y-=.5f;
  89. float fx=floor(x),fy=floor(y);
  90. int ix=fx,iy=fy;fx=x-fx;fy=y-fy;
  91. int tl=c->getPixel( ix,iy );
  92. int tr=c->getPixel( ix+1,iy );
  93. int br=c->getPixel( ix+1,iy+1 );
  94. int bl=c->getPixel( ix,iy+1 );
  95. float w1=(1-fx)*(1-fy),w2=fx*(1-fy),w3=(1-fx)*fy,w4=fx*fy;
  96. float r=RED(tl)*w1+RED(tr)*w2+RED(bl)*w3+RED(br)*w4;
  97. float g=GRN(tl)*w1+GRN(tr)*w2+GRN(bl)*w3+GRN(br)*w4;
  98. float b=BLU(tl)*w1+BLU(tr)*w2+BLU(bl)*w3+BLU(br)*w4;
  99. return (int(r+.5f)<<16)|(int(g+.5f)<<8)|int(b+.5f);
  100. }
  101. struct vec2{ float x,y; };
  102. static vec2 vrot( float m[2][2],const vec2 &v ){
  103. vec2 t;t.x=m[0][0]*v.x+m[0][1]*v.y;t.y=m[1][0]*v.x+m[1][1]*v.y;
  104. return t;
  105. }
  106. static float vmin( float a,float b,float c,float d ){
  107. float t=a;if( b<t ) t=b;if( c<t ) t=c;if( d<t ) t=d;return t;
  108. }
  109. static float vmax( float a,float b,float c,float d ){
  110. float t=a;if( b>t ) t=b;if( c>t ) t=c;if( d>t ) t=d;return t;
  111. }
  112. static gxCanvas *tformCanvas( gxCanvas *c,float m[2][2],int x_handle,int y_handle ){
  113. vec2 v,v0,v1,v2,v3;
  114. float i[2][2];
  115. float dt=1.0f/(m[0][0]*m[1][1]-m[1][0]*m[0][1]);
  116. i[0][0]=dt*m[1][1];i[1][0]=-dt*m[1][0];
  117. i[0][1]=-dt*m[0][1];i[1][1]=dt*m[0][0];
  118. float ox=x_handle,oy=y_handle;
  119. v0.x=-ox;v0.y=-oy; //tl
  120. v1.x=c->getWidth()-ox;v1.y=-oy; //tr
  121. v2.x=c->getWidth()-ox;v2.y=c->getHeight()-oy; //br
  122. v3.x=-ox;v3.y=c->getHeight()-oy; //bl
  123. v0=vrot(m,v0);v1=vrot(m,v1);v2=vrot(m,v2);v3=vrot(m,v3);
  124. float minx=floor( vmin( v0.x,v1.x,v2.x,v3.x ) );
  125. float miny=floor( vmin( v0.y,v1.y,v2.y,v3.y ) );
  126. float maxx=ceil( vmax( v0.x,v1.x,v2.x,v3.x ) );
  127. float maxy=ceil( vmax( v0.y,v1.y,v2.y,v3.y ) );
  128. int iw=maxx-minx,ih=maxy-miny;
  129. gxCanvas *t=gx_graphics->createCanvas( iw,ih,0 );
  130. t->setHandle( -minx,-miny );
  131. t->setMask( c->getMask() );
  132. c->lock();
  133. t->lock();
  134. v.y=miny+.5f;
  135. for( int y=0;y<ih;++v.y,++y ){
  136. v.x=minx+.5f;
  137. for( int x=0;x<iw;++v.x,++x ){
  138. vec2 q=vrot(i,v);
  139. unsigned rgb=filter ? getPixel( c,q.x+ox,q.y+oy ) : c->getPixel( floor(q.x+ox),floor(q.y+oy) );
  140. t->setPixel( x,y,rgb );
  141. }
  142. }
  143. t->unlock();
  144. c->unlock();
  145. return t;
  146. }
  147. static bool saveCanvas( gxCanvas *c,const string &f ){
  148. ofstream out( f.c_str(),ios::binary );
  149. if( !out.good() ) return false;
  150. int tempsize=(c->getWidth()*3+3)&~3;
  151. BITMAPFILEHEADER bf;
  152. memset( &bf,0,sizeof(bf) );
  153. bf.bfType='MB';
  154. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+tempsize*c->getHeight();
  155. bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
  156. BITMAPINFOHEADER bi;memset( &bi,0,sizeof(bi) );
  157. bi.biSize=sizeof(bi);
  158. bi.biWidth=c->getWidth();
  159. bi.biHeight=c->getHeight();
  160. bi.biPlanes=1;
  161. bi.biBitCount=24;
  162. out.write( (char*)&bf,sizeof(bf) );
  163. out.write( (char*)&bi,sizeof(bi) );
  164. unsigned char *temp=d_new unsigned char[ tempsize ];
  165. memset( temp,0,tempsize );
  166. c->lock();
  167. for( int y=c->getHeight()-1;y>=0;--y ){
  168. unsigned char *dest=temp;
  169. for( int x=0;x<c->getWidth();++x ){
  170. unsigned rgb=c->getPixelFast( x,y );
  171. *dest++=rgb&0xff;
  172. *dest++=(rgb>>8)&0xff;
  173. *dest++=(rgb>>16)&0xff;
  174. }
  175. out.write( (char*)temp,tempsize );
  176. }
  177. c->unlock();
  178. delete [] temp;
  179. return out.good();
  180. }
  181. int bbCountGfxDrivers(){
  182. return gx_runtime->numGraphicsDrivers();
  183. }
  184. BBStr * bbGfxDriverName( int n ){
  185. debugDriver( n );
  186. string t;int caps;
  187. gx_runtime->graphicsDriverInfo( n-1,&t,&caps );
  188. return d_new BBStr( t );
  189. }
  190. void bbSetGfxDriver( int n ){
  191. debugDriver( n );
  192. gfx_modes.clear();
  193. gx_driver=n-1;
  194. }
  195. int bbCountGfxModes(){
  196. gfx_modes.clear();
  197. int n=gx_runtime->numGraphicsModes( gx_driver );
  198. for( int k=0;k<n;++k ){
  199. GfxMode m;
  200. gx_runtime->graphicsModeInfo( gx_driver,k,&m.w,&m.h,&m.d,&m.caps );
  201. gfx_modes.push_back( m );
  202. }
  203. return gfx_modes.size();
  204. }
  205. int bbGfxModeWidth( int n ){
  206. debugMode( n );
  207. return gfx_modes[n-1].w;
  208. }
  209. int bbGfxModeHeight( int n ){
  210. debugMode( n );
  211. return gfx_modes[n-1].h;
  212. }
  213. int bbGfxModeDepth( int n ){
  214. debugMode( n );
  215. return gfx_modes[n-1].d;
  216. }
  217. static int modeExists( int w,int h,int d,bool bb3d ){
  218. int cnt=gx_runtime->numGraphicsModes( gx_driver );
  219. for( int k=0;k<cnt;++k ){
  220. int tw,th,td,tc;
  221. gx_runtime->graphicsModeInfo( gx_driver,k,&tw,&th,&td,&tc );
  222. if( bb3d && !(tc&gxRuntime::GFXMODECAPS_3D) ) continue;
  223. if( w==tw && h==th && d==td ) return 1;
  224. }
  225. return 0;
  226. }
  227. int bbGfxModeExists( int w,int h,int d ){
  228. return modeExists( w,h,d,false );
  229. }
  230. #ifdef PRO
  231. int bbGfxDriver3D( int n ){
  232. debugDriver( n );
  233. string t;int caps;
  234. gx_runtime->graphicsDriverInfo( n-1,&t,&caps );
  235. return (caps & gxRuntime::GFXMODECAPS_3D) ? 1 : 0;
  236. }
  237. int bbCountGfxModes3D(){
  238. gfx_modes.clear();
  239. int n=gx_runtime->numGraphicsModes( gx_driver );
  240. for( int k=0;k<n;++k ){
  241. GfxMode m;
  242. gx_runtime->graphicsModeInfo( gx_driver,k,&m.w,&m.h,&m.d,&m.caps );
  243. if( m.caps & gxRuntime::GFXMODECAPS_3D) gfx_modes.push_back( m );
  244. }
  245. return gfx_modes.size();
  246. }
  247. int bbGfxMode3DExists( int w,int h,int d ){
  248. return modeExists( w,h,d,true );
  249. }
  250. int bbGfxMode3D( int n ){
  251. debugMode( n );
  252. return gfx_modes[n-1].caps & gxRuntime::GFXMODECAPS_3D ? 1 :0;
  253. }
  254. int bbWindowed3D(){
  255. int tc;
  256. gx_runtime->windowedModeInfo( &tc );
  257. return (tc & gxRuntime::GFXMODECAPS_3D) ? 1 : 0;
  258. }
  259. #endif
  260. int bbTotalVidMem(){
  261. return gx_graphics->getTotalVidmem();
  262. }
  263. int bbAvailVidMem(){
  264. return gx_graphics->getAvailVidmem();
  265. }
  266. void bbSetBuffer( gxCanvas *buff ){
  267. debugCanvas( buff );
  268. gx_canvas=buff;
  269. curs_x=curs_y=0;
  270. gx_canvas->setOrigin( 0,0 );
  271. gx_canvas->setViewport( 0,0,gx_canvas->getWidth(),gx_canvas->getHeight() );
  272. gx_canvas->setColor( curr_color );
  273. gx_canvas->setClsColor( curr_clsColor );
  274. gx_canvas->setFont( curr_font );
  275. }
  276. gxCanvas *bbGraphicsBuffer(){
  277. return gx_canvas;
  278. }
  279. int bbLoadBuffer( gxCanvas *c,BBStr *str ){
  280. debugCanvas( c );
  281. string s=*str;delete str;
  282. gxCanvas *t=gx_graphics->loadCanvas( s,0 );
  283. if( !t ) return 0;
  284. float m[2][2];
  285. m[0][0]=(float)c->getWidth()/(float)t->getWidth();
  286. m[1][1]=(float)c->getHeight()/(float)t->getHeight();
  287. m[1][0]=m[0][1]=0;
  288. gxCanvas *p=tformCanvas( t,m,0,0 );
  289. gx_graphics->freeCanvas( t );
  290. int ox,oy;
  291. c->getOrigin( &ox,&oy );c->setOrigin( 0,0 );
  292. c->blit( 0,0,p,0,0,p->getWidth(),p->getHeight(),true );
  293. gx_graphics->freeCanvas( p );
  294. return 1;
  295. }
  296. int bbSaveBuffer( gxCanvas *c,BBStr *str ){
  297. debugCanvas( c );
  298. string t=*str;delete str;
  299. return saveCanvas( c,t ) ? 1 : 0;
  300. }
  301. void bbBufferDirty( gxCanvas *c ){
  302. debugCanvas( c );
  303. c->backup();
  304. }
  305. static void graphics( int w,int h,int d,int flags ){
  306. freeGraphics();
  307. gx_runtime->closeGraphics( gx_graphics );
  308. gx_graphics=gx_runtime->openGraphics( w,h,d,gx_driver,flags );
  309. if( !gx_runtime->idle() ) RTEX( 0 );
  310. if( !gx_graphics ){
  311. RTEX( "Unable to set graphics mode" );
  312. }
  313. curr_clsColor=0;
  314. curr_color=0xffffffff;
  315. curr_font=gx_graphics->getDefaultFont();
  316. gxCanvas *buff=(flags & gxGraphics::GRAPHICS_3D) ?
  317. gx_graphics->getBackCanvas() : gx_graphics->getFrontCanvas();
  318. bbSetBuffer( buff );
  319. }
  320. void bbGraphics( int w,int h,int d,int mode ){
  321. int flags=0;
  322. switch( mode ){
  323. case 0:flags|=debug ? gxGraphics::GRAPHICS_WINDOWED : 0 ;break;
  324. case 1:break;
  325. case 2:flags|=gxGraphics::GRAPHICS_WINDOWED;break;
  326. case 3:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_SCALED;break;
  327. case 6:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_AUTOSUSPEND;break;
  328. case 7:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_SCALED|gxGraphics::GRAPHICS_AUTOSUSPEND;break;
  329. default:RTEX( "Illegal Graphics mode" );
  330. }
  331. graphics( w,h,d,flags );
  332. }
  333. #ifdef PRO
  334. void bbGraphics3D( int w,int h,int d,int mode ){
  335. int flags=gxGraphics::GRAPHICS_3D;
  336. switch( mode ){
  337. case 0:flags|=(debug && bbWindowed3D()) ? gxGraphics::GRAPHICS_WINDOWED : 0 ;break;
  338. case 1:break;
  339. case 2:flags|=gxGraphics::GRAPHICS_WINDOWED;break;
  340. case 3:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_SCALED;break;
  341. case 6:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_AUTOSUSPEND;break;
  342. case 7:flags|=gxGraphics::GRAPHICS_WINDOWED|gxGraphics::GRAPHICS_SCALED|gxGraphics::GRAPHICS_AUTOSUSPEND;break;
  343. default:RTEX( "Illegal Graphics3D mode" );
  344. }
  345. graphics( w,h,d,flags );
  346. extern void blitz3d_open();
  347. blitz3d_open();
  348. }
  349. #endif
  350. void bbEndGraphics(){
  351. freeGraphics();
  352. gx_runtime->closeGraphics( gx_graphics );
  353. gx_graphics=gx_runtime->openGraphics( 400,300,0,0,gxGraphics::GRAPHICS_WINDOWED );
  354. if( !gx_runtime->idle() ) RTEX( 0 );
  355. if( gx_graphics ){
  356. curr_clsColor=0;
  357. curr_color=0xffffffff;
  358. curr_font=gx_graphics->getDefaultFont();
  359. bbSetBuffer( gx_graphics->getFrontCanvas() );
  360. return;
  361. }
  362. RTEX( "Unable to set graphics mode" );
  363. }
  364. int bbGraphicsLost(){
  365. return gx_runtime->graphicsLost();
  366. }
  367. void bbSetGamma( int r,int g,int b,float dr,float dg,float db ){
  368. if( dr<0 ) dr=0;
  369. else if( dr>255.0f ) dr=255.0f;
  370. if( dg<0 ) dg=0;
  371. else if( dg>255.0f ) dg=255.0f;
  372. if( db<0 ) db=0;
  373. else if( db>255.0f ) db=255.0f;
  374. gx_graphics->setGamma( r,g,b,dr,dg,db );
  375. }
  376. void bbUpdateGamma( int calibrate ){
  377. gx_graphics->updateGamma( !!calibrate );
  378. }
  379. float bbGammaRed( int n ){
  380. float dr,dg,db;
  381. gx_graphics->getGamma( n,n,n,&dr,&dg,&db );
  382. return dr;
  383. }
  384. float bbGammaGreen( int n ){
  385. float dr,dg,db;
  386. gx_graphics->getGamma( n,n,n,&dr,&dg,&db );
  387. return dg;
  388. }
  389. float bbGammaBlue( int n ){
  390. float dr,dg,db;
  391. gx_graphics->getGamma( n,n,n,&dr,&dg,&db );
  392. return db;
  393. }
  394. gxCanvas *bbFrontBuffer(){
  395. return gx_graphics->getFrontCanvas();
  396. }
  397. gxCanvas *bbBackBuffer(){
  398. return gx_graphics->getBackCanvas();
  399. }
  400. void bbLockBuffer( gxCanvas *buff ){
  401. if( buff ) debugCanvas( buff );
  402. (buff ? buff : gx_canvas)->lock();
  403. }
  404. void bbUnlockBuffer( gxCanvas *buff ){
  405. if( buff ) debugCanvas( buff );
  406. (buff ? buff : gx_canvas)->unlock();
  407. }
  408. int bbReadPixel( int x,int y,gxCanvas *buff ){
  409. if( buff ) debugCanvas( buff );
  410. return (buff ? buff : gx_canvas)->getPixel( x,y );
  411. }
  412. void bbWritePixel( int x,int y,int argb,gxCanvas *buff ){
  413. if( buff ) debugCanvas( buff );
  414. (buff ? buff : gx_canvas)->setPixel( x,y,argb );
  415. }
  416. int bbReadPixelFast( int x,int y,gxCanvas *buff ){
  417. return (buff ? buff : gx_canvas)->getPixelFast( x,y );
  418. }
  419. void bbWritePixelFast( int x,int y,int argb,gxCanvas *buff ){
  420. (buff ? buff : gx_canvas)->setPixelFast( x,y,argb );
  421. }
  422. void bbCopyPixel( int src_x,int src_y,gxCanvas *src,int dest_x,int dest_y,gxCanvas *buff ){
  423. (buff ? buff : gx_canvas)->copyPixel( dest_x,dest_y,src ? src : gx_canvas,src_x,src_y );
  424. }
  425. void bbCopyPixelFast( int src_x,int src_y,gxCanvas *src,int dest_x,int dest_y,gxCanvas *buff ){
  426. (buff ? buff : gx_canvas)->copyPixelFast( dest_x,dest_y,src ? src : gx_canvas,src_x,src_y );
  427. }
  428. int bbScanLine(){
  429. return gx_graphics->getScanLine();
  430. }
  431. void bbVWait( int n ){
  432. gx_graphics->vwait();
  433. if( !gx_runtime->idle() ) RTEX( 0 );
  434. }
  435. void bbFlip( int vwait ){
  436. gx_graphics->flip( vwait ? true : false );
  437. if( !gx_runtime->idle() ) RTEX( 0 );
  438. }
  439. int bbGraphicsWidth(){
  440. return gx_graphics->getWidth();
  441. }
  442. int bbGraphicsHeight(){
  443. return gx_graphics->getHeight();
  444. }
  445. int bbGraphicsDepth(){
  446. return gx_graphics->getDepth();
  447. }
  448. void bbOrigin( int x,int y ){
  449. gx_canvas->setOrigin( x,y );
  450. }
  451. void bbViewport( int x,int y,int w,int h ){
  452. gx_canvas->setViewport( x,y,w,h );
  453. }
  454. void bbColor( int r,int g,int b ){
  455. gx_canvas->setColor( curr_color=(r<<16)|(g<<8)|b );
  456. }
  457. void bbGetColor( int x,int y ){
  458. gx_canvas->setColor( curr_color=gx_canvas->getPixel( x,y ) );
  459. }
  460. int bbColorRed(){
  461. return (gx_canvas->getColor()>>16)&0xff;
  462. }
  463. int bbColorGreen(){
  464. return (gx_canvas->getColor()>>8)&0xff;
  465. }
  466. int bbColorBlue(){
  467. return gx_canvas->getColor()&0xff;
  468. }
  469. void bbClsColor( int r,int g,int b ){
  470. gx_canvas->setClsColor( curr_clsColor=(r<<16)|(g<<8)|b );
  471. }
  472. void bbSetFont( gxFont *f ){
  473. debugFont( f );
  474. gx_canvas->setFont( curr_font=f );
  475. }
  476. void bbCls(){
  477. gx_canvas->cls();
  478. }
  479. void bbPlot( int x,int y ){
  480. gx_canvas->plot( x,y );
  481. }
  482. void bbLine( int x1,int y1,int x2,int y2 ){
  483. gx_canvas->line( x1,y1,x2,y2 );
  484. }
  485. void bbRect( int x,int y,int w,int h,int solid ){
  486. gx_canvas->rect( x,y,w,h,solid ? true : false );
  487. }
  488. void bbOval( int x,int y,int w,int h,int solid ){
  489. gx_canvas->oval( x,y,w,h,solid ? true : false );
  490. }
  491. void bbText( int x,int y,BBStr *str,int centre_x,int centre_y ){
  492. if( centre_x ) x-=curr_font->getWidth( *str )/2;
  493. if( centre_y ) y-=curr_font->getHeight()/2;
  494. gx_canvas->text( x,y,*str );
  495. delete str;
  496. }
  497. void bbCopyRect( int sx,int sy,int w,int h,int dx,int dy,gxCanvas *src,gxCanvas *dest ){
  498. if( src ) debugCanvas( src );
  499. else src=gx_canvas;
  500. if( dest ) debugCanvas( dest );
  501. else dest=gx_canvas;
  502. dest->blit( dx,dy,src,sx,sy,w,h,true );
  503. }
  504. gxFont *bbLoadFont( BBStr *name,int height,int bold,int italic,int underline ){
  505. int flags=
  506. (bold ? gxFont::FONT_BOLD : 0 ) |
  507. (italic ? gxFont::FONT_ITALIC : 0 ) |
  508. (underline ? gxFont::FONT_UNDERLINE : 0 );
  509. gxFont *font=gx_graphics->loadFont( *name,height,flags );
  510. delete name;
  511. return font;
  512. }
  513. void bbFreeFont( gxFont *f ){
  514. debugFont( f );
  515. if( f==curr_font ) bbSetFont( gx_graphics->getDefaultFont() );
  516. gx_graphics->freeFont( f );
  517. }
  518. int bbFontWidth(){
  519. return curr_font->getWidth();
  520. }
  521. int bbFontHeight(){
  522. return curr_font->getHeight();
  523. }
  524. int bbStringWidth( BBStr *str ){
  525. string t=*str;delete str;
  526. return curr_font->getWidth( t );
  527. }
  528. int bbStringHeight( BBStr *str ){
  529. delete str;
  530. return curr_font->getHeight();
  531. }
  532. gxMovie *bbOpenMovie( BBStr *s ){
  533. gxMovie *movie=gx_graphics->openMovie( *s,0 );delete s;
  534. return movie;
  535. }
  536. int bbDrawMovie( gxMovie *movie,int x,int y,int w,int h ){
  537. if( w<0 ) w=movie->getWidth();
  538. if( h<0 ) h=movie->getHeight();
  539. int playing=movie->draw( gx_canvas,x,y,w,h );
  540. if( !gx_runtime->idle() ) RTEX( 0 );
  541. return playing;
  542. }
  543. int bbMovieWidth( gxMovie *movie ){
  544. return movie->getWidth();
  545. }
  546. int bbMovieHeight( gxMovie *movie ){
  547. return movie->getHeight();
  548. }
  549. int bbMoviePlaying( gxMovie *movie ){
  550. return movie->isPlaying();
  551. }
  552. void bbCloseMovie( gxMovie *movie ){
  553. gx_graphics->closeMovie( movie );
  554. }
  555. bbImage *bbLoadImage( BBStr *s ){
  556. string t=*s;delete s;
  557. gxCanvas *c=gx_graphics->loadCanvas( t,0 );
  558. if( !c ) return 0;
  559. if( auto_dirty ) c->backup();
  560. if( auto_midhandle ) c->setHandle( c->getWidth()/2,c->getHeight()/2 );
  561. vector<gxCanvas*> frames;
  562. frames.push_back( c );
  563. bbImage *i=d_new bbImage( frames );
  564. image_set.insert( i );
  565. return i;
  566. }
  567. bbImage *bbLoadAnimImage( BBStr *s,int w,int h,int first,int cnt ){
  568. string t=*s;delete s;
  569. if( cnt<1 ) RTEX( "Illegal frame count" );
  570. if( first<0 ) RTEX( "Illegal first frame" );
  571. gxCanvas *pic=gx_graphics->loadCanvas( t,gxCanvas::CANVAS_NONDISPLAY );
  572. if( !pic ) return 0;
  573. //frames per row, per picture
  574. int fpr=pic->getWidth()/w;
  575. int fpp=pic->getHeight()/h*fpr;
  576. if( first+cnt>fpp ){
  577. gx_graphics->freeCanvas( pic );
  578. RTEX( "Not enough frames in bitmap" );
  579. }
  580. //x,y of first frame...
  581. vector<gxCanvas*> frames;
  582. int src_x=first%fpr*w,src_y=first/fpr*h;
  583. for( int k=0;k<cnt;++k ){
  584. gxCanvas *c=gx_graphics->createCanvas( w,h,0 );
  585. if( !c ){
  586. for( --k;k>=0;--k ) gx_graphics->freeCanvas( frames[k] );
  587. gx_graphics->freeCanvas( pic );return 0;
  588. }
  589. c->blit( 0,0,pic,src_x,src_y,w,h,true );
  590. if( auto_dirty ) c->backup();
  591. if( auto_midhandle ) c->setHandle( c->getWidth()/2,c->getHeight()/2 );
  592. frames.push_back( c );
  593. src_x+=w;if( src_x+w>pic->getWidth() ){ src_x=0;src_y+=h; }
  594. }
  595. gx_graphics->freeCanvas( pic );
  596. bbImage *i=d_new bbImage( frames );
  597. image_set.insert( i );
  598. return i;
  599. }
  600. bbImage *bbCopyImage( bbImage *i ){
  601. debugImage( i );
  602. vector<gxCanvas*> frames;
  603. const vector<gxCanvas*> &f=i->getFrames();
  604. for( int k=0;k<f.size();++k ){
  605. gxCanvas *t=f[k];
  606. gxCanvas *c=gx_graphics->createCanvas( t->getWidth(),t->getHeight(),0 );
  607. if( !c ){
  608. for( --k;k>=0;--k ) gx_graphics->freeCanvas( frames[k] );
  609. return 0;
  610. }
  611. int x,y;
  612. t->getHandle( &x,&y );
  613. t->setHandle( 0,0 );
  614. c->blit( 0,0,t,0,0,t->getWidth(),t->getHeight(),true );
  615. if( auto_dirty ) c->backup();
  616. t->setHandle( x,y );
  617. c->setHandle( x,y );
  618. c->setMask( t->getMask() );
  619. frames.push_back( c );
  620. }
  621. bbImage *t=d_new bbImage( frames );
  622. image_set.insert( t );
  623. return t;
  624. }
  625. bbImage *bbCreateImage( int w,int h,int n ){
  626. vector<gxCanvas*> frames;
  627. for( int k=0;k<n;++k ){
  628. gxCanvas *c=gx_graphics->createCanvas( w,h,0 );
  629. if( !c ){
  630. for( --k;k>=0;--k ) gx_graphics->freeCanvas( frames[k] );
  631. return 0;
  632. }
  633. if( auto_dirty ) c->backup();
  634. if( auto_midhandle ) c->setHandle( c->getWidth()/2,c->getHeight()/2 );
  635. frames.push_back( c );
  636. }
  637. bbImage *i=d_new bbImage( frames );
  638. image_set.insert( i );
  639. return i;
  640. }
  641. void bbFreeImage( bbImage *i ){
  642. if( !image_set.erase(i) ) return;
  643. const vector<gxCanvas*> &f=i->getFrames();
  644. for( int k=0;k<f.size();++k ){
  645. if( f[k]==gx_canvas ){
  646. bbSetBuffer( gx_graphics->getFrontCanvas() );
  647. break;
  648. }
  649. }
  650. delete i;
  651. }
  652. int bbSaveImage( bbImage *i,BBStr *str,int n ){
  653. debugImage( i,n );
  654. string t=*str;delete str;
  655. gxCanvas *c=i->getFrames()[n];
  656. return saveCanvas( c,t ) ? 1 : 0;
  657. }
  658. void bbGrabImage( bbImage *i,int x,int y,int n ){
  659. debugImage( i,n );
  660. gxCanvas *c=i->getFrames()[n];
  661. int src_ox,src_oy,dst_hx,dst_hy;
  662. gx_canvas->getOrigin( &src_ox,&src_oy );
  663. c->getHandle( &dst_hx,&dst_hy );
  664. x+=src_ox-dst_hx;y+=src_oy-dst_hy;
  665. c->setViewport( 0,0,c->getWidth(),c->getHeight() );
  666. c->blit( 0,0,gx_canvas,x,y,c->getWidth(),c->getHeight(),true );
  667. if( auto_dirty ) c->backup();
  668. }
  669. gxCanvas *bbImageBuffer( bbImage *i,int n ){
  670. debugImage( i,n );
  671. return i->getFrames()[n];
  672. }
  673. void bbDrawImage( bbImage *i,int x,int y,int frame ){
  674. debugImage( i,frame );
  675. gxCanvas *c=i->getFrames()[frame];
  676. gx_canvas->blit( x,y,c,0,0,c->getWidth(),c->getHeight(),false );
  677. }
  678. void bbDrawBlock( bbImage *i,int x,int y,int frame ){
  679. debugImage( i,frame );
  680. gxCanvas *c=i->getFrames()[frame];
  681. gx_canvas->blit( x,y,c,0,0,c->getWidth(),c->getHeight(),true );
  682. }
  683. static void tile( bbImage *i,int x,int y,int frame,bool solid ){
  684. gxCanvas *c=i->getFrames()[frame];
  685. int hx,hy;
  686. c->getHandle( &hx,&hy );
  687. int w=c->getWidth(),h=c->getHeight();
  688. int ox,oy,vp_x,vp_y,vp_w,vp_h;
  689. gx_canvas->getOrigin( &ox,&oy );
  690. gx_canvas->getViewport( &vp_x,&vp_y,&vp_w,&vp_h );
  691. int dx=vp_x-ox+hx;
  692. int dy=vp_y-oy+hy;
  693. x-=dx;
  694. y-=dy;
  695. dx+=(x>=0?x%w:w-(-x%w));
  696. dy+=(y>=0?y%h:h-(-y%h));
  697. for( y=-h;y<vp_h;y+=h ){
  698. for( x=-w;x<vp_w;x+=w ){
  699. gx_canvas->blit( x+dx,y+dy,c,0,0,w,h,solid );
  700. }
  701. }
  702. }
  703. void bbTileImage( bbImage *i,int x,int y,int frame ){
  704. debugImage( i,frame );
  705. tile( i,x,y,frame,false );
  706. }
  707. void bbTileBlock( bbImage *i,int x,int y,int frame ){
  708. debugImage( i,frame );
  709. tile( i,x,y,frame,true );
  710. }
  711. void bbDrawImageRect( bbImage *i,int x,int y,int r_x,int r_y,int r_w,int r_h,int frame ){
  712. debugImage( i,frame );
  713. gxCanvas *c=i->getFrames()[frame];
  714. gx_canvas->blit( x,y,c,r_x,r_y,r_w,r_h,false );
  715. }
  716. void bbDrawBlockRect( bbImage *i,int x,int y,int r_x,int r_y,int r_w,int r_h,int frame ){
  717. debugImage( i,frame );
  718. gxCanvas *c=i->getFrames()[frame];
  719. gx_canvas->blit( x,y,c,r_x,r_y,r_w,r_h,true );
  720. }
  721. void bbMaskImage( bbImage *i,int r,int g,int b ){
  722. debugImage( i );
  723. unsigned argb=(r<<16)|(g<<8)|b;
  724. const vector<gxCanvas*> &f=i->getFrames();
  725. for( int k=0;k<f.size();++k ) f[k]->setMask( argb );
  726. }
  727. void bbHandleImage( bbImage *i,int x,int y ){
  728. debugImage( i );
  729. const vector<gxCanvas*> &f=i->getFrames();
  730. for( int k=0;k<f.size();++k ) f[k]->setHandle( x,y );
  731. }
  732. void bbMidHandle( bbImage *i ){
  733. debugImage( i );
  734. const vector<gxCanvas*> &f=i->getFrames();
  735. for( int k=0;k<f.size();++k ) f[k]->setHandle( f[k]->getWidth()/2,f[k]->getHeight()/2 );
  736. }
  737. void bbAutoMidHandle( int enable ){
  738. auto_midhandle=enable ? true : false;
  739. }
  740. int bbImageWidth( bbImage *i ){
  741. debugImage( i );
  742. return i->getFrames()[0]->getWidth();
  743. }
  744. int bbImageHeight( bbImage *i ){
  745. debugImage( i );
  746. return i->getFrames()[0]->getHeight();
  747. }
  748. int bbImageXHandle( bbImage *i ){
  749. debugImage( i );
  750. int x,y;
  751. i->getFrames()[0]->getHandle( &x,&y );
  752. return x;
  753. }
  754. int bbImageYHandle( bbImage *i ){
  755. debugImage( i );
  756. int x,y;
  757. i->getFrames()[0]->getHandle( &x,&y );
  758. return y;
  759. }
  760. int bbImagesOverlap( bbImage *i1,int x1,int y1,bbImage *i2,int x2,int y2 ){
  761. debugImage( i1 );
  762. debugImage( i2 );
  763. gxCanvas *c1=i1->getFrames()[0];
  764. gxCanvas *c2=i2->getFrames()[0];
  765. return c1->collide( x1,y1,c2,x2,y2,true );
  766. }
  767. int bbImagesCollide( bbImage *i1,int x1,int y1,int f1,bbImage *i2,int x2,int y2,int f2 ){
  768. debugImage( i1,f1 );
  769. debugImage( i2,f2 );
  770. gxCanvas *c1=i1->getFrames()[f1];
  771. gxCanvas *c2=i2->getFrames()[f2];
  772. return c1->collide( x1,y1,c2,x2,y2,false );
  773. }
  774. int bbRectsOverlap( int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 ){
  775. if( x1+w1<=x2 || x1>=x2+w2 || y1+h1<=y2 || y1>=y2+h2 ) return 0;
  776. return 1;
  777. }
  778. int bbImageRectOverlap( bbImage *i,int x,int y,int x2,int y2,int w2,int h2 ){
  779. debugImage( i );
  780. gxCanvas *c=i->getFrames()[0];
  781. return c->rect_collide( x,y,x2,y2,w2,h2,true );
  782. }
  783. int bbImageRectCollide( bbImage *i,int x,int y,int f,int x2,int y2,int w2,int h2 ){
  784. debugImage( i,f );
  785. gxCanvas *c=i->getFrames()[f];
  786. return c->rect_collide( x,y,x2,y2,w2,h2,false );
  787. }
  788. void bbTFormImage( bbImage *i,float a,float b,float c,float d ){
  789. debugImage( i );
  790. const vector<gxCanvas*> &f=i->getFrames();
  791. int k;
  792. for( k=0;k<f.size();++k ){
  793. if( f[k]==gx_canvas ){
  794. bbSetBuffer( gx_graphics->getFrontCanvas() );
  795. break;
  796. }
  797. }
  798. float m[2][2];
  799. m[0][0]=a;m[1][0]=b;m[0][1]=c;m[1][1]=d;
  800. for( k=0;k<f.size();++k ){
  801. gxCanvas *c=f[k];
  802. int hx,hy;c->getHandle( &hx,&hy );
  803. gxCanvas *t=tformCanvas( c,m,hx,hy );
  804. i->replaceFrame( k,t );
  805. t->backup();
  806. }
  807. }
  808. void bbScaleImage( bbImage *i,float w,float h ){
  809. debugImage( i );
  810. bbTFormImage( i,w,0,0,h );
  811. }
  812. void bbResizeImage( bbImage *i,float w,float h ){
  813. debugImage( i );
  814. gxCanvas *c=i->getFrames()[0];
  815. bbTFormImage( i,w/(float)c->getWidth(),0,0,h/(float)c->getHeight() );
  816. }
  817. void bbRotateImage( bbImage *i,float d ){
  818. debugImage( i );
  819. d*=-dtor;
  820. bbTFormImage( i,cos(d),-sin(d),sin(d),cos(d) );
  821. }
  822. void bbTFormFilter( int enable ){
  823. filter=enable ? true : false;
  824. }
  825. static int p_ox,p_oy,p_hx,p_hy,p_vpx,p_vpy,p_vpw,p_vph;
  826. static gxCanvas *startPrinting(){
  827. gxCanvas *c=gx_graphics->getFrontCanvas();
  828. c->lock();
  829. c->unlock();
  830. c->getOrigin( &p_ox,&p_oy );
  831. c->getHandle( &p_hx,&p_hy );
  832. c->getViewport( &p_vpx,&p_vpy,&p_vpw,&p_vph );
  833. c->setOrigin( 0,0 );
  834. c->setHandle( 0,0 );
  835. c->setViewport( 0,0,c->getWidth(),c->getHeight() );
  836. if( c!=gx_canvas ){
  837. c->setFont( curr_font );
  838. c->setColor( curr_color );
  839. }
  840. int dy=curs_y+curr_font->getHeight()-c->getHeight();
  841. if( dy>0 ){
  842. curs_y=c->getHeight()-curr_font->getHeight();
  843. c->blit( 0,0,c,0,dy,c->getWidth(),c->getHeight()-dy,true );
  844. c->setColor( curr_clsColor );
  845. c->rect( 0,c->getHeight()-dy,c->getWidth(),dy,true );
  846. c->setColor( curr_color );
  847. }
  848. return c;
  849. }
  850. static void endPrinting( gxCanvas *c ){
  851. c->setViewport( p_vpx,p_vpy,p_vpw,p_vph );
  852. c->setHandle( p_hx,p_hy );
  853. c->setOrigin( p_ox,p_oy );
  854. if( c==gx_canvas ) c->setColor( curr_color );
  855. if( !gx_runtime->idle() ) RTEX( 0 );
  856. }
  857. void bbWrite( BBStr *str ){
  858. gxCanvas *c=startPrinting();
  859. c->text( curs_x,curs_y,*str );
  860. curs_x+=curr_font->getWidth( *str );
  861. endPrinting( c );
  862. delete str;
  863. }
  864. void bbPrint( BBStr *str ){
  865. gxCanvas *c=startPrinting();
  866. c->text( curs_x,curs_y,*str );
  867. curs_x=0;
  868. curs_y+=curr_font->getHeight();
  869. endPrinting( c );
  870. delete str;
  871. }
  872. BBStr *bbInput( BBStr *prompt ){
  873. gxCanvas *c=startPrinting();
  874. string t=*prompt;delete prompt;
  875. //get temp canvas
  876. if( !p_canvas || p_canvas->getWidth()<c->getWidth() || p_canvas->getHeight()<curr_font->getHeight()*2 ){
  877. if( p_canvas ) gx_graphics->freeCanvas( p_canvas );
  878. p_canvas=gx_graphics->createCanvas( c->getWidth(),curr_font->getHeight()*2,0 );
  879. if( !p_canvas ){
  880. endPrinting(c);
  881. return d_new BBStr();
  882. }
  883. }
  884. //draw prompt
  885. c->text( curs_x,curs_y,t );
  886. curs_x+=curr_font->getWidth( t );
  887. p_canvas->setFont( curr_font );
  888. p_canvas->setColor( curr_color );
  889. p_canvas->blit( 0,0,c,0,curs_y,c->getWidth(),curr_font->getHeight(),true );
  890. string str;
  891. bool go=true;
  892. int curs=0,last_key=0,last_time,rep_delay;
  893. while( go ){
  894. //render all text
  895. //calc curs x and width
  896. int cx=curs_x+curr_font->getWidth( str.substr( 0,curs ) );
  897. int cw=curr_font->getWidth( curs<str.size() ? str.substr( curs,1 ) : "X" );
  898. //wait for a key
  899. int key=0,st=gx_runtime->getMilliSecs(),tc=-1;
  900. while( gx_runtime->idle() ){
  901. int t=gx_runtime->getMilliSecs();
  902. int n=(t-st)/320;
  903. if( n!=tc ){
  904. tc=n;
  905. if( !(tc&1) ){ //cursor ON
  906. c->setColor( curr_clsColor^0xffffff );
  907. c->rect( cx,curs_y,cw,curr_font->getHeight(),true );
  908. c->setColor( curr_clsColor );
  909. }else{ //cursor OFF
  910. c->blit( cx,curs_y,p_canvas,cx,0,cw,curr_font->getHeight(),true );
  911. c->setColor( curr_color );
  912. }
  913. c->text( cx,curs_y,str.substr( curs,1 ) );
  914. }
  915. if( key=gx_keyboard->getKey() ){
  916. if( int asc=gx_input->toAscii( key ) ){
  917. rep_delay=280;
  918. last_key=key;
  919. last_time=t;
  920. key=asc;
  921. break;
  922. }
  923. }
  924. if( last_key && gx_keyboard->keyDown( last_key ) ){
  925. if( t-last_time>rep_delay ){
  926. if( key=gx_input->toAscii( last_key ) ){
  927. last_time+=rep_delay;
  928. rep_delay=40;
  929. break;
  930. }
  931. }
  932. }else last_key=0;
  933. gx_runtime->delay( 20 );
  934. }
  935. //check the key
  936. switch( key ){
  937. case 0:
  938. go=false;
  939. str="";
  940. break;
  941. case 8:
  942. if( curs ){
  943. str=str.substr( 0,curs-1 )+str.substr( curs );
  944. --curs;
  945. }
  946. break;
  947. case 27:
  948. curs=0;str="";
  949. break;
  950. case gxInput::ASC_DELETE:
  951. if( curs<str.size() ) str=str.substr( 0,curs )+str.substr( curs+1 );
  952. break;
  953. case gxInput::ASC_HOME:
  954. curs=0;
  955. break;
  956. case gxInput::ASC_END:
  957. curs=str.size();
  958. break;
  959. case gxInput::ASC_LEFT:
  960. if( curs ) --curs;
  961. break;
  962. case gxInput::ASC_RIGHT:
  963. if( curs<str.size() ) ++curs;
  964. break;
  965. case '\r':
  966. go=false;
  967. break;
  968. default:
  969. if( curr_font->isPrintable( key ) ){
  970. str=str.substr(0,curs)+char(key)+str.substr(curs);
  971. ++curs;
  972. }
  973. }
  974. //render text
  975. p_canvas->blit( 0,curr_font->getHeight(),p_canvas,0,0,c->getWidth(),curr_font->getHeight(),true );
  976. p_canvas->text( curs_x,curr_font->getHeight(),str );
  977. c->blit( 0,curs_y,p_canvas,0,curr_font->getHeight(),c->getWidth(),curr_font->getHeight(),true );
  978. }
  979. curs_x=0;
  980. curs_y+=curr_font->getHeight();
  981. endPrinting( c );
  982. return d_new BBStr( str );
  983. }
  984. void bbLocate( int x,int y ){
  985. gxCanvas *c=gx_graphics->getFrontCanvas();
  986. curs_x=x<0 ? 0 : (x > c->getWidth() ? c->getWidth() : x);
  987. curs_y=y<0 ? 0 : (y > c->getHeight() ? c->getHeight() : y);
  988. }
  989. void bbShowPointer(){
  990. gx_runtime->setPointerVisible( true );
  991. }
  992. void bbHidePointer(){
  993. gx_runtime->setPointerVisible( false );
  994. }
  995. bool graphics_create(){
  996. p_canvas=0;
  997. filter=true;
  998. gx_driver=0;
  999. freeGraphics();
  1000. auto_dirty=true;
  1001. auto_midhandle=false;
  1002. gx_graphics=gx_runtime->openGraphics( 400,300,0,0,gxGraphics::GRAPHICS_WINDOWED );
  1003. if( gx_graphics ){
  1004. curr_clsColor=0;
  1005. curr_color=0xffffffff;
  1006. curr_font=gx_graphics->getDefaultFont();
  1007. bbSetBuffer( bbFrontBuffer() );
  1008. return true;
  1009. }
  1010. return false;
  1011. }
  1012. bool graphics_destroy(){
  1013. freeGraphics();
  1014. gfx_modes.clear();
  1015. if( gx_graphics ){
  1016. gx_runtime->closeGraphics( gx_graphics );
  1017. gx_graphics=0;
  1018. }
  1019. return true;
  1020. }
  1021. void graphics_link( void (*rtSym)( const char *sym,void *pc ) ){
  1022. //gfx driver info
  1023. rtSym( "%CountGfxDrivers",bbCountGfxDrivers );
  1024. rtSym( "$GfxDriverName%driver",bbGfxDriverName );
  1025. rtSym( "SetGfxDriver%driver",bbSetGfxDriver );
  1026. //gfx mode info
  1027. rtSym( "%CountGfxModes",bbCountGfxModes );
  1028. rtSym( "%GfxModeExists%width%height%depth",bbGfxModeExists );
  1029. rtSym( "%GfxModeWidth%mode",bbGfxModeWidth );
  1030. rtSym( "%GfxModeHeight%mode",bbGfxModeHeight );
  1031. rtSym( "%GfxModeDepth%mode",bbGfxModeDepth );
  1032. rtSym( "%AvailVidMem",bbAvailVidMem );
  1033. rtSym( "%TotalVidMem",bbTotalVidMem );
  1034. #ifdef PRO
  1035. rtSym( "%GfxDriver3D%driver",bbGfxDriver3D );
  1036. rtSym( "%CountGfxModes3D",bbCountGfxModes3D );
  1037. rtSym( "%GfxMode3DExists%width%height%depth",bbGfxMode3DExists );
  1038. rtSym( "%GfxMode3D%mode",bbGfxMode3D );
  1039. rtSym( "%Windowed3D",bbWindowed3D );
  1040. #endif
  1041. //display mode
  1042. rtSym( "Graphics%width%height%depth=0%mode=0",bbGraphics );
  1043. #ifdef PRO
  1044. rtSym( "Graphics3D%width%height%depth=0%mode=0",bbGraphics3D );
  1045. #endif
  1046. rtSym( "EndGraphics",bbEndGraphics );
  1047. rtSym( "%GraphicsLost",bbGraphicsLost );
  1048. rtSym( "SetGamma%src_red%src_green%src_blue#dest_red#dest_green#dest_blue",bbSetGamma );
  1049. rtSym( "UpdateGamma%calibrate=0",bbUpdateGamma );
  1050. rtSym( "#GammaRed%red",bbGammaRed );
  1051. rtSym( "#GammaGreen%green",bbGammaGreen );
  1052. rtSym( "#GammaBlue%blue",bbGammaBlue );
  1053. rtSym( "%FrontBuffer",bbFrontBuffer );
  1054. rtSym( "%BackBuffer",bbBackBuffer );
  1055. rtSym( "%ScanLine",bbScanLine );
  1056. rtSym( "VWait%frames=1",bbVWait );
  1057. rtSym( "Flip%vwait=1",bbFlip );
  1058. rtSym( "%GraphicsWidth",bbGraphicsWidth );
  1059. rtSym( "%GraphicsHeight",bbGraphicsHeight );
  1060. rtSym( "%GraphicsDepth",bbGraphicsDepth );
  1061. //buffer management
  1062. rtSym( "SetBuffer%buffer",bbSetBuffer );
  1063. rtSym( "%GraphicsBuffer",bbGraphicsBuffer );
  1064. rtSym( "%LoadBuffer%buffer$bmpfile",bbLoadBuffer );
  1065. rtSym( "%SaveBuffer%buffer$bmpfile",bbSaveBuffer );
  1066. rtSym( "BufferDirty%buffer",bbBufferDirty );
  1067. //fast pixel reads/write
  1068. rtSym( "LockBuffer%buffer=0",bbLockBuffer );
  1069. rtSym( "UnlockBuffer%buffer=0",bbUnlockBuffer );
  1070. rtSym( "%ReadPixel%x%y%buffer=0",bbReadPixel );
  1071. rtSym( "WritePixel%x%y%argb%buffer=0",bbWritePixel );
  1072. rtSym( "%ReadPixelFast%x%y%buffer=0",bbReadPixelFast );
  1073. rtSym( "WritePixelFast%x%y%argb%buffer=0",bbWritePixelFast );
  1074. rtSym( "CopyPixel%src_x%src_y%src_buffer%dest_x%dest_y%dest_buffer=0",bbCopyPixel );
  1075. rtSym( "CopyPixelFast%src_x%src_y%src_buffer%dest_x%dest_y%dest_buffer=0",bbCopyPixelFast );
  1076. //rendering
  1077. rtSym( "Origin%x%y",bbOrigin );
  1078. rtSym( "Viewport%x%y%width%height",bbViewport );
  1079. rtSym( "Color%red%green%blue",bbColor );
  1080. rtSym( "GetColor%x%y",bbGetColor );
  1081. rtSym( "%ColorRed",bbColorRed );
  1082. rtSym( "%ColorGreen",bbColorGreen );
  1083. rtSym( "%ColorBlue",bbColorBlue );
  1084. rtSym( "ClsColor%red%green%blue",bbClsColor );
  1085. rtSym( "SetFont%font",bbSetFont );
  1086. rtSym( "Cls",bbCls );
  1087. rtSym( "Plot%x%y",bbPlot );
  1088. rtSym( "Rect%x%y%width%height%solid=1",bbRect );
  1089. rtSym( "Oval%x%y%width%height%solid=1",bbOval );
  1090. rtSym( "Line%x1%y1%x2%y2",bbLine );
  1091. rtSym( "Text%x%y$text%centre_x=0%centre_y=0",bbText );
  1092. rtSym( "CopyRect%source_x%source_y%width%height%dest_x%dest_y%src_buffer=0%dest_buffer=0",bbCopyRect );
  1093. //fonts
  1094. rtSym( "%LoadFont$fontname%height=12%bold=0%italic=0%underline=0",bbLoadFont );
  1095. rtSym( "FreeFont%font",bbFreeFont );
  1096. rtSym( "%FontWidth",bbFontWidth );
  1097. rtSym( "%FontHeight",bbFontHeight );
  1098. rtSym( "%StringWidth$string",bbStringWidth );
  1099. rtSym( "%StringHeight$string",bbStringHeight );
  1100. //movies
  1101. rtSym( "%OpenMovie$file",bbOpenMovie );
  1102. rtSym( "%DrawMovie%movie%x=0%y=0%w=-1%h=-1",bbDrawMovie );
  1103. rtSym( "%MovieWidth%movie",bbMovieWidth );
  1104. rtSym( "%MovieHeight%movie",bbMovieHeight );
  1105. rtSym( "%MoviePlaying%movie",bbMoviePlaying );
  1106. rtSym( "CloseMovie%movie",bbCloseMovie );
  1107. rtSym( "%LoadImage$bmpfile",bbLoadImage );
  1108. rtSym( "%LoadAnimImage$bmpfile%cellwidth%cellheight%first%count",bbLoadAnimImage );
  1109. rtSym( "%CopyImage%image",bbCopyImage );
  1110. rtSym( "%CreateImage%width%height%frames=1",bbCreateImage );
  1111. rtSym( "FreeImage%image",bbFreeImage );
  1112. rtSym( "%SaveImage%image$bmpfile%frame=0",bbSaveImage );
  1113. rtSym( "GrabImage%image%x%y%frame=0",bbGrabImage );
  1114. rtSym( "%ImageBuffer%image%frame=0",bbImageBuffer );
  1115. rtSym( "DrawImage%image%x%y%frame=0",bbDrawImage );
  1116. rtSym( "DrawBlock%image%x%y%frame=0",bbDrawBlock );
  1117. rtSym( "TileImage%image%x=0%y=0%frame=0",bbTileImage );
  1118. rtSym( "TileBlock%image%x=0%y=0%frame=0",bbTileBlock );
  1119. rtSym( "DrawImageRect%image%x%y%rect_x%rect_y%rect_width%rect_height%frame=0",bbDrawImageRect );
  1120. rtSym( "DrawBlockRect%image%x%y%rect_x%rect_y%rect_width%rect_height%frame=0",bbDrawBlockRect );
  1121. rtSym( "MaskImage%image%red%green%blue",bbMaskImage );
  1122. rtSym( "HandleImage%image%x%y",bbHandleImage );
  1123. rtSym( "MidHandle%image",bbMidHandle );
  1124. rtSym( "AutoMidHandle%enable",bbAutoMidHandle );
  1125. rtSym( "%ImageWidth%image",bbImageWidth );
  1126. rtSym( "%ImageHeight%image",bbImageHeight );
  1127. rtSym( "%ImageXHandle%image",bbImageXHandle );
  1128. rtSym( "%ImageYHandle%image",bbImageYHandle );
  1129. rtSym( "ScaleImage%image#xscale#yscale",bbScaleImage );
  1130. rtSym( "ResizeImage%image#width#height",bbResizeImage );
  1131. rtSym( "RotateImage%image#angle",bbRotateImage );
  1132. rtSym( "TFormImage%image#a#b#c#d",bbTFormImage );
  1133. rtSym( "TFormFilter%enable",bbTFormFilter );
  1134. rtSym( "%ImagesOverlap%image1%x1%y1%image2%x2%y2",bbImagesOverlap );
  1135. rtSym( "%ImagesCollide%image1%x1%y1%frame1%image2%x2%y2%frame2",bbImagesCollide );
  1136. rtSym( "%RectsOverlap%x1%y1%width1%height1%x2%y2%width2%height2",bbRectsOverlap );
  1137. rtSym( "%ImageRectOverlap%image%x%y%rect_x%rect_y%rect_width%rect_height",bbImageRectOverlap );
  1138. rtSym( "%ImageRectCollide%image%x%y%frame%rect_x%rect_y%rect_width%rect_height",bbImageRectCollide );
  1139. rtSym( "Write$string",bbWrite );
  1140. rtSym( "Print$string=\"\"",bbPrint );
  1141. rtSym( "$Input$prompt=\"\"",bbInput );
  1142. rtSym( "Locate%x%y",bbLocate );
  1143. rtSym( "ShowPointer",bbShowPointer );
  1144. rtSym( "HidePointer",bbHidePointer );
  1145. }