예제 #1
0
static void midi_dispose_buffer(MidiBuffer * node, const char * caller)
{
    MMRESULT rv;
    
    if (node->prepared) {
        rv = midiOutUnprepareHeader( (HMIDIOUT) midiStream, &node->hdr, sizeof(MIDIHDR) );
        if (rv != MMSYSERR_NOERROR) {
            midi_error(rv, "WinMM %s/midi_dispose_buffer midiOutUnprepareHeader", caller);
        }
        node->prepared = FALSE;
    }

    if (midiThread) {
        // remove the node from the activeMidiBuffers list
        LL_Remove( node, next, prev );
    
        // when playing, we keep the buffers
        LL_Add( (MidiBuffer*) &spareMidiBuffers, node, next, prev );
        //fprintf(stderr, "WinMM %s/midi_dispose_buffer recycling buffer %p\n", caller, node);
    } else {
        // when not, we throw them away
        free(node);
        //fprintf(stderr, "WinMM %s/midi_dispose_buffer freeing buffer %p\n", caller, node);
    }
}
예제 #2
0
파일: screen.c 프로젝트: emteejay/lcdproc
/** Remove a widget from a screen.
 * \param s  Screen to remove the widget \c w from.
 * \param w  Widget to be removed from \c s.
 * \retval <0  Error.
 * \retval  0  Success.
 */
