LockID Thread_Manager::EnterLock(int mutexID) { #ifndef _WIN32 ThreadID Cur = glfwGetThreadID(); mutexNumLocks[Cur][mutexID]++; if(mutexNumLocks[Cur][mutexID] == 1) { glfwLockMutex(mutexLocks[mutexID]); } #else glfwLockMutex(mutexLocks[mutexID]); #endif return mutexID; }
void lock_mutex(kiss_mutex m) { if(!kiss_init()) return; glfwLockMutex(m); }
void GLFWCALL PhysicsThreadFun( void *arg ) { while( running ) { // Lock mutex glfwLockMutex( thread_sync.particles_lock ); // Wait for particle drawing to be done while( running && thread_sync.p_frame > thread_sync.d_frame ) { glfwWaitCond( thread_sync.d_done, thread_sync.particles_lock, 0.1 ); } // No longer running? if( !running ) { break; } // Update particles ParticleEngine( thread_sync.t, thread_sync.dt ); // Update frame counter thread_sync.p_frame ++; // Unlock mutex and signal drawing thread glfwUnlockMutex( thread_sync.particles_lock ); glfwSignalCond( thread_sync.p_done ); } }
/* Audio_Thread::play: start playing */ void Audio_Thread::play(const char *alias, const char *file) { /* check */ if(isRunning() == false) return; if(MMDAgent_strlen(alias) <= 0 || MMDAgent_strlen(file) <= 0) return; /* wait buffer mutex */ glfwLockMutex(m_mutex); /* save character name, speaking style, and text */ if(m_alias) free(m_alias); if(m_file) free(m_file); m_alias = MMDAgent_strdup(alias); m_file = MMDAgent_strdup(file); m_count++; /* start playing thread */ if(m_count <= 1) glfwSignalCond(m_cond); /* release buffer mutex */ glfwUnlockMutex(m_mutex); }
/* Message::dequeueLogString: dequeue log string */ bool Message::dequeueLogString(char *log) { bool result; glfwLockMutex(m_logStringMutex); result = MessageQueue_dequeue(&m_logStringQueue, log, NULL); glfwUnlockMutex(m_logStringMutex); return result; }
/* Message::dequeueMessage: dequeue message */ bool Message::dequeueMessage(char *type, char *value) { bool result; glfwLockMutex(m_messageMutex); result = MessageQueue_dequeue(&m_messageQueue, type, value); glfwUnlockMutex(m_messageMutex); return result; }
/* Message::dequeueCommand: dequeue command message */ bool Message::dequeueCommand(char *type, char *value) { bool result; glfwLockMutex(m_mutexCommand); result = MessageQueue_dequeue(&m_queueCommand, type, value); glfwUnlockMutex(m_mutexCommand); return result; }
/* Message::dequeueLog: dequeue log message */ bool Message::dequeueLog(char *log) { bool result; glfwLockMutex(m_mutexLog); result = MessageQueue_dequeue(&m_queueLog, log, NULL); glfwUnlockMutex(m_mutexLog); return result; }
/* Message::dequeueEvent: dequeue event message */ bool Message::dequeueEvent(char *type, char *value) { bool result; glfwLockMutex(m_mutexEvent); result = MessageQueue_dequeue(&m_queueEvent, type, value); glfwUnlockMutex(m_mutexEvent); return result; }
/* Audio_Manager::run: main loop */ void Audio_Manager::run() { int i; Audio_Link *link; char *buff, *save; char *alias, *file; /* create initial threads */ for(i = 0; i < AUDIOMANAGER_INITIALNTHREAD; i++) { link = new Audio_Link; link->audio_thread.setupAndStart(m_mmdagent); link->next = m_list; m_list = link; } while(m_kill == false) { /* wait playing event */ glfwLockMutex(m_mutex); while(m_count <= 0) { glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY); if(m_kill == true) return; } Audio_EventQueue_dequeue(&m_bufferQueue, &buff); m_count--; glfwUnlockMutex(m_mutex); if(buff != NULL) { alias = MMDAgent_strtok(buff, "|", &save); file = MMDAgent_strtok(NULL, "|", &save); if(alias != NULL && file != NULL) { /* check alias */ for(i = 0, link = m_list; link; link = link->next, i++) if(link->audio_thread.checkAlias(alias)) break; if(link) { link->audio_thread.stop(); /* if the same alias is playing, stop immediately */ } else { for(i = 0, link = m_list; link; link = link->next, i++) if(link->audio_thread.isRunning() && link->audio_thread.isPlaying() == false) break; if(link == NULL) { link = new Audio_Link; link->audio_thread.setupAndStart(m_mmdagent); link->next = m_list; m_list = link; } } /* set */ link->audio_thread.play(alias, file); } free(buff); /* free buffer */ } } }
Command_st PlayerInputListener::GetNextCommand() { Command_st oCommand; glfwLockMutex(m_oInputMutex); // Set the inputs oCommand.cMoveDirection = GetMoveDirection(); oCommand.bStealth = GetStealth(); oCommand.fZ = m_oPlayer.GetZ() + static_cast<float>(m_dRotationAxis); // Get the most up-to-date player Z value glfwUnlockMutex(m_oInputMutex); return oCommand; }
void PlayerInputListener::Reset() { glfwLockMutex(m_oInputMutex); m_dForwardAxis = 0; m_dStrafeAxis = 0; m_dRotationAxis = 0; m_dStealthHalfAxis = 0; m_WeaponChangeTEST = -1; glfwUnlockMutex(m_oInputMutex); }
/* Audio_Thread::run: main thread loop for audio */ void Audio_Thread::run() { Audio audio; char *alias, *file; bool lipsync; while (m_kill == false) { /* wait event */ glfwLockMutex(m_mutex); while(m_count <= 0) { glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY); if(m_kill == true) return; } alias = MMDAgent_strdup(m_alias); file = MMDAgent_strdup(m_file); m_count--; glfwUnlockMutex(m_mutex); m_playing = true; /* open and start audio */ Audio_initialize(&audio); if(Audio_openAndStart(&audio, alias, file) == true) { lipsync = startLipsync(file); /* send SOUND_EVENT_START */ m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTART, "%s", alias); /* wait to stop audio */ Audio_waitToStop(&audio, alias, &m_playing); if(lipsync) stopLipsync(); /* send SOUND_EVENT_STOP */ m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTOP, "%s", alias); /* close audio file */ Audio_close(&audio, alias); } if(alias) free(alias); if(file) free(file); Audio_clear(&audio); m_playing = false; } }
/* checkAlias: check playing alias */ bool Audio_Thread::checkAlias(const char *alias) { bool ret; /* check */ if(isRunning() == false) return false; /* wait buffer mutex */ glfwLockMutex(m_mutex); /* check audio alias */ ret = MMDAgent_strequal(m_alias, alias); /* release buffer mutex */ glfwUnlockMutex(m_mutex); return ret; }
/* checkAlias: check playing alias */ bool Audio_Thread::checkAlias(const char *alias) { bool ret; /* check */ if(isRunning() == false) return false; /* wait buffer mutex */ glfwLockMutex(m_mutex); /* save character name, speaking style, and text */ ret = MMDAgent_strequal(m_alias, alias); /* release buffer mutex */ glfwUnlockMutex(m_mutex); return ret; }
/* Open_JTalk_Manager::synthesis: start synthesis */ void Open_JTalk_Manager::synthesis(const char *str) { /* check */ if(isRunning() == false || MMDAgent_strlen(str) <= 0) return; /* wait buffer mutex */ glfwLockMutex(m_mutex); /* enqueue character name, speaking style, and text */ Open_JTalk_EventQueue_enqueue(&m_bufferQueue, str); m_count++; /* start synthesis event */ if(m_count <= 1) glfwSignalCond(m_cond); /* release buffer mutex */ glfwUnlockMutex(m_mutex); }
WpnCommand_st PlayerInputListener::GetNextWpnCommand() { WpnCommand_st oWpnCommand; glfwLockMutex(m_oInputMutex); if (-1 != m_WeaponChangeTEST) oWpnCommand.nAction = WeaponSystem::CHANGE_WEAPON; else if (m_bWeaponReloadTEST) oWpnCommand.nAction = WeaponSystem::RELOAD; else if (m_bWeaponFireTEST) oWpnCommand.nAction = WeaponSystem::FIRE; else oWpnCommand.nAction = WeaponSystem::IDLE; /*oWpnCommand.fGameTime = static_cast<float>(g_pGameSession->MainTimer().GetGameTime() - (WeaponSystem::FIRE == oWpnCommand.nAction ? 15 : 0)); if (oWpnCommand.fGameTime < 0) oWpnCommand.fGameTime += 256;//TEST if (oWpnCommand.fGameTime >= 256) oWpnCommand.fGameTime -= 256;//TEST*/ oWpnCommand.dTime = g_pGameSession->MainTimer().GetTime() - (/*WeaponSystem::FIRE == oWpnCommand.nAction*/false ? 1 : 0); if (WeaponSystem::FIRE == oWpnCommand.nAction) oWpnCommand.Parameter.fZ = m_oPlayer.GetZ() + static_cast<float>(m_dRotationAxis); // Get the most up-to-date player Z value else if (WeaponSystem::CHANGE_WEAPON == oWpnCommand.nAction) oWpnCommand.Parameter.WeaponNumber = static_cast<uint8>(m_WeaponChangeTEST); //m_WeaponChangeTEST = -1; glfwUnlockMutex(m_oInputMutex); return oWpnCommand; }
/* Audio_Manager::play: start playing */ void Audio_Manager::play(const char *str) { /* check */ if(isRunning() == false) return; if(MMDAgent_strlen(str) <= 0) return; /* wait buffer mutex */ glfwLockMutex(m_mutex); /* enqueue alias and file name */ Audio_EventQueue_enqueue(&m_bufferQueue, str); m_count++; /* start playing event */ if(m_count <= 1) glfwSignalCond(m_cond); /* release buffer mutex */ glfwUnlockMutex(m_mutex); }
void debugTestThreading() { logWrite("Testing thread creation and access to log file (and mutex locks)"); ThreadID Thread1 = Thread.Create(debugThread_Loop,(void*)0); ThreadID Thread2 = Thread.Create(debugThread_Loop,(void*)1); Thread.WaitForThread(Thread1); Thread.WaitForThread(Thread2); logWrite("Threads completed, killing remains..."); Thread.Kill(Thread1); Thread.Kill(Thread2); ThreadID randomThread[TEST_MAX_THREAD_NUMBER]; logWrite("Creating and destroying %d random threads...",TEST_MAX_THREAD_NUMBER); for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) { randomThread[i] = Thread.Create(debugThread_InfLoop,(void*)i); } logWrite("Waiting..."); Thread.Sleep(3.0f); logWrite("Killing threads..."); for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) { Thread.Kill(randomThread[i]); } logWrite("Waiting for remaining threads..."); for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) { Thread.WaitForThread(randomThread[i]); } logWrite("Found %d processors/cores",glfwGetNumberOfProcessors()); logWrite("Creating mutex..."); GLFWmutex mutex = glfwCreateMutex(); logWrite("Mutex object pointer: 0x%.8X. Trying to lock and unlock",mutex); glfwLockMutex(mutex); glfwUnlockMutex(mutex); logWrite("Thread test passed!\n"); }
vec2_t InputSystem::MousePosition() { glfwLockMutex(lock); vec2_t result = mousePosition; glfwUnlockMutex(lock); return result; }
void InputSystem::Update() { glfwLockMutex(lock); wantsQuit = (glfwGetKey('Q') == GLFW_PRESS); seconds = glfwGetTime(); glfwUnlockMutex(lock); }
static void OnMouseMoved(int x, int y) { glfwLockMutex(lock); mousePosition = Vec2(x, y); glfwUnlockMutex(lock); }
/* Open_JTalk_Manager::run: main loop */ void Open_JTalk_Manager::run() { int i; Open_JTalk_Link *link; char *buff, *save; char *chara, *style, *text; bool ret = true; /* create initial threads */ for(i = 0; i < OPENJTALKMANAGER_INITIALNTHREAD; i++) { link = new Open_JTalk_Link; if(link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config) == false) ret = false; link->next = m_list; m_list = link; } if(ret == false) return; while(m_kill == false) { glfwLockMutex(m_mutex); while(m_count <= 0) { glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY); if(m_kill == true) return; } Open_JTalk_EventQueue_dequeue(&m_bufferQueue, &buff); m_count--; glfwUnlockMutex(m_mutex); if(buff != NULL) { chara = MMDAgent_strtok(buff, "|", &save); style = MMDAgent_strtok(NULL, "|", &save); text = MMDAgent_strtok(NULL, "|", &save); if(chara != NULL && style != NULL && text != NULL) { /* check character */ for(i = 0, link = m_list; link; link = link->next, i++) if(link->open_jtalk_thread.checkCharacter(chara) == true) break; if(link) { if(link->open_jtalk_thread.isSpeaking() == true) link->open_jtalk_thread.stop(); /* if the same character is speaking, stop immediately */ } else { for(i = 0, link = m_list; link; link = link->next, i++) if(link->open_jtalk_thread.isRunning() == true && link->open_jtalk_thread.isSpeaking() == false) break; if(link == NULL) { link = new Open_JTalk_Link; link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config); link->next = m_list; m_list = link; } } /* set */ link->open_jtalk_thread.synthesis(chara, style, text); } free(buff); /* free buffer */ } } }
void DrawParticles( double t, float dt ) { int i, particle_count; VERTEX vertex_array[ BATCH_PARTICLES * PARTICLE_VERTS ], *vptr; float alpha; GLuint rgba; VEC quad_lower_left, quad_lower_right; GLfloat mat[ 16 ]; PARTICLE *pptr; // Here comes the real trick with flat single primitive objects (s.c. // "billboards"): We must rotate the textured primitive so that it // always faces the viewer (is coplanar with the view-plane). // We: // 1) Create the primitive around origo (0,0,0) // 2) Rotate it so that it is coplanar with the view plane // 3) Translate it according to the particle position // Note that 1) and 2) is the same for all particles (done only once). // Get modelview matrix. We will only use the upper left 3x3 part of // the matrix, which represents the rotation. glGetFloatv( GL_MODELVIEW_MATRIX, mat ); // 1) & 2) We do it in one swift step: // Although not obvious, the following six lines represent two matrix/ // vector multiplications. The matrix is the inverse 3x3 rotation // matrix (i.e. the transpose of the same matrix), and the two vectors // represent the lower left corner of the quad, PARTICLE_SIZE/2 * // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0). // The upper left/right corners of the quad is always the negative of // the opposite corners (regardless of rotation). quad_lower_left.x = (-PARTICLE_SIZE/2) * (mat[0] + mat[1]); quad_lower_left.y = (-PARTICLE_SIZE/2) * (mat[4] + mat[5]); quad_lower_left.z = (-PARTICLE_SIZE/2) * (mat[8] + mat[9]); quad_lower_right.x = (PARTICLE_SIZE/2) * (mat[0] - mat[1]); quad_lower_right.y = (PARTICLE_SIZE/2) * (mat[4] - mat[5]); quad_lower_right.z = (PARTICLE_SIZE/2) * (mat[8] - mat[9]); // Don't update z-buffer, since all particles are transparent! glDepthMask( GL_FALSE ); // Enable blending glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE ); // Select particle texture if( !wireframe ) { glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, particle_tex_id ); } // Set up vertex arrays. We use interleaved arrays, which is easier to // handle (in most situations) and it gives a linear memeory access // access pattern (which may give better performance in some // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, // 4 ubytes for color and 3 floats for vertex coord (in that order). // Most OpenGL cards / drivers are optimized for this format. glInterleavedArrays( GL_T2F_C4UB_V3F, 0, vertex_array ); // Is particle physics carried out in a separate thread? if( multithreading ) { // Wait for particle physics thread to be done glfwLockMutex( thread_sync.particles_lock ); while( running && thread_sync.p_frame <= thread_sync.d_frame ) { glfwWaitCond( thread_sync.p_done, thread_sync.particles_lock, 0.1 ); } // Store the frame time and delta time for the physics thread thread_sync.t = t; thread_sync.dt = dt; // Update frame counter thread_sync.d_frame ++; } else { // Perform particle physics in this thread ParticleEngine( t, dt ); } // Loop through all particles and build vertex arrays. particle_count = 0; vptr = vertex_array; pptr = particles; for( i = 0; i < MAX_PARTICLES; i ++ ) { if( pptr->active ) { // Calculate particle intensity (we set it to max during 75% // of its life, then it fades out) alpha = 4.0f * pptr->life; if( alpha > 1.0f ) { alpha = 1.0f; } // Convert color from float to 8-bit (store it in a 32-bit // integer using endian independent type casting) ((GLubyte *)&rgba)[0] = (GLubyte)(pptr->r * 255.0f); ((GLubyte *)&rgba)[1] = (GLubyte)(pptr->g * 255.0f); ((GLubyte *)&rgba)[2] = (GLubyte)(pptr->b * 255.0f); ((GLubyte *)&rgba)[3] = (GLubyte)(alpha * 255.0f); // 3) Translate the quad to the correct position in modelview // space and store its parameters in vertex arrays (we also // store texture coord and color information for each vertex). // Lower left corner vptr->s = 0.0f; vptr->t = 0.0f; vptr->rgba = rgba; vptr->x = pptr->x + quad_lower_left.x; vptr->y = pptr->y + quad_lower_left.y; vptr->z = pptr->z + quad_lower_left.z; vptr ++; // Lower right corner vptr->s = 1.0f; vptr->t = 0.0f; vptr->rgba = rgba; vptr->x = pptr->x + quad_lower_right.x; vptr->y = pptr->y + quad_lower_right.y; vptr->z = pptr->z + quad_lower_right.z; vptr ++; // Upper right corner vptr->s = 1.0f; vptr->t = 1.0f; vptr->rgba = rgba; vptr->x = pptr->x - quad_lower_left.x; vptr->y = pptr->y - quad_lower_left.y; vptr->z = pptr->z - quad_lower_left.z; vptr ++; // Upper left corner vptr->s = 0.0f; vptr->t = 1.0f; vptr->rgba = rgba; vptr->x = pptr->x - quad_lower_right.x; vptr->y = pptr->y - quad_lower_right.y; vptr->z = pptr->z - quad_lower_right.z; vptr ++; // Increase count of drawable particles particle_count ++; } // If we have filled up one batch of particles, draw it as a set // of quads using glDrawArrays. if( particle_count >= BATCH_PARTICLES ) { // The first argument tells which primitive type we use (QUAD) // The second argument tells the index of the first vertex (0) // The last argument is the vertex count glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count ); particle_count = 0; vptr = vertex_array; } // Next particle pptr ++; } // We are done with the particle data: Unlock mutex and signal physics // thread if( multithreading ) { glfwUnlockMutex( thread_sync.particles_lock ); glfwSignalCond( thread_sync.d_done ); } // Draw final batch of particles (if any) glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count ); // Disable vertex arrays (Note: glInterleavedArrays implicitly called // glEnableClientState for vertex, texture coord and color arrays) glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); // Disable texturing and blending glDisable( GL_TEXTURE_2D ); glDisable( GL_BLEND ); // Allow Z-buffer updates again glDepthMask( GL_TRUE ); }
void kiss_lock() { glfwLockMutex(kiss_g_glfw_mutex); }
/* Message::enqueueMessage: enqueue message */ void Message::enqueueMessage(const char *type, const char *value) { glfwLockMutex(m_messageMutex); MessageQueue_enqueue(&m_messageQueue, type, value); glfwUnlockMutex(m_messageMutex); }
/* Message::enqueueLogString: enqueue log string */ void Message::enqueueLogString(const char *log) { glfwLockMutex(m_logStringMutex); MessageQueue_enqueue(&m_logStringQueue, log, NULL); glfwUnlockMutex(m_logStringMutex); }
double InputSystem::Time() { glfwLockMutex(lock); double result = seconds; glfwUnlockMutex(lock); return seconds; }
bool InputSystem::Quit() { glfwLockMutex(lock); bool result = wantsQuit; glfwUnlockMutex(lock); return result; }
/* Message::enqueueLog: enqueue log message */ void Message::enqueueLog(const char *log) { glfwLockMutex(m_mutexLog); MessageQueue_enqueue(&m_queueLog, log, NULL); glfwUnlockMutex(m_mutexLog); }