Beispiel #1
0
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	/* Try the easy cases first */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}
	if ( timeout == SDL_MUTEX_MAXWAIT ) {
		return SDL_SemWait(sem);
	}

	/* Ack!  We have to busy wait... */
	timeout += SDL_GetTicks();
	do {
		retval = SDL_SemTryWait(sem);
		if ( retval == 0 ) {
			break;
		}
		SDL_Delay(1);
	} while ( SDL_GetTicks() < timeout );

	return retval;
}
Beispiel #2
0
void
Android_PumpEvents(_THIS)
{
    static int isPaused = 0;
#if SDL_ANDROID_BLOCK_ON_PAUSE
    static int isPausing = 0;
#endif
    /* No polling necessary */
    android_handle_bledid(SDL_TRUE);

    /*
     * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
     * When the pause semaphore is signaled, if SDL_ANDROID_BLOCK_ON_PAUSE is defined the event loop will block until the resume signal is emitted.
     */

#if SDL_ANDROID_BLOCK_ON_PAUSE
    if (isPaused && !isPausing) {
        /* Make sure this is the last thing we do before pausing */
        android_egl_context_backup();
        AndroidAUD_PauseDevices();
        if(SDL_SemWait(Android_ResumeSem) == 0) {
#else
    if (isPaused) {
        if(SDL_SemTryWait(Android_ResumeSem) == 0) {
#endif
            isPaused = 0;
            AndroidAUD_ResumeDevices();
            /* Restore the GL Context from here, as this operation is thread dependent */
            if (!SDL_HasEvent(SDL_QUIT)) {
                android_egl_context_restore();
            }
        }
    }
    else {
#if SDL_ANDROID_BLOCK_ON_PAUSE
        if( isPausing || SDL_SemTryWait(Android_PauseSem) == 0 ) {
            /* We've been signaled to pause, but before we block ourselves, 
            we need to make sure that certain key events have reached the app */
            if (SDL_HasEvent(SDL_WINDOWEVENT) || SDL_HasEvent(SDL_APP_WILLENTERBACKGROUND) || SDL_HasEvent(SDL_APP_DIDENTERBACKGROUND) ) {
                isPausing = 1;
            }
            else {
                isPausing = 0;
                isPaused = 1;
            }
        }
#else
        if(SDL_SemTryWait(Android_PauseSem) == 0) {
            android_egl_context_backup();
            AndroidAUD_PauseDevices();
            isPaused = 1;
        }
#endif
    }
}
void
Android_PumpEvents(_THIS)
{
    static int isPaused = 0;
#if SDL_ANDROID_BLOCK_ON_PAUSE
    static int isPausing = 0;
#endif
    /* No polling necessary */

    /*
     * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
     * When the pause semaphore is signaled, if SDL_ANDROID_BLOCK_ON_PAUSE is defined the event loop will block until the resume signal is emitted.
     * When the resume semaphore is signaled, SDL_GL_CreateContext is called which in turn calls Java code
     * SDLActivity::createGLContext -> SDLActivity:: initEGL -> SDLActivity::createEGLSurface -> SDLActivity::createEGLContext
     */

#if SDL_ANDROID_BLOCK_ON_PAUSE
    if (isPaused && !isPausing) {
        if(SDL_SemWait(Android_ResumeSem) == 0) {
#else
    if (isPaused) {
        if(SDL_SemTryWait(Android_ResumeSem) == 0) {
#endif
            isPaused = 0;
            /* TODO: Should we double check if we are on the same thread as the one that made the original GL context?
             * This call will go through the following chain of calls in Java:
             * SDLActivity::createGLContext -> SDLActivity:: initEGL -> SDLActivity::createEGLSurface -> SDLActivity::createEGLContext
             * SDLActivity::createEGLContext will attempt to restore the GL context first, and if that fails it will create a new one
             * If a new GL context is created, the user needs to restore the textures manually (TODO: notify the user that this happened with a message)
             */
            SDL_GL_CreateContext(Android_Window);
        }
    }
    else {
#if SDL_ANDROID_BLOCK_ON_PAUSE
        if( isPausing || SDL_SemTryWait(Android_PauseSem) == 0 ) {
            /* We've been signaled to pause, but before we block ourselves, we need to make sure that
            SDL_WINDOWEVENT_FOCUS_LOST and SDL_WINDOWEVENT_MINIMIZED have reached the app */
            if (SDL_HasEvent(SDL_WINDOWEVENT)) {
                isPausing = 1;
            }
            else {
                isPausing = 0;
                isPaused = 1;
            }
        }
#else
        if(SDL_SemTryWait(Android_PauseSem) == 0) {
            /* If we fall in here, the system is/was paused */
            isPaused = 1;
        }
#endif
    }
}
Beispiel #4
0
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	/* A timeout of 0 is an easy case */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}

	SDL_LockMutex(sem->count_lock);
	++sem->waiters_count;
	retval = 0;
	while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
		retval = SDL_CondWaitTimeout(sem->count_nonzero,
		                             sem->count_lock, timeout);
	}
	--sem->waiters_count;
	--sem->count;
	SDL_UnlockMutex(sem->count_lock);

	return retval;
}
Beispiel #5
0
int DRThread::Thread(void* data)
{
	DRThread* t = static_cast<DRThread*>(data);
	while(SDL_SemTryWait(t->semaphore)==SDL_MUTEX_TIMEDOUT)
	{
        if(t->exitCalled) return 0;
		// Lock work mutex
		t->lock();
		int status = SDL_CondWait(t->condition, t->mutex); 
		if(t->exitCalled) return 0;
		if( status == 0)
		{
            int ret = t->ThreadFunction();
            t->unlock();
            if(ret)
            {
                DREngineLog.writeToLog("error-code: %d", ret);
                LOG_ERROR("error in user defined thread, exit thread", -2);
            }
  		}
		else
		{
			//unlock mutex and exit
            t->unlock();
			LOG_ERROR("Fehler in Thread, exit", -1);
		}
	}
    return 0;
}
Beispiel #6
0
int fs_semaphore_try_wait(fs_semaphore *semaphore) {
#if defined(USE_PSEM)
    return sem_trywait(&semaphore->semaphore);
#elif defined(USE_SDL)
    return SDL_SemTryWait(semaphore->semaphore);
#else
#error no thread support
#endif
}
Beispiel #7
0
Datei: sem.c Projekt: amsl/RTGUI
rt_err_t rt_sem_trytake(rt_sem_t sem)
{
	if (SDL_SemTryWait((SDL_sem *)(sem->host_sem)) == 0)
	{
		return RT_EOK;
	}

	return -RT_ETIMEOUT;
}
int CALSAAudioSource::ThreadMain(void) 
{
  debug_message("alsa start");
  while (true) {
    int rc;

    if (m_source) {
      rc = SDL_SemTryWait(m_myMsgQueueSemaphore);
    } else {
      rc = SDL_SemWait(m_myMsgQueueSemaphore);
    }

    // semaphore error
    if (rc == -1) {
      break;
    } 

    // message pending
    if (rc == 0) {
      CMsg* pMsg = m_myMsgQueue.get_message();
		
      if (pMsg != NULL) {
        switch (pMsg->get_value()) {
        case MSG_NODE_STOP_THREAD:
          DoStopCapture();	// ensure things get cleaned up
          delete pMsg;
          debug_message("alsa stop thread");
          return 0;
        case MSG_NODE_START:
          DoStartCapture();
          break;
        case MSG_NODE_STOP:
          DoStopCapture();
          break;
        }

        delete pMsg;
      }
    }

    if (m_source) {
      try {
        //debug_message("processaudio");
        ProcessAudio();
      }
      catch (...) {
        error_message("alsa stop capture");
        DoStopCapture();	
        break;
      }
    }
  }

  debug_message("alsa thread exit");
  return -1;
}
Beispiel #9
0
static void resolverclear(void) {
  SDL_LockMutex(resolvermutex);
  resolverqueries.setsize(0);
  ResolverResults.setsize(0);
  while (SDL_SemTryWait(resolversem) == 0);
  loopv(ResolverThreads) {
    ResolverThread &rt = ResolverThreads[i];
    resolverstop(rt, true);
  }
  SDL_UnlockMutex(resolvermutex);
}
Beispiel #10
0
	bool Semaphore::wait(int timeout)
	{
		if (timeout < 0)
			return SDL_SemWait(semaphore) ? false : true;
		else if (timeout == 0)
			return SDL_SemTryWait(semaphore) ? false : true;
		else
		{
			int ret = SDL_SemWaitTimeout(semaphore, timeout);
			return (ret == 0);
		}
	}
int COSSAudioSource::ThreadMain(void) 
{
  while (true) {
    int rc;

    if (m_source) {
      rc = SDL_SemTryWait(m_myMsgQueueSemaphore);
    } else {
      rc = SDL_SemWait(m_myMsgQueueSemaphore);
    }

    // semaphore error
    if (rc == -1) {
      break;
    } 

    // message pending
    if (rc == 0) {
      CMsg* pMsg = m_myMsgQueue.get_message();
		
      if (pMsg != NULL) {
        switch (pMsg->get_value()) {
        case MSG_NODE_STOP_THREAD:
          DoStopCapture();	// ensure things get cleaned up
          delete pMsg;
          return 0;
        case MSG_NODE_START:
        case MSG_SOURCE_START_AUDIO:
          DoStartCapture();
          break;
        case MSG_NODE_STOP:
          DoStopCapture();
          break;
        }

        delete pMsg;
      }
    }

    if (m_source) {
      try {
        ProcessAudio();
      }
      catch (...) {
        DoStopCapture();	
        break;
      }
    }
  }

  return -1;
}
Beispiel #12
0
void resolverclear()
{
    SDL_LockMutex(resolvermutex);
    resolverqueries.setsize(0);
    resolverresults.setsize(0);
    while (SDL_SemTryWait(resolversem) == 0);
    loopv(resolverthreads)
    {
        resolverthread &rt = resolverthreads[i];
        resolverstop(rt, true);
    };
    SDL_UnlockMutex(resolvermutex);
};
int
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
{
    int retval;
    struct timeval now;
    struct timespec ts_timeout;

    if (!sem) {
        SDL_SetError("Passed a NULL semaphore");
        return -1;
    }

    /* Try the easy cases first */
    if (timeout == 0) {
        return SDL_SemTryWait(sem);
    }
    if (timeout == SDL_MUTEX_MAXWAIT) {
        return SDL_SemWait(sem);
    }

    /* Setup the timeout. sem_timedwait doesn't wait for
    * a lapse of time, but until we reach a certain time.
    * This time is now plus the timeout.
    */
    gettimeofday(&now, NULL);

    /* Add our timeout to current time */
    now.tv_usec += (timeout % 1000) * 1000;
    now.tv_sec += timeout / 1000;

    /* Wrap the second if needed */
    if ( now.tv_usec >= 1000000 ) {
        now.tv_usec -= 1000000;
        now.tv_sec ++;
    }

    /* Convert to timespec */
    ts_timeout.tv_sec = now.tv_sec;
    ts_timeout.tv_nsec = now.tv_usec * 1000;

    /* Wait. */
    do {
        retval = sem_timedwait(&sem->sem, &ts_timeout);
    } while (retval < 0 && errno == EINTR);

    if (retval < 0) {
        SDL_SetError("sem_timedwait() failed");
    }

    return retval;
}
Beispiel #14
0
template <typename T> bool scm_queue<T>::try_insert(T& d)
{
    if (SDL_SemTryWait(free_slots) == 0)
    {
        SDL_LockMutex(data_mutex);
        {
            S.insert(d);
        }
        SDL_UnlockMutex(data_mutex);
        SDL_SemPost(full_slots);
        return true;
    }
    return false;
}
Beispiel #15
0
t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev)
{
    if (SDL_SemTryWait (vid_mouse_events.sem) == 0) {
        if (vid_mouse_events.count > 0) {
            *ev = vid_mouse_events.events[vid_mouse_events.head++];
            vid_mouse_events.count--;
            if (vid_mouse_events.head == MAX_EVENTS)
                vid_mouse_events.head = 0;
            SDL_SemPost (vid_mouse_events.sem);
            return SCPE_OK;
        }
        SDL_SemPost (vid_mouse_events.sem);
    }
    return SCPE_EOF;
}
Beispiel #16
0
t_stat vid_poll_kb (SIM_KEY_EVENT *ev)
{
    if (SDL_SemTryWait (vid_key_events.sem) == 0) {         /* get lock */
        if (vid_key_events.count > 0) {                     /* events in queue? */
            *ev = vid_key_events.events[vid_key_events.head++];
            vid_key_events.count--;
            if (vid_key_events.head == MAX_EVENTS)
                vid_key_events.head = 0;
            SDL_SemPost (vid_key_events.sem);
            return SCPE_OK;
        }
        SDL_SemPost (vid_key_events.sem);
    }
    return SCPE_EOF;
}
Beispiel #17
0
template <typename T> bool scm_queue<T>::try_remove(T& d)
{
    if (SDL_SemTryWait(full_slots) == 0)
    {
        SDL_LockMutex(data_mutex);
        {
            d   = *(S.begin());
            S.erase(S.begin());
        }
        SDL_UnlockMutex(data_mutex);
        SDL_SemPost(free_slots);
        return true;
    }
    return false;
}
Beispiel #18
0
Uint8* AudioQueue_next (AudioQueue* self, int size, bool wait)
{
	if (wait) SDL_SemWait(self->empty_node);
	else if (SDL_SemTryWait(self->empty_node)) return NULL;

	AudioNode* node = self->tail;

	SDL_AudioCVT* cvt = &self->cvt;

	Renew(node->buf, node->alloc_size, size * cvt->len_mult, Uint8);
	cvt->buf = node->buf;
	cvt->len = size;

	node->size = size * cvt->len_mult;
	return node->buf;
}
Beispiel #19
0
void
state_game_update()
{
	newticks = SDL_GetTicks();
	dt = ticks ? newticks - ticks : 0;
	ticks = newticks;

	static uint32_t updatebuild = 0;
	updatebuild += dt;
	if(updatebuild >= 20)
	{
		updatebuild -= 20;
		SDL_SemTryWait(updatesem);
		SDL_SemPost(updatesem);
	}
}
Beispiel #20
0
static mrb_value
mrb_sdl2_semaphore_try_wait(mrb_state *mrb, mrb_value self)
{
  int status;
  mrb_sdl2_semaphore_data_t *data =
    (mrb_sdl2_semaphore_data_t*)mrb_data_get_ptr(mrb, self, &mrb_sdl2_semaphore_data_type);
  if (NULL == data->semaphore) {
    return mrb_nil_value();
  }
  status = SDL_SemTryWait(data->semaphore);
  if (0 > status) {
    mruby_sdl2_raise_error(mrb);
  }
  if (0 == status) {
    return mrb_true_value();
  }
  return mrb_false_value();
}
Beispiel #21
0
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	/* A timeout of 0 is an easy case */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}

	retval = sem_wait_timed(&sem->sem,timeout);
	if (retval==-1) retval= SDL_MUTEX_TIMEDOUT;

	return retval;
}
Beispiel #22
0
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;


	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem));

	/* A timeout of 0 is an easy case */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}
