Example #1
0
   virtual int Run()
   {
      if (bRun)
      {
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
         hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
         _ASSERTE(SUCCEEDED(hRes));
         hRes = CoResumeClassObjects();
#else
         hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
#endif
         _ASSERTE(SUCCEEDED(hRes));

         INITCOMMONCONTROLSEX iccex;
         iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
         iccex.dwICC = ICC_COOL_CLASSES;
         InitCommonControlsEx(&iccex);

         {
            EditableRegistry::RegisterEditable<Bumper>();
            EditableRegistry::RegisterEditable<Decal>();
            EditableRegistry::RegisterEditable<DispReel>();
            EditableRegistry::RegisterEditable<Flasher>();
            EditableRegistry::RegisterEditable<Flipper>();
            EditableRegistry::RegisterEditable<Gate>();
            EditableRegistry::RegisterEditable<Kicker>();
            EditableRegistry::RegisterEditable<Light>();
            EditableRegistry::RegisterEditable<LightSeq>();
            EditableRegistry::RegisterEditable<Plunger>();
            EditableRegistry::RegisterEditable<Primitive>();
            EditableRegistry::RegisterEditable<Ramp>();
            EditableRegistry::RegisterEditable<Rubber>();
            EditableRegistry::RegisterEditable<Spinner>();
            EditableRegistry::RegisterEditable<Surface>();
            EditableRegistry::RegisterEditable<Textbox>();
            EditableRegistry::RegisterEditable<Timer>();
            EditableRegistry::RegisterEditable<Trigger>();
            EditableRegistry::RegisterEditable<HitTarget>();
         }

         g_pvp = new VPinball();
         g_pvp->AddRef();
         g_pvp->Init();
         g_haccel = LoadAccelerators(g_hinst, MAKEINTRESOURCE(IDR_VPACCEL));

         if (fFile)
         {
            bool lf = true;
            if (szTableFileName[0] != '\0')
               g_pvp->LoadFileName(szTableFileName);
            else
               lf = g_pvp->LoadFile();

            if (fPlay && lf)
               g_pvp->DoPlay();

			if (fPov && lf)
			   g_pvp->Quit();
         }

         // VBA APC handles message loop (bastards)
         g_pvp->MainMsgLoop();

         g_pvp->Release();

         DestroyAcceleratorTable(g_haccel);

         _Module.RevokeClassObjects();
         Sleep(THREADS_PAUSE); //wait for any threads to finish
      }
      return 0;
   }
Example #2
0
extern "C" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int /*nShowCmd*/)
{
#ifdef CRASH_HANDLER
    rde::CrashHandler::Init();
#endif

	// disable auto-rotate on tablets
#if (WINVER <= 0x0601)
    SetDisplayAutoRotationPreferences = (pSDARP) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
                                                                "SetDisplayAutoRotationPreferences");
    if(SetDisplayAutoRotationPreferences)
        SetDisplayAutoRotationPreferences(ORIENTATION_PREFERENCE_LANDSCAPE);
#else
    SetDisplayAutoRotationPreferences(ORIENTATION_PREFERENCE_LANDSCAPE);
#endif

	g_hinst = hInstance;
   
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
    HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#else
    HRESULT hRes = CoInitialize(NULL);
