VOID _declspec(naked) HOOK_CHeli__ProcessControl() { _asm { mov dwCurrentVehicle, ecx pushad } SwitchContext((CVehicleSAInterface *)dwCurrentVehicle); _asm { popad mov edx, FUNC_CHeli__ProcessControl call edx pushad } ReturnContextToLocalPlayer(); _asm { popad retn } }
void SwitchContext ( CVehicle* pVehicle ) { if ( !pVehicle ) return; // Grab the vehicle's internal interface CVehicleSA* pVehicleSA = dynamic_cast < CVehicleSA* > ( pVehicle ); DWORD dwVehicle = (DWORD)pVehicleSA->GetInterface (); // Grab the driver of the vehicle CPed* thePed = pVehicle->GetDriver (); if ( thePed ) { // Switch the context to the driver of the vehiclee SwitchContext ( thePed ); if ( bNotInLocalContext ) { // Prevent the game making remote players vehicle's audio behave like locals (and deleting // radio etc when they are removed) - issue #95 MemPutFast < BYTE > ( 0x50230C, 0x0 ); MemPutFast < BYTE > ( dwVehicle + 312 + 0xA5, 0 ); // For tanks, to prevent our mouse movement affecting remote tanks // 006AEA25 0F85 60010000 JNZ gta_sa.006AEB8B // V // 006AEA25 90 NOP // 006AEA26 E9 60010000 JMP gta_sa.006AEB8B MemPutFast < BYTE > ( 0x6AEA25, 0x90 ); MemPutFast < BYTE > ( 0x6AEA26, 0xE9 ); // Same for firetrucks and SWATs // 00729B96 0F85 75010000 JNZ gta_sa.00729D11 // V // 00729B96 90 NOP // 00729B97 E9 75010000 JMP gta_sa.00729D11 MemPutFast < BYTE > ( 0x729B96, 0x90 ); MemPutFast < BYTE > ( 0x729B97, 0xE9 ); bRadioHackInstalled = TRUE; } else { //0050237C |. E8 9F37FFFF CALL gta_sa_u.004F5B20 MemPutFast < BYTE > ( 0x50237C + 0, 0xE8 ); MemPutFast < BYTE > ( 0x50237C + 1, 0x9F ); MemPutFast < BYTE > ( 0x50237C + 2, 0x37 ); MemPutFast < BYTE > ( 0x50237C + 3, 0xFF ); MemPutFast < BYTE > ( 0x50237C + 4, 0xFF ); //0x5023A3 MemPutFast < BYTE > ( 0x5023A3 + 0, 0xE8 ); MemPutFast < BYTE > ( 0x5023A3 + 1, 0xB8 ); MemPutFast < BYTE > ( 0x5023A3 + 2, 0x37 ); MemPutFast < BYTE > ( 0x5023A3 + 3, 0xFF ); MemPutFast < BYTE > ( 0x5023A3 + 4, 0xFF ); } } }
Context::LPFindResult ContextMemory::onFindContext(const std::string& method, const Context::Params& params, const RDOParserSrcInfo& srcInfo) const { if (method == Context::METHOD_OPERATOR_DOT) { LPLocalVariable pLocalVariable = m_pLocalVariableListStack->findLocalVariable(params.identifier()); if (pLocalVariable) return rdo::Factory<FindResult>::create(SwitchContext(pLocalVariable, params)); } if (method == Context::METHOD_GET) { LPLocalVariable pLocalVariable = m_pLocalVariableListStack->findLocalVariable(params.identifier()); if (pLocalVariable) return pLocalVariable->find(Context::METHOD_GET, params, srcInfo); } if (method == Context::METHOD_SET) { LPLocalVariable pLocalVariable = m_pLocalVariableListStack->findLocalVariable(params.identifier()); if (pLocalVariable) return pLocalVariable->find(Context::METHOD_SET, params, srcInfo); } return rdo::Factory<FindResult>::create(); }
void SwitchContext ( CPedSAInterface* ped ) { CPed* thePed = pGameInterface->GetPools ()->GetPed ( (DWORD*) ped ); if ( thePed ) { SwitchContext ( thePed ); } }
void SwitchContext ( CVehicleSAInterface* pVehicleInterface ) { // Grab the CVehicle for the given vehicle interface CPoolsSA* pool = (CPoolsSA*) pGameInterface->GetPools (); CVehicle* pVehicle = pool->GetVehicle ( (DWORD *)pVehicleInterface ); if ( pVehicle ) { SwitchContext ( pVehicle ); } }
void SwitchContext ( CVehicle* pVehicle ) { if ( !pVehicle ) return; // Grab the vehicle's internal interface CVehicleSA* pVehicleSA = dynamic_cast < CVehicleSA* > ( pVehicle ); DWORD dwVehicle = (DWORD)pVehicleSA->GetInterface (); // Grab the driver of the vehicle CPed* thePed = pVehicle->GetDriver (); if ( thePed ) { // Switch the context to the driver of the vehiclee SwitchContext ( thePed ); if ( bNotInLocalContext ) { // Prevent the game making remote players vehicle's audio behave like locals (and deleting // radio etc when they are removed) - issue #95 *(BYTE *)0x50230C = 0x0; *(BYTE *)(dwVehicle + 312 + 0xA5) = 0; // set the is local player's flag to 0 on the audio entity for the vehicle // For tanks, to prevent our mouse movement affecting remote tanks // 006AEA25 0F85 60010000 JNZ gta_sa.006AEB8B // V // 006AEA25 90 NOP // 006AEA26 E9 60010000 JMP gta_sa.006AEB8B *(BYTE *)0x6AEA25 = 0x90; *(BYTE *)0x6AEA26 = 0xE9; bRadioHackInstalled = TRUE; } else { //0050237C |. E8 9F37FFFF CALL gta_sa_u.004F5B20 *(BYTE *)(0x50237C + 0) = 0xE8; *(BYTE *)(0x50237C + 1) = 0x9F; *(BYTE *)(0x50237C + 2) = 0x37; *(BYTE *)(0x50237C + 3) = 0xFF; *(BYTE *)(0x50237C + 4) = 0xFF; //0x5023A3 *(BYTE *)(0x5023A3 + 0) = 0xE8; *(BYTE *)(0x5023A3 + 1) = 0xB8; *(BYTE *)(0x5023A3 + 2) = 0x37; *(BYTE *)(0x5023A3 + 3) = 0xFF; *(BYTE *)(0x5023A3 + 4) = 0xFF; } } }
SharedPtr<Thread> SetupMainThread(u32 stack_size, u32 entry_point, s32 priority) { DEBUG_ASSERT(!GetCurrentThread()); // Initialize new "main" thread auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END); SharedPtr<Thread> thread = thread_res.MoveFrom(); // Run new "main" thread SwitchContext(thread.get()); return thread; }
void Reschedule() { Thread* prev = GetCurrentThread(); Thread* next = PopNextReadyThread(); HLE::g_reschedule = false; if (next != nullptr) { LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId()); SwitchContext(next); } else { LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId()); for (auto& thread : thread_list) { LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(), thread->current_priority, thread->status); } } }
/// Reschedules to the next available thread (call after current thread is suspended) void Reschedule() { Thread* prev = GetCurrentThread(); Thread* next = NextThread(); HLE::g_reschedule = false; if (next > 0) { INFO_LOG(KERNEL, "context switch 0x%08X -> 0x%08X", prev->GetHandle(), next->GetHandle()); SwitchContext(next); // Hack - There is no mechanism yet to waken the primary thread if it has been put to sleep // by a simulated VBLANK thread switch. So, we'll just immediately set it to "ready" again. // This results in the current thread yielding on a VBLANK once, and then it will be // immediately placed back in the queue for execution. if (prev->wait_type == WAITTYPE_VBLANK) { ResumeThreadFromWait(prev->GetHandle()); } } }
/***************************************************************************** * InitOpenGL: initializes OpenGL provider *****************************************************************************/ static int InitOpenGL( vout_thread_t *p_vout ) { /* Initialize GLX */ if( !p_vout->p_sys->b_glx13 ) { if( InitGLX12( p_vout ) != VLC_SUCCESS ) { return VLC_EGENERIC; } } else { if( InitGLX13( p_vout ) != VLC_SUCCESS ) { return VLC_EGENERIC; } } /* Set the OpenGL context _for the current thread_ */ SwitchContext( p_vout ); return VLC_SUCCESS; }
VOID _declspec(naked) HOOK_CPlayerPed__ProcessControl() { // Assumes no reentrancy _asm { mov dwCurrentPlayerPed, ecx // Save incase of abort mov PlayerPed__ProcessControl_Saved.eax, eax mov PlayerPed__ProcessControl_Saved.ecx, ecx mov PlayerPed__ProcessControl_Saved.edx, edx mov PlayerPed__ProcessControl_Saved.ebx, ebx mov PlayerPed__ProcessControl_Saved.esp, esp mov PlayerPed__ProcessControl_Saved.ebp, ebp mov PlayerPed__ProcessControl_Saved.esi, esi mov PlayerPed__ProcessControl_Saved.edi, edi pushad } SwitchContext((CPedSAInterface *)dwCurrentPlayerPed); _asm { popad mov edx, FUNC_CPlayerPed__ProcessControl call edx pushad } ReturnContextToLocalPlayer(); _asm { popad retn } }
/** ******************************************************************************* * @brief Schedule function * @param[in] None * @param[out] None * @retval None * * @par Description * @details This function is called by every where need to switch context, * It is schedule function of OS kernel. ******************************************************************************* */ void Schedule(void) { U8 RunPrio,RdyPrio; P_OSTCB pRdyTcb,pCurTcb; pCurTcb = TCBRunning; pRdyTcb = TCBRdy; if((pRdyTcb==Co_NULL) || (pCurTcb != TCBNext) || (OSSchedLock >1) || (OSIntNesting >0)) { return; } TaskSchedReq = Co_FALSE; RunPrio = pCurTcb->prio; RdyPrio = pRdyTcb->prio; /* Is Running task status was changed? */ if(pCurTcb->state != TASK_RUNNING) { TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ pRdyTcb->state = TASK_RUNNING; RemoveFromTCBRdyList(pRdyTcb); } else if(RdyPrio < RunPrio ) /* Is higher PRI task coming in? */ { TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ InsertToTCBRdyList(pCurTcb); RemoveFromTCBRdyList(pRdyTcb); pRdyTcb->state = TASK_RUNNING; } #if CFG_ROBIN_EN >0 /* Is time for robinning */ else if((RunPrio == RdyPrio) && (OSCheckTime == OSTickCnt)) { TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ InsertToTCBRdyList(pCurTcb); RemoveFromTCBRdyList(pRdyTcb); pRdyTcb->state = TASK_RUNNING; } #endif else { return; } #if CFG_ROBIN_EN >0 if(TCBNext->prio == TCBRdy->prio) /* Reset OSCheckTime for task robinnig */ OSCheckTime = OSTickCnt + TCBNext->timeSlice; #endif #if CFG_STK_CHECKOUT_EN > 0 /* Is stack overflow? */ if((pCurTcb->stkPtr < pCurTcb->stack)||(*(U32*)(pCurTcb->stack) != MAGIC_WORD)) { CoStkOverflowHook(pCurTcb->taskID); /* Yes,call handler */ } #endif SwitchContext(); /* Call task context switch */ }
/* * Mock Implementation of PendSV ISR */ void POS_PendSV_Handler(void) { /* PendSV ISR normally calls SwitchContext() function to get next TCB */ SwitchContext(); }
int MySwitchContext (int p) { return (SwitchContext (p)); }