/*
	SDL_LockMutex(sem->count_lock);
	++sem->waiters_count;
	retval = 0;
	while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
		retval = SDL_CondWaitTimeout(sem->count_nonzero,
		                             sem->count_lock, timeout);
	}
	--sem->waiters_count;
	--sem->count;
	SDL_UnlockMutex(sem->count_lock);
*/
	if(!(retval=AttemptSemaphore(&sem->Sem)))
	{
		SDL_Delay(timeout);
		retval=AttemptSemaphore(&sem->Sem);
	}

	if(retval==TRUE)
	{
//		ReleaseSemaphore(&sem->Sem);
		retval=1;
	}

	return retval;
}
  int SourceMusic::Mix(Uint8 *data, int len) {
    if(_sample == NULL) return 0;
#ifndef macintosh
		if( SDL_SemTryWait(_sem) ) {
			fprintf(stderr, "semaphore locked, skipping mix\n");
			return 0;
		}
#endif
		// printf("mixing %d bytes\n", len);

    int volume = (int)(_volume * SDL_MIX_MAXVOLUME);
    // fprintf(stderr, "setting volume to %.3f -> %d\n", _volume, volume);
    // fprintf(stderr, "entering mixer\n");
		
    if(len < (_decoded - _read + _buffersize) % _buffersize) {
			// enough data to mix
			if(_read + len <= _buffersize) {
				SDL_MixAudio(data, _buffer + _read, len, volume);
				_read = (_read + len) % _buffersize;
			} else {
				// wrap around in buffer
				fprintf(stderr, "wrap around in buffer (%d, %d, %d)\n", 
								len, _read, _buffersize);
				
				SDL_MixAudio(data, _buffer + _read, _buffersize - _read, volume);
				len -= _buffersize - _read;
				SDL_MixAudio(data + _buffersize - _read, _buffer, len, volume);
				_read = len;
			}
		} else {
			// buffer under-run
			fprintf(stderr, "buffer underrun!\n");
			// don't do anything
		}

#ifndef macintosh
		SDL_SemPost(_sem);
#endif
    return 1;
  }