#endif
    _ASSERTE(SUCCEEDED(hRes));
    _Module.Init(ObjectMap, hInstance, &LIBID_VPinballLib);

	bool fFile = false;
	bool fPlay = false;
    bool bRun = true;
	TCHAR szTableFileName[_MAX_PATH] = {0};
    int nRet = 0;

    int nArgs;
	LPSTR *szArglist = CommandLineToArgvA(GetCommandLine(), &nArgs);

	for(int i=0; i < nArgs; ++i)
    {
        if (lstrcmpi(szArglist[i], _T("-UnregServer"))==0 || lstrcmpi(szArglist[i], _T("/UnregServer"))==0)
        {
            _Module.UpdateRegistryFromResource(IDR_VPINBALL, FALSE);
            nRet = _Module.UnregisterServer(TRUE);
            bRun = false;
			break;
        }
        if (lstrcmpi(szArglist[i], _T("-RegServer"))==0 || lstrcmpi(szArglist[i], _T("/RegServer"))==0)
        {
            _Module.UpdateRegistryFromResource(IDR_VPINBALL, TRUE);
            nRet = _Module.RegisterServer(TRUE);
            bRun = false;
			break;
        }

		const bool editfile = (lstrcmpi(szArglist[i], _T("-Edit"))==0 || lstrcmpi(szArglist[i], _T("/Edit"))==0);
		const bool playfile = (lstrcmpi(szArglist[i], _T("-Play"))==0 || lstrcmpi(szArglist[i], _T("/Play"))==0);
        if ((editfile || playfile) && (i+1 < nArgs))
        {
			fFile = true;
			fPlay = playfile;

			// Remove leading - or /
			char* filename;
			if((szArglist[i+1][0] == '-') || (szArglist[i+1][0] == '/'))
				filename = szArglist[i+1]+1;
			else
				filename = szArglist[i+1];

			// Remove " "
			if(filename[0] == '"') {
				strcpy_s(szTableFileName,filename+1);
				szTableFileName[lstrlen(szTableFileName)] = '\0';
			}
			else
				strcpy_s(szTableFileName,filename);

			// Add current path
			char szLoadDir[MAX_PATH];
			if(szTableFileName[1] != ':') {
				GetCurrentDirectory(MAX_PATH,szLoadDir);
				strcat_s(szLoadDir,"\\");
				strcat_s(szLoadDir,szTableFileName);
				strcpy_s(szTableFileName,szLoadDir);
			} else
				// Or set from table path
				if(playfile) {
					PathFromFilename(szTableFileName, szLoadDir);
					SetCurrentDirectory(szLoadDir);
				}

			if(playfile)
				VPinball::SetOpenMinimized();

			break;
        }
    }

	free(szArglist);

    // load and register VP type library for COM integration
    char szFileName[_MAX_PATH];
    if (GetModuleFileName(hInstance, szFileName, _MAX_PATH))
    {
        ITypeLib *ptl = NULL;
        MAKE_WIDEPTR_FROMANSI(wszFileName, szFileName);
        if (SUCCEEDED(LoadTypeLib(wszFileName, &ptl)))
        {
            // first try to register system-wide (if running as admin)
            HRESULT hr = RegisterTypeLib(ptl, wszFileName, NULL);
            if (!SUCCEEDED(hr))
            {
                // if failed, register only for current user
                hr = RegisterTypeLibForUser(ptl, wszFileName, NULL);
                if (!SUCCEEDED(hr))
                    MessageBox(0, "Could not register type library. Try running Visual Pinball as administrator.", "Error", MB_ICONWARNING);
            }
            ptl->Release();
        }
        else
            MessageBox(0, "Could not load type library.", "Error", MB_ICONSTOP);
    }

    if (bRun)
    {
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
        hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
        _ASSERTE(SUCCEEDED(hRes));
        hRes = CoResumeClassObjects();
#else
        hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
            REGCLS_MULTIPLEUSE);
#endif
        _ASSERTE(SUCCEEDED(hRes));

		INITCOMMONCONTROLSEX iccex;
		iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
		iccex.dwICC = ICC_COOL_CLASSES;
		InitCommonControlsEx(&iccex);

        {
            EditableRegistry::RegisterEditable<Bumper>();
            EditableRegistry::RegisterEditable<Decal>();
            EditableRegistry::RegisterEditable<DispReel>();
            EditableRegistry::RegisterEditable<Flasher>();
            EditableRegistry::RegisterEditable<Flipper>();
            EditableRegistry::RegisterEditable<Gate>();
            EditableRegistry::RegisterEditable<Kicker>();
            EditableRegistry::RegisterEditable<Light>();
            EditableRegistry::RegisterEditable<LightSeq>();
            EditableRegistry::RegisterEditable<Plunger>();
            EditableRegistry::RegisterEditable<Primitive>();
            EditableRegistry::RegisterEditable<Ramp>();
            EditableRegistry::RegisterEditable<Rubber>();
            EditableRegistry::RegisterEditable<Spinner>();
            EditableRegistry::RegisterEditable<Surface>();
            EditableRegistry::RegisterEditable<Textbox>();
            EditableRegistry::RegisterEditable<Timer>();
            EditableRegistry::RegisterEditable<Trigger>();
        }

		g_pvp = new VPinball();
		g_pvp->AddRef();
		g_pvp->Init();
		g_haccel = LoadAccelerators(g_hinst,MAKEINTRESOURCE(IDR_VPACCEL));

		if (fFile)
			{
			g_pvp->LoadFileName(szTableFileName);

			if (fPlay)
				g_pvp->DoPlay();
			}

		// VBA APC handles message loop (bastards)
		g_pvp->MainMsgLoop();

		g_pvp->Release();

		DestroyAcceleratorTable(g_haccel);

        _Module.RevokeClassObjects();
        Sleep(dwPause); //wait for any threads to finish
    }

    _Module.Term();
    CoUninitialize();
