bool OpenALMusicPlayer::streamBuffer(ALuint buffer) { char pcm[BUFFERSIZE]; int size = 0; const char* error = '\0'; if (!stream->read(pcm, BUFFERSIZE, &size, error)) { GfError("OpenALMusicPlayer: Stream read error: %s\n", error); return false; } else { int format; switch (stream->getSoundFormat()) { case SoundStream::FORMAT_MONO16: format = AL_FORMAT_MONO16; break; case SoundStream::FORMAT_STEREO16: format = AL_FORMAT_STEREO16; break; default: GfError("OpenALMusicPlayer: Format error: \n"); return false; } alBufferData(buffer, format, pcm, size, stream->getRateInHz()); return check(); } }
static tPSCommand* parseFormulaStringIntern( char **string ) { parseSkipWhitespace( string ); char ret = TRUE; tPSCommand *result = NULL; tPSCommand *current = NULL; while( ret ) { if( (*string)[0] == '{' ) { ret = parseSubCommands( string, ¤t ); } else if( (*string)[0] >= '0' && (*string)[0] <= '9' ) { ret = parseNumber( string, ¤t ); } else if( ( (*string)[0] >= 'a' && (*string)[0] <= 'z' ) || ( (*string)[0] >= 'A' && (*string)[0] <= 'Z' ) ) { ret = parseCommandVar( string, ¤t ); } else if( (*string)[0] == '\0' || (*string)[0] == '}' ) { return result; } else if( (*string)[0] == '%' ) { parseSkipComment( string ); } else { GfError( "Invalid token found: %c.", (*string)[0] ); ret = FALSE; } if( current && !result ) result = current; parseSkipWhitespace( string ); } return result; }
bool OpenALMusicPlayer::playAndManageBuffer() { if (!ready) { return false; } int processed; bool active = true; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); while(processed--) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); check(); active = streamBuffer(buffer); alSourceQueueBuffers(source, 1, &buffer); check(); } if (!active && !isPlaying()) { // Try to reanimate playback if(!startPlayback()) { GfError("OpenALMusicPlayer: Cannot play stream.\n"); } } return true; }
bool OpenALMusicPlayer::initContext() { device = alcOpenDevice(NULL); if( device == NULL ) { GfError("OpenALMusicPlayer: OpenAL could not open device\n"); return false; } context = alcCreateContext(device, NULL); if(context == NULL) { alcCloseDevice(device); GfError("OpenALMusicPlayer: OpenAL could not create contect for device\n"); return false; } alcMakeContextCurrent(context); alcGetError(device); return check(); }
bool OpenALMusicPlayer::check() { int error = alGetError(); if(error != AL_NO_ERROR) { GfError("OpenALMusicPlayer: OpenAL error was raised: %d\n", error); return false; } return true; }
static void simplifyToParse( tFormNode **node ) { tFormNode *curNode = *node; tFormNode *prevNode = NULL; char skipChilds; char againThisNode; while( curNode ) { skipChilds = FALSE; againThisNode = FALSE; if( curNode->type == FORMNODE_TYPE_TOPARSE_BLOCK ) { if( curNode->firstChild == NULL ) { prevNode->next = curNode->next; FREEZ( curNode->string ); free( curNode ); curNode = prevNode; skipChilds = TRUE; } else { if( curNode->firstChild->next == NULL ) { if( prevNode ) { prevNode->next = curNode->firstChild; prevNode->next->next = curNode->next; FREEZ( curNode->string ); free( curNode ); curNode = prevNode->next; } else { *node = curNode->firstChild; (*node)->next = curNode->next; FREEZ( curNode->string ); free( curNode ); curNode = *node; } againThisNode = TRUE; } else { GfError( "WARNING: could not simplify all blocks in a formula\n" ); } } } else if( curNode->type == FORMNODE_TYPE_TOPARSE_STRING ) { /* Unparsed string found: assume variable */ curNode->type = FORMNODE_TYPE_VARIABLE; } if( !skipChilds && curNode->firstChild ) simplifyToParse( &(curNode->firstChild) ); if( !againThisNode ) { prevNode = curNode; curNode = curNode->next; } } }
void OpenALMusicPlayer::start() { if (!ready) { if (stream->getSoundFormat() == SoundStream::FORMAT_INVALID) { GfError("OpenALMusicPlayer: Sound stream has invalid format\n"); return; } if (initContext() && initBuffers() && initSource()) { ready = true; startPlayback(); } return; } }
bool OpenALMusicPlayer::initSource() { alGenSources(1, &source); if (!check()) { GfError("OpenALMusicPlayer: initSource failed to get sound source.\n"); return false; }; alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0); alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef (source, AL_ROLLOFF_FACTOR, 0.0 ); alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE ); return true; }
void GfFormFreeCommand( void *commands ) { tPSCommand *next; tPSCommand *current = (tPSCommand*)commands; while( current ) { if( current->data ) { if( current->func == &cmdPushVar ) free( current->data ); else if( current->func == &cmdPushNumber ) free( current->data ); else if( current->func == &cmdPushCommand ) GfFormFreeCommand( (tPSCommand*)current->data ); else GfError( "WARNING: Data found, but no clue about it's contents\n" ); } next = current->next; free( current ); current = next; } }
// Create the left walls, start must point to a segment with a wall on the left and a leading // non wall segment. // FIXME: Does not work for a closed ring "by design". void buildWalls(tTrackSeg *start, int side) { if (start == NULL) { return; } tTrackSeg *current = start; bool close = false; // Going down the wall. do { tTrackSeg* s = current->side[side]; tTrackSeg* p = current->prev->side[side]; tTrackSeg* n = current->next->side[side]; // Current segment is a wall? if (s != NULL && s->style == TR_WALL && s->side[side] != NULL) { float h = s->height; t3Dd svl = s->vertex[TR_SL]; t3Dd svr = s->vertex[TR_SR]; t3Dd evl = s->vertex[TR_EL]; t3Dd evr = s->vertex[TR_ER]; static float weps = 0.01f; // Close the start with a ploygon? if (p == NULL || p->style != TR_WALL || (fabs(p->vertex[TR_EL].x - svl.x) > weps) || (fabs(p->vertex[TR_ER].x - svr.x) > weps) || (fabs(h - p->height) > weps) || fixedid == 0) { // Enough space in array? if (fixedid >= sizeof(fixedobjects)/sizeof(fixedobjects[0])) { GfError("fixedobjects full in %s, line %d\n", __FILE__, __LINE__); return; } if (close == true) { dtEndComplexShape(); GfError("Shape not closed %s, line %d\n", __FILE__, __LINE__); } // Start new shape. fixedobjects[fixedid] = dtNewComplexShape(); fixedid++; close = true; dtBegin(DT_POLYGON); dtVertex(svl.x, svl.y, svl.z); dtVertex(svr.x, svr.y, svr.z); dtVertex(svr.x, svr.y, svr.z + h); dtVertex(svl.x, svl.y, svl.z + h); dtEnd(); } // Build sides, left, top, right. Depending on how we want to use it we // can remove top perhaps. // TODO: do we want the top poly? if (close == true) { // Left. dtBegin(DT_POLYGON); dtVertex(svl.x, svl.y, svl.z); dtVertex(svl.x, svl.y, svl.z + h); dtVertex(evl.x, evl.y, evl.z + h); dtVertex(evl.x, evl.y, evl.z); dtEnd(); /* // Top. dtBegin(DT_POLYGON); dtVertex(svl.x, svl.y, svl.z + h); dtVertex(svr.x, svr.y, svr.z + h); dtVertex(evr.x, evr.y, evr.z + h); dtVertex(evl.x, evl.y, evl.z + h); dtEnd();*/ // Right. dtBegin(DT_POLYGON); dtVertex(svr.x, svr.y, svr.z + h); dtVertex(svr.x, svr.y, svr.z); dtVertex(evr.x, evr.y, evr.z); dtVertex(evr.x, evr.y, evr.z + h); dtEnd(); } else { GfError("Shape not open %s, line %d\n", __FILE__, __LINE__); } // Close the end with a ploygon? if (n == NULL || n->style != TR_WALL || (fabs(n->vertex[TR_SL].x - evl.x) > weps) || (fabs(n->vertex[TR_SR].x - evr.x) > weps) || (fabs(h - n->height) > weps)) { if (close == true) { dtBegin(DT_POLYGON); dtVertex(svl.x, svl.y, svl.z); dtVertex(svr.x, svr.y, svr.z); dtVertex(svr.x, svr.y, svr.z + h); dtVertex(svl.x, svl.y, svl.z + h); dtEnd(); dtEndComplexShape(); close = false; } else { GfError("Shape not open %s, line %d\n", __FILE__, __LINE__); } } } current = current->next; } while (current != start); }
void grInitSound(tSituation* s, int ncars) { const int BUFSIZE = 1024; char buf[BUFSIZE]; GfOut("-- grInitSound\n"); // Check if we want sound (sound.xml). const char *soundDisabledStr = GR_ATT_SOUND_STATE_DISABLED; const char *soundOpenALStr = GR_ATT_SOUND_STATE_OPENAL; const char *soundPlibStr = GR_ATT_SOUND_STATE_PLIB; snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GR_SOUND_PARM_CFG); void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); const char *optionName = GfParmGetStr(paramHandle, GR_SCT_SOUND, GR_ATT_SOUND_STATE, soundOpenALStr); float global_volume = GfParmGetNum(paramHandle, GR_SCT_SOUND, GR_ATT_SOUND_VOLUME, "%", 100.0f); if (!strcmp(optionName, soundDisabledStr)) { sound_mode = DISABLED; } else if (!strcmp(optionName, soundOpenALStr)) { sound_mode = OPENAL_MODE; } else if (!strcmp(optionName, soundPlibStr)) { sound_mode = PLIB_MODE; } //printf ("vol:%f\n", global_volume); GfParmReleaseHandle(paramHandle); paramHandle = NULL; lastUpdated = -1000.0; switch (sound_mode) { case OPENAL_MODE: try { sound_interface = new OpenalSoundInterface (44100, 32); } catch (const char* err) { GfError("Disabling Sound: OpenAL initialisation failed: %s\n", err ? err : ""); sound_mode = DISABLED; return; } break; case PLIB_MODE: sound_interface = new PlibSoundInterface(44100, 32); break; case DISABLED: return; default: GfOut (" -- Unknown sound mode %d\n", sound_mode); exit(-1); } sound_interface->setGlobalGain(global_volume/100.0f); car_sound_data = new CarSoundData* [ncars]; int i; for (i = 0; i<ncars; i++) { void* handle = s->cars[i]->_carHandle; tCarElt *car = s->cars[i]; const char* param; FILE *file = NULL; // ENGINE PARAMS tdble rpm_scale; param = GfParmGetStr(handle, "Sound", "engine sample", "engine-1.wav"); rpm_scale = GfParmGetNum(handle, "Sound", "rpm scale", NULL, 1.0); snprintf (buf, BUFSIZE, "cars/%s/%s", car->_carName, param); file = fopen(buf, "r"); if (!file) { snprintf (buf, BUFSIZE, "data/sound/%s", param); } else { fclose(file); } car_sound_data[car->index] = new CarSoundData (car->index, sound_interface); TorcsSound* engine_sound = sound_interface->addSample(buf, ACTIVE_VOLUME | ACTIVE_PITCH | ACTIVE_LP_FILTER, true, false); car_sound_data[i]->setEngineSound (engine_sound, rpm_scale); // TURBO PARAMS float default_turbo_rpm = 100.0f;//0.5f*car->_enginerpmMaxTq; bool turbo_on; param = GfParmGetStr(handle, SECT_ENGINE, PRM_TURBO, "false"); if (!strcmp(param, "true")) { turbo_on = true; } else { if (strcmp(param, "false")) { fprintf (stderr, "expected true or false, found %s\n", param); } turbo_on = false; } float turbo_rpm = GfParmGetNum(handle, SECT_ENGINE, PRM_TURBO_RPM, NULL, default_turbo_rpm); float turbo_lag = GfParmGetNum(handle, SECT_ENGINE, PRM_TURBO_LAG, NULL, 1.0f); car_sound_data[i]->setTurboParameters (turbo_on, turbo_rpm, turbo_lag); } sound_interface->setSkidSound("data/sound/skid_tyres.wav"); sound_interface->setRoadRideSound("data/sound/road-ride.wav"); sound_interface->setGrassRideSound("data/sound/out_of_road.wav"); sound_interface->setGrassSkidSound("data/sound/out_of_road-3.wav"); sound_interface->setMetalSkidSound("data/sound/skid_metal.wav"); sound_interface->setAxleSound("data/sound/axle.wav"); sound_interface->setTurboSound("data/sound/turbo1.wav"); sound_interface->setBackfireLoopSound("data/sound/backfire_loop.wav"); for (i = 0; i < NB_CRASH_SOUND; i++) { snprintf(buf, BUFSIZE, "data/sound/crash%d.wav", i+1); sound_interface->setCrashSound(buf, i); } sound_interface->setBangSound("data/sound/boom.wav"); sound_interface->setBottomCrashSound("data/sound/bottom_crash.wav"); sound_interface->setBackfireSound("data/sound/backfire.wav"); sound_interface->setGearChangeSound("data/sound/gear_change1.wav"); sound_interface->setNCars(ncars); soundInitialized = 1; // Must happen after all static non-shared have been allocated. sound_interface->initSharedSourcePool(); }
static void parseFormStringStep1( tFormNode **node, const char *string ) { tFormNode *newNode; tFormNode *prevNode = NULL; int type = 0; int startPos = -1; int currentPos = 0; int stringLength = strlen( string ); int xx; (*node) = NULL; while( currentPos < stringLength ) { if( startPos >= 0 ) { /* Check if block has ended */ if( type == FORMNODE_TYPE_STRING && string[ currentPos ] == '#' ) { /* String ended here */ newNode = (tFormNode*)malloc( sizeof( tFormNode ) ); newNode->firstChild = NULL; newNode->next = NULL; newNode->type = FORMNODE_TYPE_STRING; newNode->number = 0.0f; newNode->string = (char*)malloc( sizeof( char ) * ( currentPos - startPos + 1 ) ); newNode->func = NULL; for( xx = startPos; xx < currentPos; ++xx ) newNode->string[ xx - startPos ] = string[ xx ]; newNode->string[ currentPos - startPos ] = '\0'; if( *node ) prevNode->next = newNode; else (*node) = newNode; startPos = -1; prevNode = newNode; } else if( type == FORMNODE_TYPE_NUMBER && ( string[ currentPos ] < '0' || string[ currentPos ] > '9' ) && string[ currentPos ] != '.' ) { /* Number ended here */ newNode = (tFormNode*)malloc( sizeof( tFormNode ) ); newNode->firstChild = NULL; newNode->next = NULL; newNode->type = FORMNODE_TYPE_NUMBER; newNode->number = 0.0f; newNode->string = (char*)malloc( sizeof( char ) * ( currentPos - startPos + 1 ) ); newNode->func = NULL; for( xx = startPos; xx < currentPos; ++xx ) newNode->string[ xx - startPos ] = string[ xx ]; newNode->string[ currentPos - startPos ] = '\0'; newNode->number = (tdble)atof( newNode->string ); FREEZ( newNode->string ); if( *node ) prevNode->next = newNode; else (*node) = newNode; prevNode = newNode; startPos = -1; --currentPos; } else if( type == FORMNODE_TYPE_TOPARSE_STRING && ( string[ currentPos ] < 'a' || string[ currentPos ] > 'z' ) && ( string[ currentPos ] < 'A' || string[ currentPos ] > 'Z' ) && ( string[ currentPos ] != '_' ) ) { /* Toparse String ended here */ newNode = (tFormNode*)malloc( sizeof( tFormNode ) ); newNode->firstChild = NULL; newNode->next = NULL; newNode->type = FORMNODE_TYPE_TOPARSE_STRING; newNode->number = 0.0f; newNode->string = (char*)malloc( sizeof( char ) * ( currentPos - startPos + 1 ) ); newNode->func = NULL; for( xx = startPos; xx < currentPos; ++xx ) newNode->string[ xx - startPos ] = string[ xx ]; newNode->string[ currentPos - startPos ] = '\0'; if( *node ) prevNode->next = newNode; else (*node) = newNode; prevNode = newNode; startPos = -1; --currentPos; } } else { if( string[ currentPos ] == '#' ) { startPos = currentPos + 1; type = FORMNODE_TYPE_STRING; } else if( string[ currentPos ] >= '0' && string[ currentPos ] <= '9' ) { startPos = currentPos; type = FORMNODE_TYPE_NUMBER; } else if( ( string[ currentPos ] >= 'a' && string[ currentPos ] <= 'z' ) || ( string[ currentPos ] >= 'A' && string[ currentPos ] <= 'Z' ) ) { startPos = currentPos; type = FORMNODE_TYPE_TOPARSE_STRING; } else if( string[ currentPos ] == '(' || string[ currentPos ] == ')' || string[ currentPos ] == ',' || string[ currentPos ] == '+' || string[ currentPos ] == '-' || string[ currentPos ] == '*' || string[ currentPos ] == '/' || string[ currentPos ] == '\\' ) { /* Extra token */ newNode = (tFormNode*)malloc( sizeof( tFormNode ) ); newNode->firstChild = NULL; newNode->next = NULL; newNode->type = FORMNODE_TYPE_TOPARSE_STRING; newNode->number = 0.0f; newNode->string = (char*)malloc( sizeof( char ) * 3 ); newNode->func = NULL; if( ( string[ currentPos ] == '/' || string[ currentPos ] == '\\' ) && ( string[ currentPos + 1 ] == '/' || string[ currentPos + 1 ] == '\\' ) && string[ currentPos ] != string[ currentPos + 1 ] ) { newNode->string[ 0 ] = string[ currentPos ]; newNode->string[ 1 ] = string[ currentPos + 1 ]; newNode->string[ 2 ] = '\0'; ++currentPos; } else { newNode->string[ 0 ] = string[ currentPos ]; newNode->string[ 1 ] = '\0'; } if( *node ) prevNode->next = newNode; else (*node) = newNode; prevNode = newNode; } else if( string[ currentPos ] != ' ' && string[ currentPos ] != '\n' && string[ currentPos ] != '\r' ) { GfError( "Formula parser: invalid token: \'%c\'\n", string[ currentPos ] ); } } ++currentPos; } }
OpenalSound::OpenalSound(const char* filename, OpenalSoundInterface* sitf, int flags, bool loop, bool static_pool) : Sound(flags, loop) { this->static_pool = static_pool; poolindex = -1; itf = sitf; MAX_DISTANCE = 10000.0f; MAX_DISTANCE_LOW = 5.0f; REFERENCE_DISTANCE = 5.0f; ROLLOFF_FACTOR = 0.5f; int i; for (i = 0; i<3; i++) { source_position[i] = 0.0f; source_velocity[i] = 0.0f; zeroes[i] = 0.0f; } GfLogTrace("OpenAL : Creating %s source from %s\n", static_pool ? "static" : "dynamic", filename); int error = alGetError(); if (error != AL_NO_ERROR) { printf("Uncatched OpenAL Error on entry: %d with file %s\n", error, filename); } alGenBuffers (1, &buffer); error = alGetError(); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alGenBuffers failed %s\n", error, filename); is_enabled = false; return; } SDL_AudioSpec wavspec; Uint32 wavlen; Uint8 *wavbuf; if (!SDL_LoadWAV(filename, &wavspec, &wavbuf, &wavlen)) { if (alIsBuffer(buffer)) alDeleteBuffers(1, &buffer); GfError("OpenAL Error: Could not load %s (%s)\n", filename, SDL_GetError()); is_enabled = false; return; } if (wavspec.channels > 1) { if (alIsBuffer(buffer)) alDeleteBuffers(1, &buffer); GfError("OpenAL Error: Unsupported stereo sample %s\n", filename); is_enabled = false; return; } // Map WAV header to OpenAL format ALenum format; switch(wavspec.format) { case AUDIO_U8: case AUDIO_S8: format = AL_FORMAT_MONO8; break; case AUDIO_U16: case AUDIO_S16: format = AL_FORMAT_MONO16; break; default: SDL_FreeWAV(wavbuf); if (alIsBuffer(buffer)) alDeleteBuffers(1, &buffer); GfError("OpenAL Error: Unsupported WAV format %d for %s (not among U8, S8, U16, S16)\n", wavspec.format, filename); is_enabled = false; return; } alBufferData(buffer, format, wavbuf, wavlen, wavspec.freq); error = alGetError(); if (error != AL_NO_ERROR) { GfError("OpenAL Error: %d, alBufferData %s\n", error, filename); SDL_FreeWAV(wavbuf); if (alIsBuffer(buffer)) { alDeleteBuffers(1, &buffer); alGetError(); } is_enabled = false; return; } SDL_FreeWAV(wavbuf); if (!static_pool) { is_enabled = true; return; } if (!sitf->getStaticSource(&source)) { is_enabled = false; printf(" No static sources left: %s\n", filename); if (alIsBuffer(buffer)) { alDeleteBuffers(1, &buffer); alGetError(); } return; } else { is_enabled = true; } alSourcefv (source, AL_POSITION, source_position); error = alGetError(); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcefv AL_POSITION %s\n", error, filename); } alSourcefv (source, AL_VELOCITY, source_velocity); error = alGetError(); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcefv AL_VELOCITY %s\n", error, filename); } alSourcei (source, AL_BUFFER, buffer); error = alGetError(); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcei AL_BUFFER %s\n", error, filename); } alSourcei (source, AL_LOOPING, loop); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcei AL_LOOPING %s\n", error, filename); } alSourcef (source, AL_MAX_DISTANCE, MAX_DISTANCE); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcef AL_MAX_DISTANCE %s\n", error, filename); } alSourcef (source, AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcef AL_REFERENCE_DISTANCE %s\n", error, filename); } alSourcef (source, AL_ROLLOFF_FACTOR, ROLLOFF_FACTOR); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcef AL_ROLLOFF_FACTOR %s\n", error, filename); } alSourcef (source, AL_GAIN, 0.0f); if (error != AL_NO_ERROR) { printf("OpenAL Error: %d, alSourcef AL_GAIN %s\n", error, filename); } }