| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234 |
- #include "std.h"
- #include "gxruntime.h"
- #include "zmouse.h"
- #define SPI_SETMOUSESPEED 113
- struct gxRuntime::GfxMode{
- DDSURFACEDESC2 desc;
- };
- struct gxRuntime::GfxDriver{
- GUID *guid;
- std::string name;
- std::vector<GfxMode*> modes;
- #ifdef PRO
- D3DDEVICEDESC7 d3d_desc;
- #endif
- };
- static const int static_ws=WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;
- static const int scaled_ws=WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
- static string app_title;
- static string app_close;
- static gxRuntime *runtime;
- static bool busy,suspended;
- static volatile bool run_flag;
- static DDSURFACEDESC2 desktop_desc;
- typedef int (_stdcall *LibFunc)( const void *in,int in_sz,void *out,int out_sz );
- struct gxDll{
- HINSTANCE hinst;
- map<string,LibFunc> funcs;
- };
- static map<string,gxDll*> libs;
- static LRESULT CALLBACK windowProc( HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam );
- //current gfx mode
- //
- //0=NONE
- //1=SCALED WINDOW
- //2=FIXED SIZE WINDOW
- //3=EXCLUSIVE
- //
- static int gfx_mode;
- static bool gfx_lost;
- static bool auto_suspend;
- //for modes 1 and 2
- static int mod_cnt;
- static MMRESULT timerID;
- static IDirectDrawClipper *clipper;
- static IDirectDrawSurface7 *primSurf;
- static Debugger *debugger;
- static set<gxTimer*> timers;
- enum{
- WM_STOP=WM_USER+1,WM_RUN,WM_END
- };
- ////////////////////
- // STATIC STARTUP //
- ////////////////////
- gxRuntime *gxRuntime::openRuntime( HINSTANCE hinst,const string &cmd_line,Debugger *d ){
- if( runtime ) return 0;
- //create debugger
- debugger=d;
- //create WNDCLASS
- WNDCLASS wndclass;
- memset(&wndclass,0,sizeof(wndclass));
- wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
- wndclass.lpfnWndProc=::windowProc;
- wndclass.hInstance=hinst;
- wndclass.lpszClassName="Blitz Runtime Class";
- wndclass.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
- wndclass.hbrBackground=(HBRUSH)GetStockObject( BLACK_BRUSH );
- RegisterClass( &wndclass );
- gfx_mode=0;
- clipper=0;primSurf=0;
- busy=suspended=false;
- run_flag=true;
- const char *app_t=" ";
- int ws=WS_CAPTION,ws_ex=0;
- HWND hwnd=CreateWindowEx( ws_ex,"Blitz Runtime Class",app_t,ws,0,0,0,0,0,0,0,0 );
- UpdateWindow( hwnd );
- runtime=d_new gxRuntime( hinst,cmd_line,hwnd );
- return runtime;
- }
- void gxRuntime::closeRuntime( gxRuntime *r ){
- if( !runtime || runtime!=r ) return;
- map<string,gxDll*>::const_iterator it;
- for( it=libs.begin();it!=libs.end();++it ){
- FreeLibrary( it->second->hinst );
- }
- libs.clear();
- delete runtime;
- runtime=0;
- }
- //////////////////////////
- // RUNTIME CONSTRUCTION //
- //////////////////////////
- typedef int (_stdcall *SetAppCompatDataFunc)( int x,int y );
- gxRuntime::gxRuntime( HINSTANCE hi,const string &cl,HWND hw ):
- hinst(hi),cmd_line(cl),hwnd(hw),curr_driver(0),enum_all(false),
- pointer_visible(true),audio(0),input(0),graphics(0),fileSystem(0),use_di(false){
- CoInitialize( 0 );
- enumGfx();
- TIMECAPS tc;
- timeGetDevCaps( &tc,sizeof(tc) );
- timeBeginPeriod( tc.wPeriodMin );
- memset( &osinfo,0,sizeof(osinfo) );
- osinfo.dwOSVersionInfoSize=sizeof(osinfo);
- GetVersionEx( &osinfo );
- HMODULE ddraw=LoadLibraryA( "ddraw.dll" );
- if( ddraw ){
- SetAppCompatDataFunc SetAppCompatData=(SetAppCompatDataFunc)GetProcAddress( ddraw,"SetAppCompatData" );
- if( SetAppCompatData ) SetAppCompatData( 12,0 );
- FreeLibrary( ddraw );
- }
- }
- gxRuntime::~gxRuntime(){
- while( timers.size() ) freeTimer( *timers.begin() );
- if( audio ) closeAudio( audio );
- if( graphics ) closeGraphics( graphics );
- if( input ) closeInput( input );
- TIMECAPS tc;
- timeGetDevCaps( &tc,sizeof(tc) );
- timeEndPeriod( tc.wPeriodMin );
- denumGfx();
- DestroyWindow( hwnd );
- UnregisterClass( "Blitz Runtime Class",hinst );
- CoUninitialize();
- }
- void gxRuntime::pauseAudio(){
- if( audio ) audio->pause();
- }
- void gxRuntime::resumeAudio(){
- if( audio ) audio->resume();
- }
- void gxRuntime::backupGraphics(){
- if( auto_suspend ){
- graphics->backup();
- }
- }
- void gxRuntime::restoreGraphics(){
- if( auto_suspend ){
- if( !graphics->restore() ) gfx_lost=true;
- }
- }
- void gxRuntime::resetInput(){
- if( input ) input->reset();
- }
- void gxRuntime::acquireInput(){
- if( !input ) return;
- if( gfx_mode==3 ){
- if( use_di ){
- use_di=input->acquire();
- }else{
- }
- }
- input->reset();
- }
- void gxRuntime::unacquireInput(){
- if( !input ) return;
- if( gfx_mode==3 && use_di ) input->unacquire();
- input->reset();
- }
- /////////////
- // SUSPEND //
- /////////////
- void gxRuntime::suspend(){
- busy=true;
- pauseAudio();
- backupGraphics();
- unacquireInput();
- suspended=true;
- busy=false;
- if( gfx_mode==3 ) ShowCursor(1);
- if( debugger ) debugger->debugStop();
- }
- ////////////
- // RESUME //
- ////////////
- void gxRuntime::resume(){
- if( gfx_mode==3 ) ShowCursor(0);
- busy=true;
- acquireInput();
- restoreGraphics();
- resumeAudio();
- suspended=false;
- busy=false;
- if( debugger ) debugger->debugRun();
- }
- ///////////////////
- // FORCE SUSPEND //
- ///////////////////
- void gxRuntime::forceSuspend(){
- if( gfx_mode==3 ){
- SetForegroundWindow( GetDesktopWindow() );
- ShowWindow( GetDesktopWindow(),SW_SHOW );
- }else{
- suspend();
- }
- }
- //////////////////
- // FORCE RESUME //
- //////////////////
- void gxRuntime::forceResume(){
- if( gfx_mode==3 ){
- SetForegroundWindow( hwnd );
- ShowWindow( hwnd,SW_SHOWMAXIMIZED );
- }else{
- resume();
- }
- }
- ///////////
- // PAINT //
- ///////////
- void gxRuntime::paint(){
- switch( gfx_mode ){
- case 0:
- {
- }
- break;
- case 1:case 2: //scaled windowed mode.
- {
- RECT src,dest;
- src.left=src.top=0;
- GetClientRect( hwnd,&dest );
- src.right=gfx_mode==1 ? graphics->getWidth() : dest.right;
- src.bottom=gfx_mode==1 ? graphics->getHeight() : dest.bottom;
- POINT p;p.x=p.y=0;ClientToScreen( hwnd,&p );
- dest.left+=p.x;dest.right+=p.x;
- dest.top+=p.y;dest.bottom+=p.y;
- gxCanvas *f=graphics->getFrontCanvas();
- primSurf->Blt( &dest,f->getSurface(),&src,0,0 );
- }
- break;
- case 3:
- {
- //exclusive mode
- }
- break;
- }
- }
- //////////
- // FLIP //
- //////////
- void gxRuntime::flip( bool vwait ){
- gxCanvas *b=graphics->getBackCanvas();
- gxCanvas *f=graphics->getFrontCanvas();
- int n;
- switch( gfx_mode ){
- case 1:case 2:
- if( vwait ) graphics->vwait();
- f->setModify( b->getModify() );
- if( f->getModify()!=mod_cnt ){
- mod_cnt=f->getModify();
- paint();
- }
- break;
- case 3:
- if( vwait ){
- BOOL vb;
- while( graphics->dirDraw->GetVerticalBlankStatus( &vb )>=0 && vb ) {}
- n=f->getSurface()->Flip( 0,DDFLIP_WAIT );
- }else{
- n=f->getSurface()->Flip( 0,DDFLIP_NOVSYNC|DDFLIP_WAIT );
- }
- if( n>=0 ) return;
- string t="Flip Failed! Return code:"+itoa(n&0x7fff);
- debugLog( t.c_str() );
- break;
- }
- }
- ////////////////
- // MOVE MOUSE //
- ////////////////
- void gxRuntime::moveMouse( int x,int y ){
- POINT p;
- RECT rect;
- switch( gfx_mode ){
- case 1:
- GetClientRect( hwnd,&rect );
- x=x*(rect.right-rect.left)/graphics->getWidth();
- y=y*(rect.bottom-rect.top)/graphics->getHeight();
- case 2:
- p.x=x;p.y=y;ClientToScreen( hwnd,&p );x=p.x;y=p.y;
- break;
- case 3:
- if( use_di ) return;
- break;
- default:
- return;
- }
- SetCursorPos( x,y );
- }
- /////////////////
- // WINDOW PROC //
- /////////////////
- LRESULT gxRuntime::windowProc( HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam ){
- if( busy ){
- return DefWindowProc( hwnd,msg,wparam,lparam );
- }
- PAINTSTRUCT ps;
- //handle 'special' messages!
- switch( msg ){
- case WM_PAINT:
- if( gfx_mode && !auto_suspend ){
- if( !graphics->restore() ) gfx_lost=true;
- }
- BeginPaint( hwnd,&ps );
- paint();
- EndPaint( hwnd,&ps );
- return DefWindowProc( hwnd,msg,wparam,lparam );
- case WM_ERASEBKGND:
- return gfx_mode ? 1 : DefWindowProc( hwnd,msg,wparam,lparam );
- case WM_CLOSE:
- if( app_close.size() ){
- int n=MessageBox( hwnd,app_close.c_str(),app_title.c_str(),MB_OKCANCEL|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST );
- if( n!=IDOK ) return 0;
- }
- asyncEnd();
- return 0;
- case WM_SETCURSOR:
- if( !suspended ){
- if( gfx_mode==3 ){
- SetCursor( 0 );
- return 1;
- }else if( !pointer_visible ){
- POINT p;
- GetCursorPos( &p );
- ScreenToClient( hwnd,&p );
- RECT r;GetClientRect( hwnd,&r );
- if( p.x>=0 && p.y>=0 && p.x<r.right && p.y<r.bottom ){
- SetCursor( 0 );
- return 1;
- }
- }
- }
- break;
- case WM_ACTIVATEAPP:
- if( auto_suspend ){
- if( wparam ){
- if( suspended ) resume();
- }else{
- if( !suspended ) suspend();
- }
- }
- break;
- }
- if( !input || suspended ) return DefWindowProc( hwnd,msg,wparam,lparam );
- if( gfx_mode==3 && use_di ){
- use_di=input->acquire();
- return DefWindowProc( hwnd,msg,wparam,lparam );
- }
- static const int MK_ALLBUTTONS=MK_LBUTTON|MK_RBUTTON|MK_MBUTTON;
- //handle input messages
- switch( msg ){
- case WM_LBUTTONDOWN:
- input->wm_mousedown(1);
- SetCapture(hwnd);
- break;
- case WM_LBUTTONUP:
- input->wm_mouseup(1);
- if( !(wparam&MK_ALLBUTTONS) ) ReleaseCapture();
- break;
- case WM_RBUTTONDOWN:
- input->wm_mousedown(2);
- SetCapture( hwnd );
- break;
- case WM_RBUTTONUP:
- input->wm_mouseup(2);
- if( !(wparam&MK_ALLBUTTONS) ) ReleaseCapture();
- break;
- case WM_MBUTTONDOWN:
- input->wm_mousedown(3);
- SetCapture( hwnd );
- break;
- case WM_MBUTTONUP:
- input->wm_mouseup(3);
- if( !(wparam&MK_ALLBUTTONS) ) ReleaseCapture();
- break;
- case WM_MOUSEMOVE:
- if( !graphics ) break;
- if( gfx_mode==3 && !use_di ){
- POINT p;GetCursorPos( &p );
- input->wm_mousemove( p.x,p.y );
- }else{
- int x=(short)(lparam&0xffff),y=lparam>>16;
- if( gfx_mode==1 ){
- RECT rect;GetClientRect( hwnd,&rect );
- x=x*graphics->getWidth()/(rect.right-rect.left);
- y=y*graphics->getHeight()/(rect.bottom-rect.top);
- }
- if( x<0 ) x=0;
- else if( x>=graphics->getWidth() ) x=graphics->getWidth()-1;
- if( y<0 ) y=0;
- else if( y>=graphics->getHeight() ) y=graphics->getHeight()-1;
- input->wm_mousemove( x,y );
- }
- break;
- case WM_MOUSEWHEEL:
- input->wm_mousewheel( (short)HIWORD( wparam ) );
- break;
- case WM_KEYDOWN:case WM_SYSKEYDOWN:
- if( lparam & 0x40000000 ) break;
- if( int n=((lparam>>17)&0x80)|((lparam>>16)&0x7f) ) input->wm_keydown( n );
- break;
- case WM_KEYUP:case WM_SYSKEYUP:
- if( int n=((lparam>>17)&0x80)|((lparam>>16)&0x7f) ) input->wm_keyup( n );
- break;
- default:
- return DefWindowProc( hwnd,msg,wparam,lparam );
- }
- return 0;
- }
- static LRESULT CALLBACK windowProc( HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam ){
- if( runtime ) return runtime->windowProc( hwnd,msg,wparam,lparam );
- return DefWindowProc( hwnd,msg,wparam,lparam );
- }
- //////////////////////////////
- //STOP FROM EXTERNAL SOURCE //
- //////////////////////////////
- void gxRuntime::asyncStop(){
- PostMessage( hwnd,WM_STOP,0,0 );
- }
- //////////////////////////////
- //RUN FROM EXTERNAL SOURCE //
- //////////////////////////////
- void gxRuntime::asyncRun(){
- PostMessage( hwnd,WM_RUN,0,0 );
- }
- //////////////////////////////
- // END FROM EXTERNAL SOURCE //
- //////////////////////////////
- void gxRuntime::asyncEnd(){
- PostMessage( hwnd,WM_END,0,0 );
- }
- //////////
- // IDLE //
- //////////
- bool gxRuntime::idle(){
- for(;;){
- MSG msg;
- if( suspended && run_flag ){
- GetMessage( &msg,0,0,0 );
- }else{
- if( !PeekMessage( &msg,0,0,0,PM_REMOVE ) ) return run_flag;
- }
- switch( msg.message ){
- case WM_STOP:
- if( !suspended ) forceSuspend();
- break;
- case WM_RUN:
- if( suspended ) forceResume();
- break;
- case WM_END:
- debugger=0;
- run_flag=false;
- break;
- default:
- DispatchMessage( &msg );
- }
- }
- return run_flag;
- }
- ///////////
- // DELAY //
- ///////////
- bool gxRuntime::delay( int ms ){
- int t=timeGetTime()+ms;
- for(;;){
- if( !idle() ) return false;
- int d=t-timeGetTime(); //how long left to wait
- if( d<=0 ) return true;
- if( d>100 ) d=100;
- Sleep( d );
- }
- }
- ///////////////
- // DEBUGSTMT //
- ///////////////
- void gxRuntime::debugStmt( int pos,const char *file ){
- if( debugger ) debugger->debugStmt( pos,file );
- }
- ///////////////
- // DEBUGSTOP //
- ///////////////
- void gxRuntime::debugStop(){
- if( !suspended ) forceSuspend();
- }
- ////////////////
- // DEBUGENTER //
- ////////////////
- void gxRuntime::debugEnter( void *frame,void *env,const char *func ){
- if( debugger ) debugger->debugEnter( frame,env,func );
- }
- ////////////////
- // DEBUGLEAVE //
- ////////////////
- void gxRuntime::debugLeave(){
- if( debugger ) debugger->debugLeave();
- }
- ////////////////
- // DEBUGERROR //
- ////////////////
- void gxRuntime::debugError( const char *t ){
- if( !debugger ) return;
- Debugger *d=debugger;
- asyncEnd();
- if( !suspended ){
- forceSuspend();
- }
- d->debugMsg( t,true );
- }
- ///////////////
- // DEBUGINFO //
- ///////////////
- void gxRuntime::debugInfo( const char *t ){
- if( !debugger ) return;
- Debugger *d=debugger;
- asyncEnd();
- if( !suspended ){
- forceSuspend();
- }
- d->debugMsg( t,false );
- }
- //////////////
- // DEBUGLOG //
- //////////////
- void gxRuntime::debugLog( const char *t ){
- if( debugger ) debugger->debugLog( t );
- }
- /////////////////////////
- // RETURN COMMAND LINE //
- /////////////////////////
- string gxRuntime::commandLine(){
- return cmd_line;
- }
- /////////////
- // EXECUTE //
- /////////////
- bool gxRuntime::execute( const string &cmd_line ){
- if( !cmd_line.size() ) return false;
- //convert cmd_line to cmd and params
- string cmd=cmd_line,params;
- while( cmd.size() && cmd[0]==' ' ) cmd=cmd.substr( 1 );
- if( cmd.find( '\"' )==0 ){
- int n=cmd.find( '\"',1 );
- if( n!=string::npos ){
- params=cmd.substr( n+1 );
- cmd=cmd.substr( 1,n-1 );
- }
- }else{
- int n=cmd.find( ' ' );
- if( n!=string::npos ){
- params=cmd.substr( n+1 );
- cmd=cmd.substr( 0,n );
- }
- }
- while( params.size() && params[0]==' ' ) params=params.substr( 1 );
- while( params.size() && params[params.size()-1]==' ' ) params=params.substr( 0,params.size()-1 );
- SetForegroundWindow( GetDesktopWindow() );
- return (int)ShellExecute( GetDesktopWindow(),0,cmd.c_str(),params.size() ? params.c_str() : 0,0,SW_SHOW )>32;
- }
- ///////////////
- // APP TITLE //
- ///////////////
- void gxRuntime::setTitle( const string &t,const string &e ){
- app_title=t;
- app_close=e;
- SetWindowText( hwnd,app_title.c_str() );
- }
- //////////////////
- // GETMILLISECS //
- //////////////////
- int gxRuntime::getMilliSecs(){
- return timeGetTime();
- }
- /////////////////////
- // POINTER VISIBLE //
- /////////////////////
- void gxRuntime::setPointerVisible( bool vis ){
- if( pointer_visible==vis ) return;
- pointer_visible=vis;
- if( gfx_mode==3 ) return;
- //force a WM_SETCURSOR
- POINT pt;
- GetCursorPos( &pt );
- SetCursorPos( pt.x,pt.y );
- }
- /////////////////
- // AUDIO SETUP //
- /////////////////
- gxAudio *gxRuntime::openAudio( int flags ){
- if( audio ) return 0;
- int f_flags=
- FSOUND_INIT_GLOBALFOCUS|
- FSOUND_INIT_USEDEFAULTMIDISYNTH;
- FSOUND_SetHWND( hwnd );
- if( !FSOUND_Init( 44100,1024,f_flags ) ){
- return 0;
- }
- audio=d_new gxAudio( this );
- return audio;
- }
- void gxRuntime::closeAudio( gxAudio *a ){
- if( !audio || audio!=a ) return;
- delete audio;
- audio=0;
- }
- /////////////////
- // INPUT SETUP //
- /////////////////
- gxInput *gxRuntime::openInput( int flags ){
- if( input ) return 0;
- IDirectInput7 *di;
- if( DirectInputCreateEx( hinst,DIRECTINPUT_VERSION,IID_IDirectInput7,(void**)&di,0 )>=0 ){
- input=d_new gxInput( this,di );
- acquireInput();
- }else{
- debugInfo( "Create DirectInput failed" );
- }
- return input;
- }
- void gxRuntime::closeInput( gxInput *i ){
- if( !input || input!=i ) return;
- unacquireInput();
- delete input;
- input=0;
- }
- /////////////////////////////////////////////////////
- // TIMER CALLBACK FOR AUTOREFRESH OF WINDOWED MODE //
- /////////////////////////////////////////////////////
- static void CALLBACK timerCallback( UINT id,UINT msg,DWORD user,DWORD dw1,DWORD dw2 ){
- if( gfx_mode ){
- gxCanvas *f=runtime->graphics->getFrontCanvas();
- if( f->getModify()!=mod_cnt ){
- mod_cnt=f->getModify();
- InvalidateRect( runtime->hwnd,0,false );
- }
- }
- }
- ////////////////////
- // GRAPHICS SETUP //
- ////////////////////
- void gxRuntime::backupWindowState(){
- GetWindowRect( hwnd,&t_rect );
- t_style=GetWindowLong( hwnd,GWL_STYLE );
- }
- void gxRuntime::restoreWindowState(){
- SetWindowLong( hwnd,GWL_STYLE,t_style );
- SetWindowPos(
- hwnd,0,t_rect.left,t_rect.top,
- t_rect.right-t_rect.left,t_rect.bottom-t_rect.top,
- SWP_NOZORDER|SWP_FRAMECHANGED );
- }
- bool gxRuntime::setDisplayMode( int w,int h,int d,bool d3d,IDirectDraw7 *dirDraw ){
- if( d ) return dirDraw->SetDisplayMode( w,h,d,0,0 )>=0;
- int best_d=0;
- if( d3d ){
- #ifdef PRO
- int bd=curr_driver->d3d_desc.dwDeviceRenderBitDepth;
- if( bd & DDBD_32 ) best_d=32;
- else if( bd & DDBD_24 ) best_d=24;
- else if( bd & DDBD_16 ) best_d=16;
- #endif
- }else{
- int best_n=0;
- for( d=16;d<=32;d+=8 ){
- if( dirDraw->SetDisplayMode( w,h,d,0,0 )<0 ) continue;
- DDCAPS caps={ sizeof(caps) };
- dirDraw->GetCaps( &caps,0 );
- int n=0;
- if( caps.dwCaps & DDCAPS_BLT ) ++n;
- if( caps.dwCaps & DDCAPS_BLTCOLORFILL ) ++n;
- if( caps.dwCKeyCaps & DDCKEYCAPS_SRCBLT ) ++n;
- if( caps.dwCaps2 & DDCAPS2_WIDESURFACES ) ++n;
- if( n==4 ) return true;
- if( n>best_n ){
- best_d=d;
- best_n=n;
- }
- dirDraw->RestoreDisplayMode();
- }
- }
- return best_d ? dirDraw->SetDisplayMode( w,h,best_d,0,0 )>=0 : false;
- }
- gxGraphics *gxRuntime::openWindowedGraphics( int w,int h,int d,bool d3d ){
- IDirectDraw7 *dd;
- if( DirectDrawCreateEx( curr_driver->guid,(void**)&dd,IID_IDirectDraw7,0 )<0 ) return 0;
- //set coop level
- if( dd->SetCooperativeLevel( hwnd,DDSCL_NORMAL )>=0 ){
- //create primary surface
- IDirectDrawSurface7 *ps;
- DDSURFACEDESC2 desc={sizeof(desc)};
- desc.dwFlags=DDSD_CAPS;
- desc.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
- if( dd->CreateSurface( &desc,&ps,0 )>=0 ){
- //create clipper
- IDirectDrawClipper *cp;
- if( dd->CreateClipper( 0,&cp,0 )>=0 ){
- //attach clipper
- if( ps->SetClipper( cp )>=0 ){
- //set clipper HWND
- if( cp->SetHWnd( 0,hwnd )>=0 ){
- //create front buffer
- IDirectDrawSurface7 *fs;
- DDSURFACEDESC2 desc={sizeof(desc)};
- desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS;
- desc.dwWidth=w;desc.dwHeight=h;
- desc.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
- if( d3d ) desc.ddsCaps.dwCaps|=DDSCAPS_3DDEVICE;
- if( dd->CreateSurface( &desc,&fs,0 )>=0 ){
- if( timerID=timeSetEvent( 100,10,timerCallback,0,TIME_PERIODIC ) ){
- //Success!
- clipper=cp;
- primSurf=ps;
- mod_cnt=0;
- fs->AddRef();
- return d_new gxGraphics( this,dd,fs,fs,d3d );
- }
- fs->Release();
- }
- }
- }
- cp->Release();
- }
- ps->Release();
- }
- }
- dd->Release();
- return 0;
- }
- gxGraphics *gxRuntime::openExclusiveGraphics( int w,int h,int d,bool d3d ){
- IDirectDraw7 *dd;
- if( DirectDrawCreateEx( curr_driver->guid,(void**)&dd,IID_IDirectDraw7,0 )<0 ) return 0;
- //Set coop level
- if( dd->SetCooperativeLevel( hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT )>=0 ){
- //Set display mode
- if( setDisplayMode( w,h,d,d3d,dd ) ){
- //create primary surface
- IDirectDrawSurface7 *ps;
- DDSURFACEDESC2 desc={sizeof(desc)};
- desc.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
- desc.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
- desc.dwBackBufferCount=1;
- if( d3d ) desc.ddsCaps.dwCaps|=DDSCAPS_3DDEVICE;
- if( dd->CreateSurface( &desc,&ps,0 )>=0 ){
- //find back surface
- IDirectDrawSurface7 *bs;
- DDSCAPS2 caps={sizeof caps};
- caps.dwCaps=DDSCAPS_BACKBUFFER;
- if( ps->GetAttachedSurface( &caps,&bs )>=0 ){
- return d_new gxGraphics( this,dd,ps,bs,d3d );
- }
- ps->Release();
- }
- dd->RestoreDisplayMode();
- }
- }
- dd->Release();
- return 0;
- }
- gxGraphics *gxRuntime::openGraphics( int w,int h,int d,int driver,int flags ){
- if( graphics ) return 0;
- busy=true;
- bool d3d=flags & gxGraphics::GRAPHICS_3D ? true : false;
- bool windowed=flags & gxGraphics::GRAPHICS_WINDOWED ? true : false;
- if( windowed ) driver=0;
- curr_driver=drivers[driver];
- if( windowed ){
- if( graphics=openWindowedGraphics( w,h,d,d3d ) ){
- gfx_mode=(flags & gxGraphics::GRAPHICS_SCALED) ? 1 : 2;
- auto_suspend=(flags & gxGraphics::GRAPHICS_AUTOSUSPEND) ? true : false;
- int ws,ww,hh;
- if( gfx_mode==1 ){
- ws=scaled_ws;
- RECT c_r;
- GetClientRect( hwnd,&c_r );
- ww=c_r.right-c_r.left;
- hh=c_r.bottom-c_r.top;
- }else{
- ws=static_ws;
- ww=w;
- hh=h;
- }
- SetWindowLong( hwnd,GWL_STYLE,ws );
- SetWindowPos( hwnd,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED );
- RECT w_r,c_r;
- GetWindowRect( hwnd,&w_r );
- GetClientRect( hwnd,&c_r );
- int tw=(w_r.right-w_r.left)-(c_r.right-c_r.left);
- int th=(w_r.bottom-w_r.top)-(c_r.bottom-c_r.top );
- int cx=( GetSystemMetrics( SM_CXSCREEN )-ww )/2;
- int cy=( GetSystemMetrics( SM_CYSCREEN )-hh )/2;
- POINT zz={0,0};
- ClientToScreen( hwnd,&zz );
- int bw=zz.x-w_r.left,bh=zz.y-w_r.top;
- int wx=cx-bw,wy=cy-bh;if( wy<0 ) wy=0; //not above top!
- MoveWindow( hwnd,wx,wy,ww+tw,hh+th,true );
- }
- }else{
- backupWindowState();
- SetWindowLong( hwnd,GWL_STYLE,WS_VISIBLE|WS_POPUP );
- SetWindowPos( hwnd,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED );
- ShowCursor( 0 );
- if( graphics=openExclusiveGraphics( w,h,d,d3d ) ){
- gfx_mode=3;
- auto_suspend=true;
- SetCursorPos(0,0);
- acquireInput();
- }else{
- ShowCursor( 1 );
- restoreWindowState();
- }
- }
- if( !graphics ) curr_driver=0;
- gfx_lost=false;
- busy=false;
- return graphics;
- }
- void gxRuntime::closeGraphics( gxGraphics *g ){
- if( !graphics || graphics!=g ) return;
- auto_suspend=false;
- busy=true;
- unacquireInput();
- if( timerID ){ timeKillEvent( timerID );timerID=0; }
- if( clipper ){ clipper->Release();clipper=0; }
- if( primSurf ){ primSurf->Release();primSurf=0; }
- delete graphics;graphics=0;
- if( gfx_mode==3 ){
- ShowCursor( 1 );
- restoreWindowState();
- }
- gfx_mode=0;
- gfx_lost=false;
- busy=false;
- }
- bool gxRuntime::graphicsLost(){
- return gfx_lost;
- }
- gxFileSystem *gxRuntime::openFileSystem( int flags ){
- if( fileSystem ) return 0;
- fileSystem=d_new gxFileSystem();
- return fileSystem;
- }
- void gxRuntime::closeFileSystem( gxFileSystem *f ){
- if( !fileSystem || fileSystem!=f ) return;
- delete fileSystem;
- fileSystem=0;
- }
- ////////////////////
- // GFX ENUM STUFF //
- ////////////////////
- static HRESULT WINAPI enumMode( DDSURFACEDESC2 *desc,void *context ){
- int dp=desc->ddpfPixelFormat.dwRGBBitCount;
- if( dp==16 || dp==24 || dp==32 ){
- gxRuntime::GfxMode *m=d_new gxRuntime::GfxMode;
- m->desc=*desc;
- gxRuntime::GfxDriver *d=(gxRuntime::GfxDriver*)context;
- d->modes.push_back( m );
- }
- return DDENUMRET_OK;
- }
- #ifdef PRO
- static int maxDevType;
- static HRESULT CALLBACK enumDevice( char *desc,char *name,D3DDEVICEDESC7 *devDesc,void *context ){
- int t=0;
- GUID guid=devDesc->deviceGUID;
- if( guid==IID_IDirect3DRGBDevice ) t=1;
- else if( guid==IID_IDirect3DHALDevice ) t=2;
- else if( guid==IID_IDirect3DTnLHalDevice ) t=3;
- if( t>1 && t>maxDevType ){
- maxDevType=t;
- gxRuntime::GfxDriver *d=(gxRuntime::GfxDriver*)context;
- d->d3d_desc=*devDesc;
- }
- return D3DENUMRET_OK;
- }
- #endif
- static BOOL WINAPI enumDriver( GUID FAR *guid,LPSTR desc,LPSTR name,LPVOID context,HMONITOR hm ){
- IDirectDraw7 *dd;
- if( DirectDrawCreateEx( guid,(void**)&dd,IID_IDirectDraw7,0 )<0 ) return 0;
- if( !guid && !desktop_desc.ddpfPixelFormat.dwRGBBitCount ){
- desktop_desc.dwSize=sizeof(desktop_desc);
- dd->GetDisplayMode( &desktop_desc );
- }
- gxRuntime::GfxDriver *d=d_new gxRuntime::GfxDriver;
- d->guid=guid ? d_new GUID( *guid ) : 0;
- d->name=desc;//string( name )+" "+string( desc );
- #ifdef PRO
- memset( &d->d3d_desc,0,sizeof(d->d3d_desc) );
- IDirect3D7 *dir3d;
- if( dd->QueryInterface( IID_IDirect3D7,(void**)&dir3d )>=0 ){
- maxDevType=0;
- dir3d->EnumDevices( enumDevice,d );
- dir3d->Release();
- }
- #endif
- vector<gxRuntime::GfxDriver*> *drivers=(vector<gxRuntime::GfxDriver*>*)context;
- drivers->push_back( d );
- dd->EnumDisplayModes( 0,0,d,enumMode );
- dd->Release();
- return 1;
- }
- void gxRuntime::enumGfx(){
- denumGfx();
- if( enum_all ){
- DirectDrawEnumerateEx( enumDriver,&drivers,DDENUM_ATTACHEDSECONDARYDEVICES|DDENUM_NONDISPLAYDEVICES );
- }else{
- DirectDrawEnumerateEx( enumDriver,&drivers,0 );
- }
- }
- void gxRuntime::denumGfx(){
- for( int k=0;k<drivers.size();++k ){
- gxRuntime::GfxDriver *d=drivers[k];
- for( int j=0;j<d->modes.size();++j ) delete d->modes[j];
- delete d->guid;
- delete d;
- }
- drivers.clear();
- }
- int gxRuntime::numGraphicsDrivers(){
- if( !enum_all ){
- enum_all=true;
- enumGfx();
- }
- return drivers.size();
- }
- void gxRuntime::graphicsDriverInfo( int driver,string *name,int *c ){
- GfxDriver *g=drivers[driver];
- int caps=0;
- #ifdef PRO
- if( g->d3d_desc.dwDeviceRenderBitDepth ) caps|=GFXMODECAPS_3D;
- #endif
- *name=g->name;
- *c=caps;
- }
- int gxRuntime::numGraphicsModes( int driver ){
- return drivers[driver]->modes.size();
- }
- void gxRuntime::graphicsModeInfo( int driver,int mode,int *w,int *h,int *d,int *c ){
- GfxDriver *g=drivers[driver];
- GfxMode *m=g->modes[mode];
- int caps=0;
- #ifdef PRO
- int bd=0;
- switch( m->desc.ddpfPixelFormat.dwRGBBitCount ){
- case 16:bd=DDBD_16;break;
- case 24:bd=DDBD_24;break;
- case 32:bd=DDBD_32;break;
- }
- if( g->d3d_desc.dwDeviceRenderBitDepth & bd ) caps|=GFXMODECAPS_3D;
- #endif
- *w=m->desc.dwWidth;
- *h=m->desc.dwHeight;
- *d=m->desc.ddpfPixelFormat.dwRGBBitCount;
- *c=caps;
- }
- void gxRuntime::windowedModeInfo( int *c ){
- int caps=0;
- #ifdef PRO
- int bd=0;
- switch( desktop_desc.ddpfPixelFormat.dwRGBBitCount ){
- case 16:bd=DDBD_16;break;
- case 24:bd=DDBD_24;break;
- case 32:bd=DDBD_32;break;
- }
- if( drivers[0]->d3d_desc.dwDeviceRenderBitDepth & bd ) caps|=GFXMODECAPS_3D;
- #endif
- *c=caps;
- }
- gxTimer *gxRuntime::createTimer( int hertz ){
- gxTimer *t=d_new gxTimer( this,hertz );
- timers.insert( t );
- return t;
- }
- void gxRuntime::freeTimer( gxTimer *t ){
- if( !timers.count( t ) ) return;
- timers.erase( t );
- delete t;
- }
- static string toDir( string t ){
- if( t.size() && t[t.size()-1]!='\\' ) t+='\\';
- return t;
- }
- string gxRuntime::systemProperty( const std::string &p ){
- char buff[MAX_PATH+1];
- string t=tolower(p);
- if( t=="cpu" ){
- return "Intel";
- }else if( t=="os" ){
- switch( osinfo.dwMajorVersion ){
- case 3:
- switch( osinfo.dwMinorVersion ){
- case 51:return "Windows NT 3.1";
- }
- break;
- case 4:
- switch( osinfo.dwMinorVersion ){
- case 0:return "Windows 95";
- case 10:return "Windows 98";
- case 90:return "Windows ME";
- }
- break;
- case 5:
- switch( osinfo.dwMinorVersion ){
- case 0:return "Windows 2000";
- case 1:return "Windows XP";
- case 2:return "Windows Server 2003";
- }
- break;
- case 6:
- switch( osinfo.dwMinorVersion ){
- case 0:return "Windows Vista";
- case 1:return "Windows 7";
- }
- break;
- }
- }else if( t=="appdir" ){
- if( GetModuleFileName( 0,buff,MAX_PATH ) ){
- string t=buff;
- int n=t.find_last_of( '\\' );
- if( n!=string::npos ) t=t.substr( 0,n );
- return toDir( t );
- }
- }else if( t=="apphwnd" ){
- return itoa( (int)hwnd );
- }else if( t=="apphinstance" ){
- return itoa( (int)hinst );
- }else if( t=="windowsdir" ){
- if( GetWindowsDirectory( buff,MAX_PATH ) ) return toDir( buff );
- }else if( t=="systemdir" ){
- if( GetSystemDirectory( buff,MAX_PATH ) ) return toDir( buff );
- }else if( t=="tempdir" ){
- if( GetTempPath( MAX_PATH,buff ) ) return toDir( buff );
- }else if( t=="direct3d7" ){
- if( graphics ) return itoa( (int)graphics->dir3d );
- }else if( t=="direct3ddevice7" ){
- if( graphics ) return itoa( (int)graphics->dir3dDev );
- }else if( t=="directdraw7" ){
- if( graphics ) return itoa( (int)graphics->dirDraw );
- }else if( t=="directinput7" ){
- if( input ) return itoa( (int)input->dirInput );
- }
- return "";
- }
- void gxRuntime::enableDirectInput( bool enable ){
- if( use_di=enable ){
- acquireInput();
- }else{
- unacquireInput();
- }
- }
- int gxRuntime::callDll( const std::string &dll,const std::string &func,const void *in,int in_sz,void *out,int out_sz ){
- map<string,gxDll*>::const_iterator lib_it=libs.find( dll );
- if( lib_it==libs.end() ){
- HINSTANCE h=LoadLibrary( dll.c_str() );
- if( !h ) return 0;
- gxDll *t=d_new gxDll;
- t->hinst=h;
- lib_it=libs.insert( make_pair( dll,t ) ).first;
- }
- gxDll *t=lib_it->second;
- map<string,LibFunc>::const_iterator fun_it=t->funcs.find( func );
- if( fun_it==t->funcs.end() ){
- LibFunc f=(LibFunc)GetProcAddress( t->hinst,func.c_str() );
- if( !f ) return 0;
- fun_it=t->funcs.insert( make_pair( func,f ) ).first;
- }
- static void *save_esp;
- _asm{
- mov [save_esp],esp
- };
- int n=fun_it->second( in,in_sz,out,out_sz );
- _asm{
- mov esp,[save_esp]
- };
- return n;
- }
|