int
screen_remove_widget(Screen *s, Widget *w)
{
	debug(RPT_DEBUG, "%s(s=[%.40s], widget=[%.40s])", __FUNCTION__, s->id, w->id);

	LL_Remove(s->widgetlist, (void *) w, NEXT);

	return 0;
}
예제 #3
0
void LL_DeleteList(LINKED_LIST_t* linkedList)
{
	LIST_NODE_t* node;
	node = linkedList->first;

	while(node)
	{
		LL_Remove(linkedList, node);
		node = linkedList->first;
	}
}
int
screenlist_remove(Screen *s)
{
	debug(RPT_DEBUG, "%s(s=[%.40s])", __FUNCTION__, s->id);

	if (!screenlist)
		return -1;

	/* Are we trying to remove the current screen ? */
	if (s == current_screen) {
		screenlist_goto_next();
		if (s == current_screen) {
			/* Hmm, no other screen had same priority */
			void *res = LL_Remove(screenlist, s, NEXT);
			/* And now once more */
			screenlist_goto_next();
			return (res == NULL) ? -1 : 0;
		}
	}
	return (LL_Remove(screenlist, s, NEXT) == NULL) ? -1 : 0;
}
예제 #5
0
void LL_DeleteListAndData(LINKED_LIST_t* linkedList)
{
	LIST_NODE_t* node;
	node = linkedList->first;

	while(node)
	{
		LL_Free(node->data);
		LL_Remove(linkedList, node);
		node = linkedList->first;
	}
}
예제 #6
0
void* LL_PopData(LINKED_LIST_t* linkedList)
{
    LIST_NODE_t* retNode;
    void* data = NULL;
    retNode = linkedList->first;
    if( retNode )
    {
        data = retNode->data;
    }

    LL_Remove(linkedList, retNode);
    return data;
}
예제 #7
0
파일: multivoc.c 프로젝트: dahlor/Duke3DS
VoiceNode *MV_AllocVoice(int32_t priority)
{
    VoiceNode   *voice, *node;

    DisableInterrupts();

    // Check if we have any free voices
    if (LL_Empty(&VoicePool, next, prev))
    {
        // check if we have a higher priority than a voice that is playing.
        for (voice = node = VoiceList.next; node != &VoiceList; node = node->next)
        {
            if (node->priority < voice->priority)
                voice = node;
        }

        if (priority >= voice->priority && voice != &VoiceList && voice->handle >= MV_MINVOICEHANDLE)
            MV_Kill(voice->handle);

        if (LL_Empty(&VoicePool, next, prev))
        {
            // No free voices
            RestoreInterrupts();
            return NULL;
        }
    }

    voice = VoicePool.next;
    LL_Remove(voice, next, prev);
    RestoreInterrupts();

    int32_t vhan = MV_MINVOICEHANDLE;

    // Find a free voice handle
    do
    {
        if (++vhan < MV_MINVOICEHANDLE || vhan > MV_MaxVoices)
            vhan = MV_MINVOICEHANDLE;
    } while (MV_VoicePlaying(vhan));

    voice->handle = vhan;

    return voice;
}
예제 #8
0
파일: alist.c 프로젝트: job/irrd
int
remove_access_list (int num, int permit, prefix_t *prefix, prefix_t *wildcard,
                    int exact, int refine) {
    condition_t *condition;

    if (num < 0 || num >= MAX_ALIST)
        return (-1);
    if (access_list[num] == NULL) {
        return (-1);
    }
    condition = find_access_list (num, permit, prefix, wildcard, exact, refine);
    if (condition == NULL)
        return (-1);

    Deref_Prefix (condition->prefix);
    Deref_Prefix (condition->wildcard);
    LL_Remove (access_list[num], condition);

    return (LL_GetCount (access_list[num]));
}
예제 #9
0
/*
=================
FreeEdict

Marks the edict as free
=================
*/
void Level::FreeEdict( gentity_t *ed )
{
	gclient_t *client;
	
	assert( ed != &free_edicts );
	
	// unlink from world
	gi.unlinkentity ( ed );
	
	assert( ed->next );
	assert( ed->prev );
	
	if ( next_edict == ed )
	{
		next_edict = ed->next;
	}
	
	LL_Remove( ed, next, prev );
	
	assert( ed->next == ed );
	assert( ed->prev == ed );
	assert( free_edicts.next );
	assert( free_edicts.prev );
	
	client = ed->client;
	memset( ed, 0, sizeof( *ed ) );
	ed->client = client;
	ed->freetime = time;
	ed->inuse = false;
	ed->s.number = ed - g_entities;
	
	assert( free_edicts.next );
	assert( free_edicts.prev );
	
	LL_Add( &free_edicts, ed, next, prev );
	
	assert( ed->next );
	assert( ed->prev );
}
예제 #10
0
static void midi_free_buffers(void)
{
    MidiBuffer *node, *next;

    //fprintf(stderr, "waiting for active buffers to return\n");
    while (!LL_ListEmpty(&activeMidiBuffers, next, prev)) {
        // wait for Windows to finish with all the buffers queued
        midi_gc_buffers();
        //fprintf(stderr, "waiting...\n");
        Sleep(10);
    }
    //fprintf(stderr, "waiting over\n");

    for ( node = spareMidiBuffers.next; node != &spareMidiBuffers; node = next ) {
        next = node->next;
        LL_Remove( node, next, prev );
        free(node);
        //fprintf(stderr, "WinMM midi_free_buffers freeing buffer %p\n", node);
    }
    
    assert(currentMidiBuffer == 0);
}
예제 #11
0
파일: multivoc.c 프로젝트: dahlor/Duke3DS
static void MV_StopVoice(VoiceNode *voice)
{
    DisableInterrupts();

    // move the voice from the play list to the free list
    LL_Remove(voice, next, prev);
    LL_Add((VoiceNode*) &VoicePool, voice, next, prev);

    RestoreInterrupts();

    switch (voice->wavetype)
    {
#ifdef HAVE_VORBIS
        case FMT_VORBIS: MV_ReleaseVorbisVoice(voice); break;
#endif
#ifdef HAVE_FLAC
        case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
#endif
        case FMT_XA: MV_ReleaseXAVoice(voice); break;
        default: break;
    }

    voice->handle = 0;
}
예제 #12
0
파일: guswave.c 프로젝트: Rockbox/rockbox
static int LOADDS GUSWAVE_DebugCallBack
   (
   int reason,
   int voice,
   unsigned char **buf,
   unsigned long *size
   )

   {
   VoiceNode *Voice;

   // this function is called from an interrupt
   // remember not to make any DOS or BIOS calls from here
   // also don't call any C library functions unless you are sure that
   // they are reentrant
   // restore our DS register

   if ( VoiceStatus[ voice ].playing == FALSE )
      {
//      DB_printf( "GUS Voice %d not playing.\n", voice );
      DB_printf( "GUS Voice " );
      DB_PrintNum( voice );
      DB_printf( " not playing.\n" );
      return( DIG_DONE );
         }

      if ( reason == DIG_MORE_DATA )
         {
         Voice = VoiceStatus[ voice ].Voice;

//         DB_printf( "Voice %d : More data -- ", Voice );
         DB_printf( "Voice " );
         DB_PrintNum( voice );
         DB_printf( " : More data -- " );
         if ( Voice != NULL )
            {
            if ( Voice->Playing )
               {
               GUSWAVE_GetNextVOCBlock( Voice );
               if ( Voice->Playing )
                  {
//                  DB_printf( "More data -- size = %u blocklength = %u\n",
//                     Voice->length, Voice->BlockLength );
                  DB_printf( "More data -- size = " );
                  DB_PrintNum( Voice->length );
                  DB_printf( " blocklength = " );
                  DB_PrintNum( Voice->BlockLength );
                  DB_printf( "\n" );
                  *buf  = Voice->sound;
                  *size = Voice->length;
                  return( DIG_MORE_DATA );
                  }
               else
                  {
                  DB_printf( "Voice done.\n" );
                  }
               }
            else
               {
               DB_printf( "Voice not active.\n" );
               }
            }
         else
            {
            DB_printf( " NULL Voice\n" );
            }

         return( DIG_DONE );
         }

      if ( reason == DIG_DONE )
         {
         VoiceStatus[ voice ].playing = FALSE;
         Voice = VoiceStatus[ voice ].Voice;
//         DB_printf( "Voice %d : Done -- ", Voice );
         DB_printf( "Voice " );
         DB_PrintNum( voice );
         DB_printf( " : Done -- " );

         if ( Voice != NULL )
            {
            DB_printf( "Ok\n" );

            Voice->Active   = FALSE;
            Voice->Playing  = FALSE;

// I'm commenting this out because a -1 could cause a crash if it
// is sent to the GF1 code.  This shouldn't be necessary since
// Active should be false when GF1voice is -1, but this is just
// a precaution.  Adjust the pan on the wrong voice is a lot
// more pleasant than a crash!
//         Voice->GF1voice = -1;

         LL_Remove( VoiceNode, &VoiceList, Voice );
         LL_AddToTail( VoiceNode, &VoicePool, Voice );
         }
      else
         {
         DB_printf( "Null voice\n" );
         }

      if ( GUSWAVE_CallBackFunc )
         {
         GUSWAVE_CallBackFunc( Voice->callbackval );
         }
      }

   return( DIG_DONE );
   }