Beispiel #24
0
/**
 * @brief Handles assigning jobs to the workers and killing them if necessary.
 * Stopping the threeadpool_handler is not yet implemented.
 *
 * @param data Not used. SDL threading requires functions to take a void
 * pointer as argument.
 *
 * @return Not really implemented yet.
 */
static int threadpool_handler( void *data )
{
   (void) data;
   int i, nrunning, newthread;
   ThreadData *threadargs, *threadarg;
   /* Queues for idle workers and stopped workers */
   ThreadQueue *idle, *stopped;
   ThreadQueueData *node;

   /* Initialize the idle and stopped queues. */
   idle     = tq_create();
   stopped  = tq_create();

   /* Allocate threadargs to communicate with workers */
   threadargs = calloc( MAXTHREADS, sizeof(ThreadData) );

   /* Initialize threadargs */
   for (i=0; i<MAXTHREADS; i++) {
      threadargs[i].function  = NULL;
      threadargs[i].data      = NULL;
      threadargs[i].semaphore = SDL_CreateSemaphore( 0 );
      threadargs[i].idle      = idle;
      threadargs[i].stopped   = stopped;
      threadargs[i].signal    = THREADSIG_RUN;
      /* 'Workers' that do not have a thread are considered stopped */
      tq_enqueue( stopped, &threadargs[i] );
   }

   /* Set the number of running threads to 0 */
   nrunning = 0;

   /*
    * Thread handler main loop.
    */
   while (1) {
      /*
       * We must now wait, this shall be done on each active thread. However they will
       * be put to sleep as time passes. When we receive a command we'll proceed to process
       * it.
       */
      if (nrunning > 0) {
         /*
          * Here we'll wait until thread gets work to do. If it doesn't it will
          * just stop a worker thread and wait until it gets something to do.
          */
         if (SDL_SemWaitTimeout( global_queue->semaphore, THREADPOOL_TIMEOUT ) != 0) {
            /* There weren't any new jobs so we'll start killing threads ;) */
            if (SDL_SemTryWait( idle->semaphore ) == 0) {
               threadarg         = tq_dequeue( idle );
               /* Set signal to stop worker thread */
               threadarg->signal = THREADSIG_STOP;
               /* Signal thread and decrement running threads counter */
               SDL_SemPost( threadarg->semaphore );
               nrunning -= 1;
            }

            /* We just go back to waiting on a thread. */
            continue;
         }

         /* We got work. Continue to handle work. */
      }
      else {
         /*
          * Here we wait for a new job. No threads are alive at this point and the
          * threadpool is just patiently waiting for work to arrive.
          */
         if (SDL_SemWait( global_queue->semaphore ) == -1) {
             WARN("L%d: SDL_SemWait failed! Error: %s", __LINE__, SDL_GetError());
             continue;
         }

         /* We got work. Continue to handle work. */
      }

      /*
       * We assume there's work available. We now have to choose who does the work.
       * We'll try to wake up a sleeping thread, if none are left new threads will
       * be created.
       */

      /*
       * Get a new job from the queue. This should be safe as we have received
       * a permission from the global_queue->semaphore.
       */
      node        = tq_dequeue( global_queue );
      newthread   = 0;

      /*
       * Choose where to get the thread. Either idle, revive stopped or block until
       * another thread becomes idle.
       */
      /* Idle thread available */
      if (SDL_SemTryWait(idle->semaphore) == 0)
         threadarg         = tq_dequeue( idle );
      /* Make a new thread */
      else if (SDL_SemTryWait(stopped->semaphore) == 0) {
         threadarg         = tq_dequeue( stopped );
         threadarg->signal = THREADSIG_RUN;
         newthread         = 1;
      }
      /* Wait for idle thread */
      else {
         while (SDL_SemWait(idle->semaphore) == -1) {
             /* Bad idea */
             WARN("L%d: SDL_SemWait failed! Error: %s", __LINE__, SDL_GetError());
         }
         threadarg         = tq_dequeue( idle );
      }

      /* Assign arguments for the thread */
      threadarg->function  = node->function;
      threadarg->data      = node->data;
      /* Signal the thread that there's a new job */
      SDL_SemPost( threadarg->semaphore );
      /* Start a new thread and increment the thread counter */
      if (newthread) {
         SDL_CreateThread( threadpool_worker, threadarg );
         nrunning += 1;
      }

      /* Free the now unused job from the global_queue */
      free(node);
   }
   /* TODO: cleanup and a way to stop the threadpool */

   return 0;
}
Beispiel #25
0
void Hook_Update()
{
    if (BOOST_LIKELY(SDL_ThreadID() == enabler->renderer_threadid))
    {
        return;
    }

    if (lockstep_want_shutdown)
    {
        while (!lockstep_ready_for_shutdown)
        {
            tthread::this_thread::yield();
        }
        LOCKSTEP_DEBUG("trying to unhook");
        lockstep_want_shutdown = false;
        lockstep_ready_for_shutdown = false;
        Hook_Shutdown();
    }
    else if (!lockstep_hooked && config.lockstep && !Hook_Want_Disable() && !lockstep_want_shutdown_now)
    {
        LOCKSTEP_DEBUG("trying to hook");
        if (init->display.flag.is_set(init_display_flags::TEXT))
        {
            auto & out = Core::getInstance().getConsole();
            out << COLOR_LIGHTRED << "[df-ai] lockstep mode does not work with PRINT_MODE:TEXT. Disabling lockstep in the df-ai config.";
            out << COLOR_RESET << std::endl;
            config.set(out, config.lockstep, false);
            return;
        }

        if (strict_virtual_cast<df::viewscreen_movieplayerst>(Gui::getCurViewscreen(false)))
        {
            LOCKSTEP_DEBUG("not hooking while movie player is present");
            return;
        }

        lockstep_hooked = true;

#ifdef _WIN32
        lockstep_tick_count = GetTickCount();
        LOCKSTEP_DEBUG("initial lockstep_tick_count is " << lockstep_tick_count);
        Add_Hook((void *)GetTickCount, Real_GetTickCount, (void *)Fake_GetTickCount);
#else
        struct timeval tv;
        gettimeofday(&tv, nullptr);
        lockstep_tick_count = tv.tv_sec * 1000 + tv.tv_usec / 1000;
        LOCKSTEP_DEBUG("initial lockstep_tick_count is " << lockstep_tick_count);
        Add_Hook((void *)gettimeofday, Real_gettimeofday, (void *)Fake_gettimeofday);
#endif
        LOCKSTEP_DEBUG("hooked time");
        Add_Hook((void *)SDL_GetTicks, Real_SDL_GetTicks, (void *)Fake_SDL_GetTicks);
        LOCKSTEP_DEBUG("hooked ticks");
        enabler->outstanding_gframes = 0;
        enabler->outstanding_frames = 0;

        lockstep_renderer = new df_ai_renderer(enabler->renderer);
        enabler->renderer = lockstep_renderer;

        CoreSuspendReleaseMain releaser;

        SDL_SemWait(enabler->async_zoom.sem);
        enabler->async_zoom.queue.push_back(zoom_commands::zoom_reset);
        SDL_SemPost(enabler->async_zoom.sem);
        SDL_SemPost(enabler->async_zoom.sem_fill);

        while (lockstep_hooked && !lockstep_want_shutdown)
        {
            while (SDL_SemTryWait(enabler->async_tobox.sem_fill) == 0)
            {
                SDL_SemWait(enabler->async_tobox.sem);
                auto msg = enabler->async_tobox.queue.front();
                enabler->async_tobox.queue.pop_front();
                switch (msg.cmd)
                {
                case df::enabler::T_async_tobox::T_queue::pause:
                case df::enabler::T_async_tobox::T_queue::render:
                {
                    df::enabler::T_async_frombox::T_queue complete;
                    complete.msg = df::enabler::T_async_frombox::T_queue::complete;
                    SDL_SemWait(enabler->async_frombox.sem);
                    enabler->async_frombox.queue.push_back(complete);
                    SDL_SemPost(enabler->async_frombox.sem);
                    SDL_SemPost(enabler->async_frombox.sem_fill);
                    break;
                }
                case df::enabler::T_async_tobox::T_queue::start:
                case df::enabler::T_async_tobox::T_queue::inc:
                case df::enabler::T_async_tobox::T_queue::set_fps:
                    break;
                }
                SDL_SemPost(enabler->async_tobox.sem);
            }

            tthread::this_thread::sleep_for(tthread::chrono::seconds(1));
        }
    }
}
Beispiel #26
0
def_dll int sdl_semaphore::try_wait()
{
	return SDL_SemTryWait(_semaphore);
}
Beispiel #27
0
// render stuff
void display_update() {
	int gx, gy;
	char buffer[20];
	char time_buffer[8];
	Particle *current_particle = NULL;
	ParticleCollection *current_collection = NULL;
	SDL_Color grid_color;

	// TODO: make grid color settable
	grid_color.r = 255;
	grid_color.g = 255;
	grid_color.b = 255;

	graphics_clear();

  // draw texture for the grid
	if (grid) {
		graphics_drawGrid(20, 0, GRID_BLOCK_SIZE, GRID_WIDTH, GRID_HEIGHT, &grid_color);	
	}

  // draw grid
  if (grid && block_texture) {
		for (gy = 0; gy < GRID_HEIGHT; gy++) { // TODO: cater for realtime grid width/height settings
			for (gx = 0; gx < GRID_WIDTH; gx++) {
				// red
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 1) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, red_block_texture);
				}
				// green
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 2) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, green_block_texture);
				}
				// blue
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 3) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, blue_block_texture);
				}
				// orange
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 4) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, orange_block_texture);
				}
				// yellow
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 5) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, yellow_block_texture);
				}
				// cyan
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 6) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, cyan_block_texture);
				}
				// purple
				if (*(grid->data + gx + (gy * GRID_WIDTH)) == 7) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx),
          0 + (GRID_BLOCK_SIZE * gy), GRID_BLOCK_SIZE,
          GRID_BLOCK_SIZE, purple_block_texture);
				}
			}
		}
  }

  // draw tetromino
  if (block_texture && current_tetromino) {
    for (gy = 0; gy < 4; gy++) { // TODO: cater for realtime grid width/height settings
			for (gx = 0; gx < 4; gx++) {
			  // red
				if (*(current_tetromino->data+gx+(4*gy)) == 1) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, red_block_texture);
				}
				// green
				if (*(current_tetromino->data+gx+(4*gy)) == 2) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, green_block_texture);
				}
				// blue
				if (*(current_tetromino->data+gx+(4*gy)) == 3) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, blue_block_texture);
				}
				// orange
				if (*(current_tetromino->data+gx+(4*gy)) == 4) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, orange_block_texture);
				}
				// yellow
				if (*(current_tetromino->data+gx+(4*gy)) == 5) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, yellow_block_texture);
				}
				// cyan
				if (*(current_tetromino->data+gx+(4*gy)) == 6) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, cyan_block_texture);
				}
				// purple
				if (*(current_tetromino->data+gx+(4*gy)) == 7) {
					graphics_drawTextureScaled(20 + (GRID_BLOCK_SIZE * gx) +
          (GRID_BLOCK_SIZE * current_tetromino->x),
            0 + (GRID_BLOCK_SIZE * gy) + (GRID_BLOCK_SIZE *
            current_tetromino->y), GRID_BLOCK_SIZE, GRID_BLOCK_SIZE, purple_block_texture);
				}
			}
		}
  } 

  // draw text
  font_print(280, 35, "SCORE", NULL);
	sprintf(buffer, "%d", game.score);
  font_print(280, 55, buffer, NULL);
  font_print(280, 75, "TIME", NULL);
  game_getTime(time_buffer);
  font_print(280, 95, time_buffer, NULL);
  font_print(280, 115, "LEVEL", NULL);
	sprintf(buffer, "%d", game.level);
  font_print(280, 135, buffer, NULL);
  font_print(280, 155, "LINES", NULL);
	sprintf(buffer, "%d", game.lines);
  font_print(280, 175, buffer, NULL); 

  // render any particles if they're not currently being modified
	if (SDL_SemTryWait(sem) == 0) {
		current_collection = particle_getActiveCollections();
		if (current_collection) {
 	  	while (current_collection) {
      	current_particle = current_collection->first;
	
      	while (current_particle) {
      		glColor4f(1.0f, 1.0f, 1.0f, current_particle->alpha);
    	    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  	      glEnable(GL_BLEND);
	
  	      graphics_drawTexture(current_particle->x, current_particle->y, current_particle->texture);
	        glDisable(GL_BLEND);

        	current_particle = current_particle->next;
      	}

      	current_collection = current_collection->next;
    	}
  	}
		SDL_SemPost(sem);
	}

  // draw the menu if its needed
	if (ui_isMenuVisible()) {
		if (grid && current_tetromino) {
			ui_drawMainMenu(MENU_IN_GAME);
		}
		else {
			ui_drawMainMenu(MENU_MAIN);
		}
	}

	SDL_GL_SwapBuffers();
}
Beispiel #28
0
		int SemTryWait(Sem *sem)
		{
			return SDL_SemTryWait(sem);
		}
