コード例 #1
0
ファイル: global_room.cpp プロジェクト: CalinLeafshade/ags
void NewRoom(int nrnum) {
    if (nrnum < 0)
        quitprintf("!NewRoom: room change requested to invalid room number %d.", nrnum);

    if (displayed_room < 0) {
        // called from game_start; change the room where the game will start
        playerchar->room = nrnum;
        return;
    }


    DEBUG_CONSOLE("Room change requested to room %d", nrnum);
    EndSkippingUntilCharStops();

    can_run_delayed_command();

    if (play.stop_dialog_at_end != DIALOG_NONE) {
        if (play.stop_dialog_at_end == DIALOG_RUNNING)
            play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum;
        else {
            quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d",
                last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line);
        }
        return;
    }

    get_script_position(last_in_dialog_request_script_pos);

    if (in_leaves_screen >= 0) {
        // NewRoom called from the Player Leaves Screen event -- just
        // change which room it will go to
        in_leaves_screen = nrnum;
    }
    else if (in_enters_screen) {
        setevent(EV_NEWROOM,nrnum);
        return;
    }
    else if (in_inv_screen) {
        inv_screen_newroom = nrnum;
        return;
    }
    else if ((inside_script==0) & (in_graph_script==0)) {
        new_room(nrnum,playerchar);
        return;
    }
    else if (inside_script) {
        curscript->queue_action(ePSANewRoom, nrnum, "NewRoom");
        // we might be within a MoveCharacterBlocking -- the room
        // change should abort it
        if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) {
            // nasty hack - make sure it doesn't move the character
            // to a walkable area
            mls[playerchar->walking].direct = 1;
            StopMoving(game.playercharacter);
        }
    }
    else if (in_graph_script)
        gs_to_newroom = nrnum;
}
コード例 #2
0
int32_t FTDIListener(ftdi_context ftdihandle)
{
	int32_t returnvalue,i;
	unsigned char * bufferptr;
	
	#ifdef DEBUGMODE
	printf("FTDIListener\n");
	#endif 
	do
	{	
		do
		{
			returnvalue=p_ftdi_read_data(ftdihandle, RXBUFFER, 2);
		}while(returnvalue==0);
		if(returnvalue>0)
		{
			for(i=0;i<returnvalue;i++)
			{				
				rx_fifo.BUFFER[(rx_fifo.ptr_in)&(BUFFERSIZE-1)]=RXBUFFER[i];
				rx_fifo.ptr_in=(rx_fifo.ptr_in+1)&(BUFFERSIZE-1);
			}

			#ifdef DEBUGMODE
				printf("rx : %d %d \n",rx_fifo.ptr_in,returnvalue);
			#endif
			if(READ_THREAD_EVENT)setevent(READ_THREAD_EVENT);
		}
		else
		{
			#ifdef DEBUGMODE
				printf("FTDIListener : ftdi_read_data=%d\n",returnvalue);
			#endif

			stop_thread=1;
			if(READ_THREAD_EVENT)setevent(READ_THREAD_EVENT);
		}

	}while(!stop_thread);
	setevent(STOP_THREAD_EVENT);
	return 0;
}
コード例 #3
0
// Function name	: ShmemLockedQueue::RemoveNextInsert
// Description	    : 
// Return type		: bool 
// Argument         : MessageQueue *pMsgQueue
bool ShmemLockedQueue::RemoveNextInsert(MessageQueue *pMsgQueue, bool bBlocking)
{
	ShmemLockedQueueHeader *pTail, *pHead, *pMessage;

	if (bBlocking)
	{
		// Get the next available entry in the queue
		while(true)
		{
			// Get the queue mutex
			lock(m_plQMutex);
			
			// Wait for the queue to not be empty
			while (SHMEM_Q_HEAD_OFFSET == 0)
			{
				unlock(m_plQMutex);
				if (m_bUseEvent)
				{
					if (WaitForSingleObject(m_hMsgAvailableEvent, INFINITE) 
						!= WAIT_OBJECT_0)
					{
						printf("ShmemLockedQueue:RemoveNextInsert:Wait for MsgAvailableEvent on an empty queue failed, error %d\n", GetLastError());fflush(stdout);
						return false;
					}
				}
				else
					wait(m_plMsgAvailableTrigger);
				lock(m_plQMutex);
			}
			
			// Search the queue for the next available entry
			pMessage = SHMEM_Q_HEAD_PTR;
			pTail = SHMEM_Q_TAIL_PTR;
			
			while ((pMessage->state == SHMEM_Q_BEING_READ) && (pMessage < pTail))
				pMessage = (ShmemLockedQueueHeader*)
				((LPBYTE)pMessage + pMessage->next_offset);
			
			// If we haven't reached the tail and the element we are on is not 
			// currently being written, then successfully break out of this loop
			if ( (pMessage < pTail) && (pMessage->state != SHMEM_Q_BEING_WRITTEN) )
				break;
			
			// All messages are being read or the next message in order is not 
			// ready. I need to reset MsgAvailableEvent, wait for it to be 
			// signalled and then start over
			if (m_bUseEvent)
			{
				ResetEvent(m_hMsgAvailableEvent);
				unlock(m_plQMutex);
				if (WaitForSingleObject(m_hMsgAvailableEvent, INFINITE) 
					!= WAIT_OBJECT_0)
				{
					printf("ShmemLockedQueue:RemoveNextInsert:Wait for MsgAvailableEvent failed, error %d\n", GetLastError());fflush(stdout);
					return false;
				}
			}
			else
			{
				resetevent(m_plMsgAvailableTrigger);
				unlock(m_plQMutex);
				wait(m_plMsgAvailableTrigger);
			}
		}
	}
	else
	{
		// Try to get the next available entry in the queue

		// Get the queue mutex
		lock(m_plQMutex);
			
		// Wait for the queue to not be empty
		if (SHMEM_Q_HEAD_OFFSET == 0)
		{
			unlock(m_plQMutex);
			return false;
		}
			
		// Search the queue for the next available entry
		pMessage = SHMEM_Q_HEAD_PTR;
		pTail = SHMEM_Q_TAIL_PTR;
			
		while ((pMessage->state == SHMEM_Q_BEING_READ) && (pMessage < pTail))
			pMessage = (ShmemLockedQueueHeader*)
						((LPBYTE)pMessage + pMessage->next_offset);
			
		// If we haven't reached the tail and the element we are on is not 
		// currently being written, then successfully break out of this loop
		if ( (pMessage >= pTail) || (pMessage->state == SHMEM_Q_BEING_WRITTEN) )
		{
			// All messages are being read or the next message in order is not 
			// ready. I need to reset MsgAvailableEvent, wait for it to be 
			// signalled and then start over
			if (m_bUseEvent)
			{
				ResetEvent(m_hMsgAvailableEvent);
				unlock(m_plQMutex);
				return false;
			}
			else
			{
				resetevent(m_plMsgAvailableTrigger);
				unlock(m_plQMutex);
				return false;
			}
		}
	}

	MessageQueue::MsgQueueElement *pElement;
	if (pMessage->from == -1)
	{
		unlock(m_plQMutex);
		return false;
	}
	if (pMessage->state == SHMEM_Q_SHP_AVAIL_FOR_READ)
	{
		shpData data;

		memcpy(&data, (LPBYTE)pMessage + sizeof(ShmemLockedQueueHeader), 
			sizeof(shpData));

		void *pLocal = 
			g_MsgQueue.GetBufferToFill(pMessage->tag, data.length, 
										pMessage->from, &pElement);
		if (!ReadProcessMemory(	
				g_hProcesses[pMessage->from], 
				data.address, pLocal, data.length , NULL))
			//nt_error("Unable to read remote memory", pMessage->from);
			MakeErrMsg(GetLastError(), "Unable to read remote memory in process %d", pMessage->from);
		SetEvent(g_hShpSendCompleteEvent[g_nIproc]);
		g_MsgQueue.SetElementEvent(pElement);
	}
	else
	{
		void *pBuffer = pMsgQueue->GetBufferToFill(
			pMessage->tag, pMessage->length, pMessage->from, &pElement);
		
		// Mark the message as being read
		pMessage->state = SHMEM_Q_BEING_READ;
		unlock(m_plQMutex);
		
		// Read the data from the message
		memcpy(pBuffer, (LPBYTE)pMessage + sizeof(ShmemLockedQueueHeader), 
				pMessage->length);
		pMsgQueue->SetElementEvent(pElement);
		
		lock(m_plQMutex);
	}
	// Mark the message as having been read
	pMessage->state = SHMEM_Q_READ;

	// Update the head and tail pointers of the queue
	pHead = SHMEM_Q_HEAD_PTR;
	pTail = SHMEM_Q_TAIL_PTR;
		
	// Advance the head pointer over all the read messages
	while ( (pHead < pTail) && (pHead->state == SHMEM_Q_READ) )
		pHead = (ShmemLockedQueueHeader*)((LPBYTE)pHead + pHead->next_offset);

	if (pHead >= pTail)
	{
		// When the head catches up to the tail, the queue is empty so reset 
		// the pointers and signal the queue empty
		SHMEM_Q_HEAD_OFFSET = 0;
		SHMEM_Q_TAIL_OFFSET = 2*sizeof(unsigned long);
		if (m_bUseEvent)
			ResetEvent(m_hMsgAvailableEvent);
		else
			resetevent(m_plMsgAvailableTrigger);
		setevent(m_plQEmptyTrigger);
	}
	else
		SHMEM_Q_HEAD_OFFSET = (unsigned long)((LPBYTE)pHead - (LPBYTE)m_pBase);

	unlock(m_plQMutex);

	return true;
}
コード例 #4
0
// Function name	: ShmemLockedQueue::RemoveNext
// Description	    : 
// Return type		: bool 
// Argument         : unsigned char *buffer
// Argument         : unsigned int *length
// Argument         : int *tag
// Argument         : int *from
bool ShmemLockedQueue::RemoveNext(
	unsigned char *buffer, unsigned int *length, int *tag, int *from)
{
	ShmemLockedQueueHeader *pTail, *pHead, *pMessage;

	// Get the next available entry in the queue
	while(true)
	{
		// Get the queue mutex
		lock(m_plQMutex);
		
		// Wait for the queue to not be empty
		while (SHMEM_Q_HEAD_OFFSET == 0)
		{
			unlock(m_plQMutex);
			if (m_bUseEvent)
			{
				if (WaitForSingleObject(m_hMsgAvailableEvent, INFINITE) 
						!= WAIT_OBJECT_0)
				{
					printf("ShmemLockedQueue:RemoveNext:Wait for MsgAvailableEvent on an empty queue failed, error %d\n", GetLastError());fflush(stdout);
					return false;
				}
			}
			else
				wait(m_plMsgAvailableTrigger);
			lock(m_plQMutex);
		}
		
		// Search the queue for the next entry not being read by another thread
		pMessage = SHMEM_Q_HEAD_PTR;
		pTail = SHMEM_Q_TAIL_PTR;
		
		while ((pMessage->state == SHMEM_Q_BEING_READ) && (pMessage < pTail))
			pMessage = (ShmemLockedQueueHeader*)
				((LPBYTE)pMessage + pMessage->next_offset);
		
		// If we haven't reached the tail and the element we are on is not 
		// currently being written, then successfully break out of this loop
		if ( (pMessage < pTail) && (pMessage->state != SHMEM_Q_BEING_WRITTEN) )
			break;

		// All messages are being read or the next message in order is 
		// not ready. I need to reset MsgAvailableEvent, wait for it to be 
		// signalled and then start over
		if (m_bUseEvent)
		{
			ResetEvent(m_hMsgAvailableEvent);
			unlock(m_plQMutex);
			if (WaitForSingleObject(m_hMsgAvailableEvent, INFINITE) 
					!= WAIT_OBJECT_0)
			{
				printf("ShmemLockedQueue:RemoveNext:Wait for MsgAvailableEvent failed, error %d\n", GetLastError());fflush(stdout);
				return false;
			}
		}
		else
		{
			resetevent(m_plMsgAvailableTrigger);
			unlock(m_plQMutex);
			wait(m_plMsgAvailableTrigger);
		}
	}

	// Check that the buffer provided is large enough to hold the data
	if (pMessage->length > *length)
	{
		printf("ShmemLockedQueue:RemoveNext:shmem message length %d > %d user buffer length\n", pMessage->length, *length);
		unlock(m_plQMutex);
		return false;
	}

	// Mark the message as being read
	pMessage->state = SHMEM_Q_BEING_READ;
	unlock(m_plQMutex);

	// Read the data from the message
	*tag = pMessage->tag;
	*from = pMessage->from;
	*length = pMessage->length;
	memcpy(buffer, 
		(LPBYTE)pMessage + sizeof(ShmemLockedQueueHeader), pMessage->length);

	lock(m_plQMutex);
	// Mark the message as having been read
	pMessage->state = SHMEM_Q_READ;

	// Update the head and tail pointers of the queue
	pHead = SHMEM_Q_HEAD_PTR;
	pTail = SHMEM_Q_TAIL_PTR;
		
	// Advance the head pointer over all the read messages
	while ( (pHead < pTail) && (pHead->state == SHMEM_Q_READ) )
		pHead = (ShmemLockedQueueHeader*)((LPBYTE)pHead + pHead->next_offset);

	if (pHead >= pTail)
	{
		// When the head catches up to the tail, 
		// the queue is empty so reset the pointers and signal the queue empty
		SHMEM_Q_HEAD_OFFSET = 0;
		SHMEM_Q_TAIL_OFFSET = 2*sizeof(unsigned long);
		if (m_bUseEvent)
			ResetEvent(m_hMsgAvailableEvent);
		else
			resetevent(m_plMsgAvailableTrigger);
		setevent(m_plQEmptyTrigger);
	}
	else
		SHMEM_Q_HEAD_OFFSET = (unsigned long)((LPBYTE)pHead - (LPBYTE)m_pBase);

	unlock(m_plQMutex);

	return true;
}
コード例 #5
0
bool ShmemLockedQueue::InsertSHP(
	unsigned char *buffer, unsigned int length, int tag, int from, 
	HANDLE hRemoteMutex, HANDLE hRemoteEvent, ShmemLockedQueue *pOtherQueue)
{
	ShmemLockedQueueHeader *pMessage;
	shpData data;
	data.address = buffer;
	data.length = length;
	
	WaitForSingleObject(hRemoteMutex, INFINITE);

	lock(m_plQMutex);

	// Wait for a contiguous block large enough to hold the data 
	while ( ( SHMEM_Q_TAIL_PTR >= m_pEnd ) || 
			( (unsigned long)m_pEnd - 
			  (unsigned long)SHMEM_Q_TAIL_PTR - 
			   sizeof(ShmemLockedQueueHeader) < sizeof(shpData) ) )
	{
		unlock(m_plQMutex);
		if (m_pProgressPollFunction)
		{
			while (!test(m_plQEmptyTrigger))
				m_pProgressPollFunction();
		}
		else
			wait(m_plQEmptyTrigger);
		lock(m_plQMutex);
	}

	// Read the tail pointer
	pMessage = SHMEM_Q_TAIL_PTR;
	// If the head offset is 0, set it to the tail
	if ( SHMEM_Q_HEAD_OFFSET == 0 )
		SHMEM_Q_HEAD_OFFSET = SHMEM_Q_TAIL_OFFSET;

	// Set the state and advance the tail offset
	pMessage->state = SHMEM_Q_BEING_WRITTEN;
	// Advance the tail offset
	SHMEM_Q_TAIL_OFFSET = (unsigned long)(
		(unsigned long)pMessage + 
		sizeof(ShmemLockedQueueHeader) + 
		sizeof(shpData) - (unsigned long)m_pBase);
	unlock(m_plQMutex);

	// Write the header
	pMessage->tag = tag;
	pMessage->from = from;
	pMessage->length = sizeof(shpData);
	pMessage->next_offset = (sizeof(ShmemLockedQueueHeader) + sizeof(shpData));
	
	// Copy the data
	memcpy((LPBYTE)pMessage + sizeof(ShmemLockedQueueHeader), 
		&data, sizeof(shpData));

	lock(m_plQMutex);
	// Signal data has arrived and release the mutex
	pMessage->state = SHMEM_Q_SHP_AVAIL_FOR_READ;
	if (m_bUseEvent)
		SetEvent(m_hMsgAvailableEvent);
	else
		setevent(m_plMsgAvailableTrigger);
	resetevent(m_plQEmptyTrigger);
	unlock(m_plQMutex);

	if (g_MsgQueue.m_pProgressPollFunction)
	{
		while (WaitForSingleObject(hRemoteEvent, 0) != WAIT_OBJECT_0)
			g_MsgQueue.m_pProgressPollFunction();
	}
	else if (pOtherQueue->m_pProgressPollFunction)
	{
		while (WaitForSingleObject(hRemoteEvent, 0) != WAIT_OBJECT_0)
			pOtherQueue->m_pProgressPollFunction();
			//pOtherQueue->RemoveNextInsert(&g_MsgQueue, false);
	}
	else
		WaitForSingleObject(hRemoteEvent, INFINITE);

	ResetEvent(hRemoteEvent);
	ReleaseMutex(hRemoteMutex);
	return true;
}
コード例 #6
0
// Function name	: ShmemLockedQueue::Insert
// Description	    : 
// Return type		: bool 
// Argument         : unsigned char *buffer
// Argument         : unsigned int length
// Argument         : int tag
// Argument         : int from
bool ShmemLockedQueue::Insert(
	unsigned char *buffer, unsigned int length, int tag, int from)
{
	ShmemLockedQueueHeader *pMessage;

	lock(m_plQMutex);

	if (length > m_dwMaxMsgSize)
	{
		unlock(m_plQMutex);
		return false;
	}

	// Wait for a contiguous block large enough to hold the data 
	while ( ( SHMEM_Q_TAIL_PTR >= m_pEnd ) || 
			( (unsigned long)m_pEnd - 
			  (unsigned long)SHMEM_Q_TAIL_PTR - 
			   sizeof(ShmemLockedQueueHeader) < length) )
	{
		unlock(m_plQMutex);
		if (m_pProgressPollFunction)
		{
			while (!test(m_plQEmptyTrigger))
				m_pProgressPollFunction();
		}
		else
			wait(m_plQEmptyTrigger);
		lock(m_plQMutex);
	}

	// Read the tail pointer
	pMessage = SHMEM_Q_TAIL_PTR;
	// If the head offset is 0, set it to the tail
	if ( SHMEM_Q_HEAD_OFFSET == 0 )
		SHMEM_Q_HEAD_OFFSET = SHMEM_Q_TAIL_OFFSET;

	// Set the state and advance the tail offset
	pMessage->state = SHMEM_Q_BEING_WRITTEN;
	// Advance the tail offset
	SHMEM_Q_TAIL_OFFSET = 
		(unsigned long)(
			(unsigned long)pMessage + 
			sizeof(ShmemLockedQueueHeader) + 
			length - (unsigned long)m_pBase);
	unlock(m_plQMutex);

	// Write the header
	pMessage->tag = tag;
	pMessage->from = from;
	pMessage->length = length;
	pMessage->next_offset = (sizeof(ShmemLockedQueueHeader) + length);
	
	// Copy the data
	memcpy((LPBYTE)pMessage + sizeof(ShmemLockedQueueHeader), buffer, length);

	lock(m_plQMutex);
	// Signal data has arrived and release the mutex
	pMessage->state = SHMEM_Q_AVAIL_FOR_READ;
	if (m_bUseEvent)
		SetEvent(m_hMsgAvailableEvent);
	else
		setevent(m_plMsgAvailableTrigger);
	resetevent(m_plQEmptyTrigger);
	unlock(m_plQMutex);

	return true;
}