예제 #13
0
파일: guswave.c 프로젝트: Rockbox/rockbox
static int LOADDS GUSWAVE_CallBack
   (
   int reason,
   int voice,
   unsigned char **buf,
   unsigned long *size
   )

   {
   VoiceNode *Voice;
   playbackstatus status;

   // this function is called from an interrupt
   // remember not to make any DOS or BIOS calls from here
   // also don't call any C library functions unless you are sure that
   // they are reentrant
   // restore our DS register

   if ( VoiceStatus[ voice ].playing == FALSE )
      {
      return( DIG_DONE );
      }

   if ( reason == DIG_MORE_DATA )
      {
//      SetBorderColor(16);
      Voice = VoiceStatus[ voice ].Voice;

      if ( ( Voice != NULL ) && ( Voice->Playing ) )
/*
         {
         *buf = ( unsigned char * )GUS_Silence16;
         *size = 1024;

         SetBorderColor(0);
         return( DIG_MORE_DATA );
         }
 */
         {
         status = Voice->GetSound( Voice );
         if ( status != SoundDone )
            {
            if ( ( Voice->sound == NULL ) || ( status == NoMoreData ) )
               {
               if ( Voice->bits == 8 )
                  {
                  *buf = GUS_Silence8;
                  }
               else
                  {
                  *buf = ( unsigned char * )GUS_Silence16;
                  }
               *size = 256;
               }
            else
               {
               *buf  = Voice->sound;
               *size = Voice->length;
               }
            return( DIG_MORE_DATA );
            }
         }
//      SetBorderColor(16);
      return( DIG_DONE );
      }

   if ( reason == DIG_DONE )
      {
      Voice = VoiceStatus[ voice ].Voice;
      VoiceStatus[ voice ].playing = FALSE;

      if ( Voice != NULL )
         {
         Voice->Active   = FALSE;
         Voice->Playing  = FALSE;

// I'm commenting this out because a -1 could cause a crash if it
// is sent to the GF1 code.  This shouldn't be necessary since
// Active should be false when GF1voice is -1, but this is just
// a precaution.  Adjust the pan on the wrong voice is a lot
// more pleasant than a crash!
//         Voice->GF1voice = -1;

         LL_Remove( VoiceNode, &VoiceList, Voice );
         LL_AddToTail( VoiceNode, &VoicePool, Voice );
         }

      if ( GUSWAVE_CallBackFunc )
         {
         GUSWAVE_CallBackFunc( Voice->callbackval );
         }
      }

   return( DIG_DONE );
   }
