//************************************************ //*测试任务初始化 //************************************************ VOID t1::TestInit() { if (m_TrialType == TRIAL_PRACTICE) { m_TrialTime = m_Setting.m_PracTime; m_TrialTimes = m_Setting.m_PracTimes; } else { m_TrialTime = m_Setting.m_ExperTime; m_TrialTimes = m_Setting.m_ExperTimes; } a = x_resolution / 2; b = y_resolution / 2; r1 = 300; r2 = 200; Rx = 400; Ry = 200; acce = m_Setting.m_AccelerationMin; // inc_v = m_Setting.m_IncreaseValue; if (m_Setting.m_SpeedMode == 0) { v = m_Setting.m_Speed; } else { v = m_Setting.m_InitSpeed; } InitRotateAngle = 0.0; if (m_Setting.m_MoveMode) { RandValueFloat(m_Setting.m_AngleSpeedMin, m_Setting.m_AngleSpeedMax, AngleSpeed); RandValueFloat(-90.0, 90.0, RotateAngle); if (RotateAngle<0) { AngleSpeed = -AngleSpeed; } } else { RotateAngle = 0.0; AngleSpeed = 0.0; } fai = 0.0; post_fai = 0.0; m_PointNum = 0; m_MemNum = 1000; m_ObjPoint = (SPOINT*)malloc(m_MemNum*sizeof(POINT)); m_PostPoint = (SPOINT*)malloc(m_MemNum*sizeof(POINT)); m_ObjRotate = (float*)malloc(m_MemNum*sizeof(float)); m_PostRotate = (float*)malloc(m_MemNum*sizeof(float)); m_Distance = (float*)malloc(m_MemNum*sizeof(float)); m_RotateError = (float*)malloc(m_MemNum*sizeof(float)); m_PointTime = (unsigned long*)malloc(m_MemNum*sizeof(unsigned long)); m_bHit = (BOOL*)malloc(m_MemNum*sizeof(BOOL)); m_ObjSpeedX = (float*)malloc(m_MemNum*sizeof(float)); m_ObjSpeedY = (float*)malloc(m_MemNum*sizeof(float)); m_PostSpeedX = (float*)malloc(m_MemNum*sizeof(float)); m_PostSpeedY = (float*)malloc(m_MemNum*sizeof(float)); m_ObjRotateSpeed = (float*)malloc(m_MemNum*sizeof(float)); m_PostRotateSpeed = (float*)malloc(m_MemNum*sizeof(float)); if (m_Setting.m_Pause == 1) { m_PauseTimeStart = (int*)malloc(m_Setting.m_PauseNum*sizeof(int)); m_PauseTimeEnd = (int*)malloc(m_Setting.m_PauseNum*sizeof(int)); } m_ObjRotateSpeed[m_PointNum] = AngleSpeed; m_PostPointX = x_resolution / 2; m_PostPointY = y_resolution / 2; m_PostPoint[m_PointNum].x = m_PostPointX; m_PostPoint[m_PointNum].y = m_PostPointY; m_PostRotate[m_PointNum] = post_fai; m_ObjRotate[m_PointNum] = fai; m_RotateError[m_PointNum] = 0.0; switch (m_Setting.m_Track) { case TRACK_CIRCLE: alpha = m_Setting.m_InitAngle*PI / 180.0; m_ObjPoint[m_PointNum].x = a + r1 * cos(alpha); m_ObjPoint[m_PointNum].y = b - r1 * sin(alpha); r = r1; break; case TRACK_ELLIPSE: alpha = m_Setting.m_InitAngle*PI / 180.0; m_ObjPoint[m_PointNum].x = a + Rx * cos(alpha); m_ObjPoint[m_PointNum].y = b - Ry * sin(alpha); r = pow(pow((m_ObjPoint[m_PointNum].y - b), (float)2.0) + pow((m_ObjPoint[m_PointNum].x - a), (float)2.0), (float)0.5); break; case TRACK_EIGHT: alpha = 0; m_ObjPoint[m_PointNum].x = a + r2 + r2 * cos(2 * alpha); m_ObjPoint[m_PointNum].y = b - r2 * sin(2 * alpha); r = r2; break; } m_Distance[m_PointNum] = pow(pow((m_ObjPoint[m_PointNum].y - m_PostPoint[m_PointNum].y), 2.0) + pow((m_ObjPoint[m_PointNum].x - m_PostPoint[m_PointNum].x), 2.0), 0.5); if (m_Setting.m_Track == TRACK_ELLIPSE) { omiga = pow(v*v / (pow(Rx*sin(alpha), (float)2.0) + pow(Ry*cos(alpha), (float)2.0)), (float)0.5); } else { omiga = v / r; } m_ObjSpeedX[m_PointNum] = -v * sin(alpha); m_ObjSpeedY[m_PointNum] = -v * cos(alpha); JoyX = 0; JoyY = 0; m_bHit[m_PointNum] = FALSE; m_bObjPause = FALSE; m_PauseNo = 0; if (m_Setting.m_Pause == 1) { RandPausePoint(60, m_Setting.m_PauseNum, m_PauseTimeStart, m_PauseTimeEnd); } if (JoystickUpdate()) { post_fai0 = GetZAxis();//GetXAxis(); } if (m_Setting.m_Direction == 0) { m_Direction = 1; } else { m_Direction = -1; } }
//************************************************ //*操纵杆输入线程 //************************************************ DWORD WINAPI t1::InputThreadProcedure(LPVOID lpStartupParam) { // get the data we passed to the thread. Note that we don't have to use this // at all if we don't want MYDATA* pMyData = (MYDATA*)lpStartupParam; // access some imaginary members of MYDATA, which you can define on // your own later pMyData->nTime = GetCurrentTime(); // imaginary function I created pMyData->nNumber = 5; // here's the thread's main loop ?kind of like the main loop in WinMain MSG msg; int i; for (;;) { //处理外部消息 if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { GetMessage(&msg, NULL, 0, 0); if (msg.message == WM_THREADSTOP) break; // only way out of the for( ;; ) loop TranslateMessage(&msg); DispatchMessage(&msg); } else { switch (m_TestState) { case STATE_DISPLAYINSTURCTION: case STATE_DISPLAYNEXT: case STATE_DISPLAYOPTION: //呈现开始选项,等待按任意键开始测试 if (JoystickUpdate()) { for (i = 0; i<8; i++) { if (IsButtonDown(KEY_YES)) { m_TrialNo++; TestInit(); m_TestState = STATE_DISPLAYOBJ; break; } } } break; case STATE_DISPLAYOBJ: case STATE_MOVINGOBJ: //测试过程中获得操纵杆输入 if (JoystickUpdate()) { JoyX = GetXAxis();//GetYAxis();// JoyY = GetYAxis();//-GetZAxis();// if (m_Setting.m_MoveMode == MODE_MOVEROATE) { JoyZ = GetZAxis();//GetXAxis();// post_fai = (float)(JoyZ - post_fai0)*(3600.0 / 1024.0) / m_HardSetting.m_KnobSensitive;//GetZAxis()*PI/400.0; while (post_fai<-180) { post_fai = post_fai + 360; } while (post_fai>180) { post_fai = post_fai - 360; } } } break; case STATE_OVER: //测试结束,等待按任意键退出 if (JoystickUpdate()) { for (i = 0; i<12; i++) { if (IsButtonDown(i)) { PostThreadMessage(dwInputThreadID, WM_THREADSTOP, 0, 0); m_TestState = STATE_NEXT;// STATE_EXIT --> STATE_NEXT } } } break; default: break; } // do the task ?add in your own stuff here // yield to other threads, because we almost never get messages // (note that we may be yielding to WinMain too) //以键盘代替操纵杆 if (JOY == 0) { if (IsButtonDown(DIK_ESCAPE)) { PostThreadMessage(dwInputThreadID, WM_THREADSTOP, 0, 0); m_TestState = STATE_EXIT; } } } Sleep(1); } g_nThreadExitCount++; return 0; }
//************************************************ //*主程序 //************************************************ int APIENTRY t1::_tWinMain(HINSTANCE &hInstance, HINSTANCE &hPrevInstance, LPTSTR &lpCmdLine, int &nCmdShow, HWND &_hWnd, std::string winClassName, std::string winName) { // 初始化句柄和状态 bool bUnClosedLastWin = true; hWnd = _hWnd; gHinstance = hInstance; ShowCursor(FALSE); //g_nThreadExitCount = 0; //获得传递的命令行参数,得到被试着名字和任务编号 char *pdest; int result; int pos1; pdest = strrchr(lpCmdLine, ' '); pos1 = pdest - lpCmdLine; if (pos1>0) { strncpy(m_TaskNumStr, lpCmdLine, pos1); } else { strcpy(m_TaskNumStr, ""); } pdest = strrchr(lpCmdLine, '-'); result = pdest - lpCmdLine; if (result>0) { strncpy(m_TesterName, lpCmdLine + pos1 + 1, result - pos1 - 1); } else { strcpy(m_TesterName, ""); } if (pos1>0) { strcpy(m_DataName, lpCmdLine + pos1 + 1); } else { strcpy(m_DataName, ""); } //读取任务设置 if (!ReadSetting()) { MessageBox(hWnd, "任务设置文件格式错误!", "测试任务", MB_OK); return 0; } //注册窗口类 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS, MsgProc, 0L, 0L, hInstance, NULL, NULL, NULL, NULL, std::to_string(nCmdShow).c_str(), NULL }; RegisterClassEx(&wc); x_resolution = GetSystemMetrics(SM_CXSCREEN); y_resolution = GetSystemMetrics(SM_CYSCREEN); rec_x_begin = (x_resolution - 1024) / 2; rec_y_begin = (y_resolution - 768) / 2; rec_x_end = (x_resolution + 1024) / 2; rec_y_end = (y_resolution + 768) / 2; _hWnd = hWnd = CreateWindow(std::to_string(nCmdShow).c_str(), std::to_string(nCmdShow).c_str(), WS_VISIBLE | WS_POPUP, 0, 0, x_resolution, y_resolution, NULL, NULL, hInstance, NULL); //显示主窗口 SetFocus(hWnd); //创建DirectX设备 if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_lpkDInput, NULL))) { return 0; } float m_JoySpeedMax; if (m_HardSetting.m_JoySpeedMax > 0) { m_JoySpeedMax = m_HardSetting.m_JoySpeedMax; } else { m_JoySpeedMax = 200; } //关闭输入法 HKL hkl; hkl = LoadKeyboardLayout("00000804", KLF_ACTIVATE); if (hkl != NULL) { ActivateKeyboardLayout(hkl, KLF_SETFORPROCESS); } //ShowCursor(FALSE); //设置操纵杆变化范围 if (JoystickInit(hWnd, -m_JoySpeedMax, m_JoySpeedMax, 1)) { JoystickUpdate(); } else { MessageBox(hWnd, "请检查操纵杆连接是否正确!", "测试任务", MB_OK); return 0; } // declare a variable of our data structure to pass to the ThreadProcedure MYDATA MyThreadData; MyThreadData.nTime = 7509843; MyThreadData.nNumber = 39; //创建操纵杆输入线程 // declare a DWORD to hold our thread's new generated ID HANDLE h = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)InputThreadProcedure, (LPVOID)&MyThreadData, NULL, &dwInputThreadID); // SetPriorityClass(h,NORMAL_PRIORITY_CLASS); // SetThreadPriority(h,THREAD_PRIORITY_ABOVE_NORMAL); // actually create and start the thread now! // the thread will run until we send it our own WM_THREADSTOP message srand((unsigned)time(NULL)); //初始化随机种子 //初始化Direct3D bool b_InitD3d = SUCCEEDED(InitD3D(hWnd)); if (b_InitD3d) { //进入消息循环 MSG msg; ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { //处理外部消息 TranslateMessage(&msg); DispatchMessage(&msg); } else { //执行测试过程 UpdateState(); if (m_bDisplayReady) { //渲染图形 Render(); hideLastWindow(bUnClosedLastWin, winClassName, winName, hInstance); } } Sleep(1); // 当按下“下一个任务”或“退出”时,终止消息循环 if (m_TestState == STATE_NEXT || m_TestState == STATE_EXIT) { break; } } } ShowCursor(TRUE); CloseHandle(h); return rtn; }
void Joystick::updateJoystick(int x, int y){ emit JoystickUpdate(y,x); }