#ifdef _CRTDBG_MAP_ALLOC
#ifdef DEBUG_XXX  //disable this in perference to DevPartner
	_CrtSetDumpClient(MemLeakAlert);
#endif
	_CrtDumpMemoryLeaks();
#endif
	//SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );

    return nRet;
}
DWORD OPCEngine::mainOPCThread(void)
{
	DWORD ret;
	BOOL end = FALSE;

	try
	{
		_TRACE(TL_INF, TG_ENG, (_T("started engine thread")));

		//-- initialize engine thread --
		_TRACE(TL_DEB, TG_ENG, (_T("COM initialize (multithreaded)")));
		HRESULT res = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
		if( FAILED(res)) 
		{
			_ERROR(TG_ENG, OPCENGINE_ERR_COM,(_T("Can't initialize COM: 0x%X"), res));
			return res;
		}

		if (m_type == OutProc)
		{
			_TRACE(TL_DEB, TG_ENG, (_T("register class objects")));
			_Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
		}

		//-- wait till engine termiantion --
		while (!end)
		{
			ret = ::WaitForMultipleObjects(2, m_events, FALSE, m_clientCheckInterval);

			switch (ret - WAIT_OBJECT_0)
			{
				case END_EVENT:
				{ // end event
					end = TRUE;
					_TRACE(TL_DEB, TG_ENG, (_T("received end event")));
				} 
				break;

				case SHUTDOWN_EVENT:
				{ // shutdown event
					OPCShutdownRequest *sreq; 

					_TRACE(TL_DEB, TG_ENG, (_T("received shutdown event")));
					while(!m_shutdownList.IsEmpty())
					{
						sreq = m_shutdownList.RemoveHead();
						if (sreq->server)
						{
							sreq->server->sendShutdownRequest(sreq->reason);
							if (sreq->event != INVALID_HANDLE_VALUE)
								::SetEvent(sreq->event);	
							sreq->server->release();
						}
						delete sreq;
					}
				} 
				break;

				default:
				{ // timeout
					//-- check client connections --
					GenericList<GenericBranch> serverListCopy;
					POSITION posSrv;
					GenericServer *server;	
					BOOL conOK;

					serverListCopy.create();

					{
				 	GenericList<GenericBranch> serverList(m_opcRoot->getBranchList());
					posSrv = serverList.getStartPosition();
					while(posSrv)
					{
						server = (GenericServer *)serverList.getNext(posSrv);
						server->addRef();
						serverListCopy.add(server);
					}
					}

					posSrv = serverListCopy.getStartPosition();
					while(posSrv)
					{
						server = (GenericServer *)serverListCopy.getNext(posSrv);

						conOK = server->checkClientConnection();
							
						if (!conOK)
						{
							server->disconnectClient();
						}
						server->release();
					}

					serverListCopy.free();
				}
				break;
			}
		}

		//-- terminated engine --
		if (m_type == OutProc)
		{
			_TRACE(TL_DEB, TG_ENG, (_T("revoke class objects")));
			_Module.RevokeClassObjects(); 
		}

		//-- disconnect all clients --
	 	GenericList<GenericBranch> serverList(m_opcRoot->getBranchList());
		POSITION posSrv;
		GenericServer *server;	
		posSrv = serverList.getStartPosition();
		while(posSrv)
		{
			server = (GenericServer *)serverList.getNext(posSrv);
			server->disconnectClient();
		}
		serverList.unlock();

		_TRACE(TL_DEB, TG_ENG, (_T("COM uninitialize")));
		::CoUninitialize();
		_TRACE(TL_INF, TG_ENG, (_T("terminated engine thread")));

	}
	catch(CException* e)
	{
		TCHAR excText[100];
		CRuntimeClass* rt = e->GetRuntimeClass();
		e->GetErrorMessage(excText, 100);
		_ERROR(TG_ENG, OPCENGINE_ERR_EXCEPTION,(_T("MFC EXCEPTION in OPC Engine Main Thread: %s (%s)"), rt->m_lpszClassName, excText));
		return 1;
	}	
	catch(...)
	{
		_ERROR(TG_ENG, OPCENGINE_ERR_EXCEPTION,(_T("EXCEPTION in OPC Engine Main Thread")));
		return 1;
	}	

    return S_OK;
}