예제 #14
0
/*
=================
AllocEdict

Either finds a free edict, or allocates a new one.
Try to avoid reusing an entity that was recently freed, because it
can cause the client to think the entity morphed into something else
instead of being removed and recreated, which can cause interpolated
angles and bad trails.
=================
*/
gentity_t *Level::AllocEdict( Entity *ent )
{
	int		   i;
	gentity_t   *edict;
	
	if ( spawn_entnum >= 0 )
	{
		edict = &g_entities[ spawn_entnum ];
		spawn_entnum = -1;
		
		assert( !edict->inuse && !edict->entity );
		
		// free up the entity pointer in case we took one that still exists
		if ( edict->inuse && edict->entity )
		{
			delete edict->entity;
		}
	}
	else
	{
		edict = &g_entities[ maxclients->integer ];
		for ( i = maxclients->integer; i < globals.num_entities; i++, edict++ )
		{
			// the first couple seconds of server time can involve a lot of
			// freeing and allocating, so relax the replacement policy
			if (
				!edict->inuse &&
				(
				( edict->freetime < ( 2.0f + startTime ) ) ||
				( time - edict->freetime > 0.5f )
				)
				)
			{
				break;
			}
		}
		
		// allow two spots for none and world
		if ( i == game.maxentities - 2.0f )
		{
			// Try one more time before failing, relax timing completely

			edict = &g_entities[ maxclients->integer ];

			for ( i = maxclients->integer; i < globals.num_entities; i++, edict++ )
			{
				if ( !edict->inuse )
				{
					break;
				}
			}

			if ( i == game.maxentities - 2.0f )
			{
				gi.Error( ERR_DROP, "Level::AllocEdict: no free edicts" );
			}
		}
	}
	
	assert( edict->next );
	assert( edict->prev );
	LL_Remove( edict, next, prev );
	InitEdict( edict );
	assert( active_edicts.next );
	assert( active_edicts.prev );
	LL_Add( &active_edicts, edict, next, prev );
	assert( edict->next );
	assert( edict->prev );
	
	assert( edict->next != &free_edicts );
	assert( edict->prev != &free_edicts );
	
	// Tell the server about our data since we just spawned something
	if ( ( edict->s.number < ENTITYNUM_WORLD ) && ( globals.num_entities <= edict->s.number ) )
	{
		globals.num_entities = edict->s.number + 1;
		gi.LocateGameData( g_entities, globals.num_entities, sizeof( gentity_t ), &game.clients[ 0 ].ps, sizeof( game.clients[ 0 ] ) );
	}
	
	edict->entity = ent;
	edict->s.instanceNumber = currentInstanceNumber;
	currentInstanceNumber++;

	if ( currentInstanceNumber < 0 )
		currentInstanceNumber = 0;
	
	return edict;
}
예제 #15
0
/* Gets space in the buffer presently being filled.
   If insufficient space can be found in the buffer,
   what is there is flushed to the stream and a new
   buffer large enough is allocated.
   
   Returns a pointer to starting writing at in 'data'.
 */
