static int ThreadFunction(void *unused) { uint64_t next_time; uint64_t now; // Keep running until OPL_Timer_StopThread is called. while (timer_thread_state == THREAD_STATE_RUNNING) { // Get the next time that we must sleep until, and // wait until that time. next_time = GetNextTime(); now = SDL_GetTicks() * OPL_MS; if (next_time > now) { SDL_Delay((next_time - now) / OPL_MS); } // Update the current time. SDL_LockMutex(callback_queue_mutex); current_time = next_time; SDL_UnlockMutex(callback_queue_mutex); } timer_thread_state = THREAD_STATE_STOPPED; return 0; }
void CQuiz::NoticeMessage() { if( GetState() == QE_OPEN ) { DWORD dwRemainTime = GetNextTime() - GetTickCount(); if( static_cast<int>( dwRemainTime ) <= 0 ) return; g_DPCoreClient.SendQuizSystemMessage( TID_GAME_QUIZ_PRE_NOTICE1, FALSE, g_uIdofMulti, ( dwRemainTime / MIN( 1 ) + 1 ) ); g_DPCoreClient.SendQuizSystemMessage( TID_GAME_QUIZ_PRE_NOTICE2 ); } else if( GetState() == QE_WATCHINGZONE_OPEN ) { DWORD dwRemainTime = GetNextTime() - GetTickCount(); if( static_cast<int>( dwRemainTime ) <= 0 ) return; g_DPCoreClient.SendQuizSystemMessage( TID_GAME_QUIZ_CUR_NOTICE1, FALSE, g_uIdofMulti, ( dwRemainTime / MIN( 1 ) + 1 ) ); g_DPCoreClient.SendQuizSystemMessage( TID_GAME_QUIZ_CUR_NOTICE2 ); } }
void CQuiz::Process() { DWORD dwTick = GetTickCount(); vector<QUIZLIST>::iterator it = m_vecQuizList.begin(); switch( m_nState ) { case QE_CLOSE: // 퀴즈 이벤트 종료. 모든 유저 밖으로 이동 if( dwTick > GetNextTime() ) CloseQuizEvent(); break; case QE_OPEN: { if( dwTick > GetNextTime() ) { if( !m_vecQuizList.size() ) { Error( "Quiz List Load Failed!" ); CloseQuizEvent(); return; } if( (int)( m_vecQuizList.size() ) < m_nQuizSize ) break; BOOL bAble = FALSE; int nUser = 0; CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) { for( DWORD i = 0; i < pWorld->m_dwObjNum; ++i ) { if( IsInQuizEventPlayer( pWorld, nDefaultLayer, i ) ) { static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( prj.GetText( TID_GAME_QUIZ_WAIT_QUESTION ) ); bAble = TRUE; ++nUser; } } } if( !bAble ) { CloseQuizEvent(); return; } if( nUser <= LIMIT_USER_COUNT ) m_bSelectLog = TRUE; SetNextTime( dwTick + m_dwWaitTime ); SetState( QE_QUESTION ); g_dpDBClient.SendQuizEventState( QE_QUESTION, g_uIdofMulti ); } } break; case QE_QUESTION: // 문제 출제 if( dwTick > GetNextTime() ) { // UI CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) { for( DWORD i = 0; i < pWorld->m_dwObjNum; ++i ) { if( IsInQuizEventPlayer( pWorld, nDefaultLayer, i ) ) { static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( prj.GetText( TID_GAME_QUIZ_QUESTION ), QE_QUESTION ); static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizQuestion( GetType(), it->strQuestion, m_dwQuestionTime / SEC(1) ); } } } SetNextTime( dwTick + m_dwQuestionTime ); SetState( QE_CORRECT_ANSWER ); g_dpDBClient.SendQuizEventState( QE_CORRECT_ANSWER, g_uIdofMulti ); ++m_nQuizCount; } break; case QE_CORRECT_ANSWER: // 정답 공개 if( dwTick > GetNextTime() ) { /* // 유저 이동 불가 - object DWORD dwId = NULL; if( GetType() == TYPE_OX ) dwId = 1116; else dwId = 1115; m_pVObj = CreateObj( D3DDEVICE, OT_OBJ, dwId ); if( !m_pVObj ) return; m_pVObj->SetPos( m_sQuizData.vQuizZonePos ); m_pVObj->UpdateLocalMatrix(); CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) pWorld->ADDOBJ( m_pVObj, TRUE, nDefaultLayer ); if( GetType() == TYPE_4C ) { m_pHObj = CreateObj( D3DDEVICE, OT_OBJ, dwId ); if( !m_pHObj ) return; m_pHObj->SetPos( m_sQuizData.vQuizZonePos ); m_pHObj->SetAngle( 90 ); m_pHObj->UpdateLocalMatrix(); CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) pWorld->ADDOBJ( m_pHObj, TRUE, nDefaultLayer ); }*/ // 문제 풀이 종료 메세지 CString str_Message; str_Message.Format( prj.GetText( TID_GAME_QUIZ_END_SOLVE_QUESTION ), m_nQuizCount ); // 정답 메세지 CString strMessage; if( GetType() == TYPE_OX ) { if( it->nCorrect == 1 ) strMessage.Format( prj.GetText( TID_GAME_QUIZ_CORRECT_ANSWER_OX ), 'O' ); else strMessage.Format( prj.GetText( TID_GAME_QUIZ_CORRECT_ANSWER_OX ), 'X' ); } else if( GetType() == TYPE_4C ) strMessage.Format( prj.GetText( TID_GAME_QUIZ_CORRECT_ANSWER_4C ), it->nCorrect ); D3DXVECTOR3 vPos = m_sQuizData.aExamplePos[(*it).nCorrect - 1]; g_UserMng.AddWorldCreateSfxObj( XI_QUIZCORRECTANSWER, vPos.x, vPos.y, vPos.z, FALSE, WI_WORLD_QUIZ ); CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) { for( DWORD i = 0; i < pWorld->m_dwObjNum; ++i ) { if( IsInQuizEventPlayer( pWorld, nDefaultLayer, i ) ) { static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( str_Message, QE_CORRECT_ANSWER ); static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( strMessage ); } } } SetNextTime( dwTick + m_dwWaitTime ); SetState( QE_DROP_OUT ); g_dpDBClient.SendQuizEventState( QE_DROP_OUT, g_uIdofMulti ); } break; case QE_DROP_OUT: if( dwTick > GetNextTime() ) { // 탈락자 대기존으로 이동 DropOutWrongUser( (*it).nQuizId, (*it).nCorrect ); m_vecQuizList.erase( it ); } break; case QE_CLOSE_WAIT: { // 문제가 요구치 보다 많이 남아있을 시 대기존 개방 if( m_vecQuizList.size() > REMAIN_QUIZ ) { CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) { for( DWORD i = 0; i < pWorld->m_dwObjNum; ++i ) { if( IsInQuizEventPlayer( pWorld, nDefaultLayer, i ) ) { static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( prj.GetText( TID_GAME_QUIZ_WATCHINGZONE_OPEN ), QE_WATCHINGZONE_OPEN ); static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( prj.GetText( TID_GAME_QUIZ_TELEPORT_QUIZZONE ) ); } } } SetNextTime( dwTick + m_dwWatchingZoneOpenTime ); SetState( QE_WATCHINGZONE_OPEN ); m_bSelectLog = FALSE; m_nQuizCount = 0; g_dpDBClient.SendQuizEventState( QE_WATCHINGZONE_OPEN, g_uIdofMulti ); } // 문제가 요구치 보다 적을 시 퀴즈 이벤트 종료 else { g_DPCoreClient.SendQuizSystemMessage( TID_GAME_QUIZ_CLOSING, TRUE, g_uIdofMulti ); SetNextTime( dwTick + m_dwCloseWaitTime ); SetState( QE_CLOSE ); g_dpDBClient.SendQuizEventState( QE_CLOSE_WAIT, g_uIdofMulti ); } } break; case QE_WATCHINGZONE_OPEN: // 대기존 개방 if( dwTick > GetNextTime() ) { BOOL bAble = FALSE; int nUser = 0; CWorld* pWorld = g_WorldMng.GetWorld( WI_WORLD_QUIZ ); if( pWorld ) { for( DWORD i = 0; i < pWorld->m_dwObjNum; ++i ) { if( IsInQuizEventPlayer( pWorld, nDefaultLayer, i ) ) { static_cast<CUser*>( pWorld->m_apObject[i] )->AddQuizEventMessage( prj.GetText( TID_GAME_QUIZ_WAIT_QUESTION ) ); //if( static_cast<CUser*>( pWorld->m_apObject[i] )->IsAuthHigher( AUTH_GAMEMASTER ) == FALSE ) if( GetZoneType( static_cast<CMover*>( pWorld->m_apObject[i] ) ) == ZONE_QUIZ ) { bAble = TRUE; ++nUser; } } } } if( bAble ) { SetNextTime( dwTick + m_dwWaitTime ); SetState( QE_QUESTION ); if( nUser <= LIMIT_USER_COUNT ) m_bSelectLog = TRUE; } else { CloseQuizEvent(); return; } } break; } }