Beispiel #29
0
	bool Semaphore::tryWait()
	{
		return SDL_SemTryWait(semaphore) ? false : true;
	}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
	int retval;
#ifdef HAVE_SEM_TIMEDWAIT
	struct timeval now;
	struct timespec ts_timeout;
#else
	Uint32 end;
#endif

	if ( ! sem ) {
		SDL_SetError("Passed a NULL semaphore");
		return -1;
	}

	/* Try the easy cases first */
	if ( timeout == 0 ) {
		return SDL_SemTryWait(sem);
	}
	if ( timeout == SDL_MUTEX_MAXWAIT ) {
		return SDL_SemWait(sem);
	}

#ifdef HAVE_SEM_TIMEDWAIT
	/* Setup the timeout. sem_timedwait doesn't wait for
	 * a lapse of time, but until we reach a certain time.
	 * This time is now plus the timeout.
	 */
	gettimeofday(&now, NULL);

	/* Add our timeout to current time */
	now.tv_usec += (timeout % 1000) * 1000;
	now.tv_sec += timeout / 1000;

	/* Wrap the second if needed */
	if ( now.tv_usec >= 1000000 ) {
		now.tv_usec -= 1000000;
		now.tv_sec ++;
	}

	/* Convert to timespec */
	ts_timeout.tv_sec = now.tv_sec;
	ts_timeout.tv_nsec = now.tv_usec * 1000;

	/* Wait. */
	do
		retval = sem_timedwait(&sem->sem, &ts_timeout);
	while (retval == -1 && errno == EINTR);

	if (retval == -1)
		SDL_SetError(strerror(errno));
#else
	end = SDL_GetTicks() + timeout;
	while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
		if ((SDL_GetTicks() - end) >= 0) {
			break;
		}
		SDL_Delay(0);
	}
#endif /* HAVE_SEM_TIMEDWAIT */

	return retval;
}