static BOOL midi_get_buffer(int length, unsigned char ** data)
{
    int datalen;
    MidiBuffer * node;
    
    // determine the space to alloc.
    // the size of a MIDIEVENT is 3*sizeof(DWORD) = 12.
    // short messages need only that amount of space.
    // long messages need additional space equal to the length of
    //    the message, padded to 4 bytes
    
    if (length <= 3) {
        datalen = 12;
    } else {
        datalen = 12 + length;
        if ((datalen & 3) > 0) {
            datalen += 4 - (datalen & 3);
        }
    }
    
    if (!midiThread) {
        assert(currentMidiBuffer == 0);
    }
    
    if (currentMidiBuffer && (currentMidiBuffer->hdr.dwBufferLength -
            currentMidiBuffer->hdr.dwBytesRecorded) >= datalen) {
        // there was enough space in the current buffer, so hand that back
        midi_setup_event(length, data);
        
        currentMidiBuffer->hdr.dwBytesRecorded += datalen;
        
        return TRUE;
    }
    
    if (currentMidiBuffer) {
        // not enough space in the current buffer to accommodate the
        // new data, so flush it to the stream
        midi_flush_current_buffer();
        currentMidiBuffer = 0;
    }
    
    // check if there's a spare buffer big enough to hold the message
    if (midiThread) {
        for ( node = spareMidiBuffers.next; node != &spareMidiBuffers; node = node->next ) {
            if (node->hdr.dwBufferLength >= datalen) {
                // yes!
                LL_Remove( node, next, prev );
                
                node->hdr.dwBytesRecorded = 0;
                memset(node->hdr.lpData, 0, node->hdr.dwBufferLength);
                
                currentMidiBuffer = node;
                
                //fprintf(stderr, "WinMM midi_get_buffer fetched buffer %p\n", node);
                break;
            }
        }
    }
    
    if (!currentMidiBuffer) {
        // there were no spare buffers, or none were big enough, so
        // allocate a new one
        int size;
        
        if (midiThread) {
            // playing a file, so allocate a buffer for more than
            // one event
            size = max(MIDI_BUFFER_SPACE, datalen);
        } else {
            // not playing a file, so allocate just a buffer for
            // the event we'll be sending immediately
            size = datalen;
        }
        
        node = (MidiBuffer *) malloc( sizeof(MidiBuffer) + size );
        if (node == 0) {
            return FALSE;
        }

        memset(node, 0, sizeof(MidiBuffer) + datalen);
        node->hdr.dwUser = (DWORD_PTR) node;
        node->hdr.lpData = (LPSTR) ((intptr_t)node + sizeof(MidiBuffer));
        node->hdr.dwBufferLength = size;
        node->hdr.dwBytesRecorded = 0;
        
        currentMidiBuffer = node;
        
        //fprintf(stderr, "WinMM midi_get_buffer allocated buffer %p\n", node);
    }

    midi_setup_event(length, data);

    currentMidiBuffer->hdr.dwBytesRecorded += datalen;
    
    return TRUE;
}
예제 #16
0
파일: multivoc.c 프로젝트: dahlor/Duke3DS
/*---------------------------------------------------------------------
   JBF: no synchronisation happens inside MV_ServiceVoc nor the
        supporting functions it calls. This would cause a deadlock
        between the mixer thread in the driver vs the nested
        locking in the user-space functions of MultiVoc. The call
        to MV_ServiceVoc is synchronised in the driver.
---------------------------------------------------------------------*/
static void MV_ServiceVoc(void)
{
    // Toggle which buffer we'll mix next
    if (++MV_MixPage >= MV_NumberOfBuffers)
        MV_MixPage -= MV_NumberOfBuffers;

    if (MV_ReverbLevel == 0)
    {
        // Initialize buffer
        //Commented out so that the buffer is always cleared.
        //This is so the guys at Echo Speech can mix into the
        //buffer even when no sounds are playing.
        if (!MV_BufferEmpty[MV_MixPage])
        {
            Bmemset(MV_MixBuffer[MV_MixPage], 0, MV_BufferSize);
            MV_BufferEmpty[ MV_MixPage ] = TRUE;
        }
    }
    else
    {
        char const *const end = MV_MixBuffer[0] + MV_BufferLength;
        char *dest = MV_MixBuffer[MV_MixPage];
        char const *source = MV_MixBuffer[MV_MixPage] - MV_ReverbDelay;

        if (source < MV_MixBuffer[ 0 ])
            source += MV_BufferLength;

        int32_t length = MV_BufferSize;

        while (length > 0)
        {
            int const count = (source + length > end) ? (end - source) : length;

            MV_16BitReverb(source, dest, MV_ReverbTable, count / 2);

            // if we go through the loop again, it means that we've wrapped around the buffer
            source  = MV_MixBuffer[ 0 ];
            dest   += count;
            length -= count;
        }
    }

    // Play any waiting voices
    //DisableInterrupts();

    VoiceNode *voice;

    if (!VoiceList.next || (voice = VoiceList.next) == &VoiceList)
        return;

    int iter = 0;

    VoiceNode *next;

    do
    {
        next = voice->next;

        if (++iter > MV_MaxVoices && MV_Printf)
            MV_Printf("more iterations than voices! iter: %d\n",iter);

        if (voice->Paused)
            continue;

        MV_BufferEmpty[ MV_MixPage ] = FALSE;

        MV_Mix(voice, MV_MixPage);

        // Is this voice done?
        if (!voice->Playing)
        {
            //JBF: prevent a deadlock caused by MV_StopVoice grabbing the mutex again
            //MV_StopVoice( voice );
            LL_Remove(voice, next, prev);
            LL_Add((VoiceNode*) &VoicePool, voice, next, prev);

            switch (voice->wavetype)
            {
#ifdef HAVE_VORBIS
                case FMT_VORBIS: MV_ReleaseVorbisVoice(voice); break;
#endif
#ifdef HAVE_FLAC
                case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
#endif
                case FMT_XA: MV_ReleaseXAVoice(voice); break;
                default: break;
            }

            voice->handle = 0;

            if (MV_CallBackFunc)
                MV_CallBackFunc(voice->callbackval);
        }
    }
    while ((voice = next) != &VoiceList);

    //RestoreInterrupts();
}