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; }
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 } }
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; }
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; }
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 }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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(); }
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; }
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; }
/** * @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; }
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)); } } }
def_dll int sdl_semaphore::try_wait() { return SDL_SemTryWait(_semaphore); }
// 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(); }
int SemTryWait(Sem *sem) { return SDL_SemTryWait(sem); }
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; }