static void CDAudio_AddTrack(trackinfo_t* nod, char* track) { int ord; trackinfo_t* tnew; ord = strcmp(track, nod->track); if(ord != 0) { if(((ord < 0) && (nod->prev == NULL)) || ((ord > 0) && (nod->next == NULL))) { tnew = Sys_Malloc(sizeof(trackinfo_t), "CDAudio_GetAudioDiskInfo"); tnew->track = Sys_Malloc(strlen(track) + 1, "CDAudio_GetAudioDiskInfo"); strcpy(tnew->track, track); tnew->prev = NULL; tnew->next = NULL; if(ord < 0) { nod->prev = tnew; } else { nod->next = tnew; }; } else if(ord < 0) { CDAudio_AddTrack(nod->prev, track); } else { CDAudio_AddTrack(nod->next, track); }; }; }
static int CDAudio_GetAudioDiskInfo(void) { char* t; cdValid = false; if(trackList != NULL) { CDAudio_DeleteTracks(trackList); free(trackList); trackList = NULL; }; maxTrack = 0; sprintf(trackDir, cd_tracks.string, com_gamedir); sprintf(tracks, "%s/*.ogg", trackDir); t = Sys_FindFirst(tracks, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM); if(t == NULL) { Sys_FindClose(); return -1; } cdValid = true; do { if(trackList == NULL) { trackList = Sys_Malloc(sizeof(trackinfo_t), "CDAudio_GetAudioDiskInfo"); trackList->track = Sys_Malloc(strlen(t) + 1, "CDAudio_GetAudioDiskInfo"); strcpy(trackList->track, t); trackList->prev = NULL; trackList->next = NULL; } else { CDAudio_AddTrack(trackList, t); }; maxTrack++; t = Sys_FindNext(0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM); } while(t != NULL); if(cd_nofirst.value) maxTrack++; Sys_FindClose(); return 0; }
/** * * Puts a process on the blocked list and stops its execution (if it's executed) * * @param[in] pid Process ID * @param[in] eventID The Id of the event which can put the process (PID) back on the ready list * @param[in] func The function that handles the event * @param[in] cond The condition under which the handler is executed * @return bool Was the event-handler successfully added? */ bool Sys_Add_Event_Subscription(uint pid, uint eventID, pEventHandlerFunction func, pConditionFunction cond){ if(func == 0){//if nothing handles events, nothing will always handle events -> true return true; } sys_pcb_list_element *element = Sys_Find_Process(pid); if(element == 0){//cant find process (pid)) return false; } sys_process_event_handler *new_event = (sys_process_event_handler *) Sys_Malloc(sizeof(sys_process_event_handler)); if(new_event == 0){//no memory return false; } new_event->eventID = eventID; new_event->handler = func; new_event->condition = cond; new_event->next = 0; new_event->buffered_data = 0; if(element->pcb.event_register != 0 ){ //add at the end sys_process_event_handler *event_h = element->pcb.event_register; while(event_h != 0){ if(event_h->next == 0){ break; }else{ event_h = event_h->next; } } event_h->next = new_event; }else{ //add to top element->pcb.event_register = new_event; } return true; }
/** * * This function adds the event-data to the local list of the process (pid). * * @param[in] pid process identifier * @param[in] eventID event identifier * @param[in] data memory that contains the value of the occurred event * @param[in] length length of the data (bytes) */ void Sys_Add_Event_to_Process(uint pid, uint eventID, void *data, uint length){ sys_pcb_list_element *element; Sys_Start_AtomicSection(); element = Sys_Find_Process(pid); if(element == 0){//no process with pid Sys_End_AtomicSection(); return; } bool add_event = true; sys_occurred_event **o_event = &sys_occurred_events; while(*o_event != 0){//check if the event (eventID) already occurred if((*o_event)->eventID == eventID){//it already occurred add_event = false; break; } o_event = &((*o_event)->next); } if(add_event){//if it hasn't occurred //add eventID to the list of occurred events (*o_event) = Sys_Malloc(sizeof(sys_occurred_event)); if((*o_event) == 0){ Sys_End_AtomicSection(); return; //no memory left } (*o_event)->eventID = eventID; (*o_event)->next = 0; } //NOW add the data sys_process_event_handler *event = element->pcb.event_register; while( (event = Sys_Next_EventHandler(event, eventID)) != 0 ){ //check if the condition was met to add the event data bool is_condition_met = false; if(event->condition != 0){ is_condition_met = event->condition(data); }else{//no condition is always met is_condition_met = true; } if( is_condition_met ){ sys_event_data *e_data = (sys_event_data*) Sys_Malloc(sizeof(sys_event_data)); if(e_data == 0){//if malloc fails .. exit Sys_End_AtomicSection(); return; } //create the struct that holds the data if(length != 0){//if there is data e_data->value = Sys_Malloc(length); if(e_data->value == 0){//if malloc fails .. exit Sys_Free(e_data); Sys_End_AtomicSection(); return; } Sys_Memcpy(data, e_data->value, length); }else{ e_data->value = 0; } e_data->size = length; e_data->next = 0; //add the struct to the end of the buffered_data if(event->buffered_data == 0){ event->buffered_data = e_data; }else{ sys_event_data *set_data = event->buffered_data; while(set_data->next != 0){ set_data = set_data->next; } set_data->next = e_data; } event = event->next; } } Sys_End_AtomicSection(); }
void CDAudio_Play(byte track, qboolean looping) { int i, lf; trackinfo_t* tnod; int trackHdl; int newTrackDataLength; byte* newTrackData; if (!enabled) return; if (!cdValid) { CDAudio_GetAudioDiskInfo(); if (!cdValid) return; } track = remap[track]; if (track < 1 || track > maxTrack) { Con_DPrintf("CDAudio: Bad track number %u.\n", track); return; } i = track; if(cd_nofirst.value) i--; if (playing) { if (playTrack == track) return; CDAudio_Stop(); } lf = -1; tnod = CDAudio_GetTrack(trackList, i - 1, &lf); if(tnod == NULL) { Con_Printf("CDAudio: Can't locate track %i\n", track); return; } newTrackDataLength = Sys_FileOpenRead(tnod->track, &trackHdl); if(newTrackDataLength <= 0) { Con_Printf("CDAudio: Can't open track %i\n", track); return; }; if(trackData == NULL) { trackData = Sys_Malloc(newTrackDataLength, "CDAudio_Play"); trackDataSize = newTrackDataLength; } else if(trackDataSize < newTrackDataLength) { newTrackData = realloc(trackData, newTrackDataLength); if(newTrackData == NULL) { free(trackData); trackData = Sys_Malloc(newTrackDataLength, "CDAudio_Play"); } else { trackData = newTrackData; }; trackDataSize = newTrackDataLength; }; trackDataLength = newTrackDataLength; Sys_FileRead(trackHdl, trackData, trackDataLength); Sys_FileClose(trackHdl); if(PlayOgg(trackData, trackDataLength, 0, looping ? OGG_INFINITE_TIME : OGG_ONE_TIME)) { Con_Printf("CDAudio: Can't play track %i\n", track); return; }; playLooping = looping; playTrack = track; playing = true; //Con_Printf("Now playing: %s\n", tnod->track); if (cdvolume == 0.0) CDAudio_Pause (); }