/* * @brief Loads the music by the specified name. */ s_music_t *S_LoadMusic(const char *name) { char key[MAX_QPATH]; s_music_t *music; StripExtension(name, key); if (!(music = (s_music_t *) S_FindMedia(key))) { void *buffer; SDL_RWops *rw; Mix_Music *mus; if (S_LoadMusicFile(key, &buffer, &rw, &mus)) { music = (s_music_t *) S_AllocMedia(key, sizeof(s_music_t)); music->media.Retain = S_RetainMusic; music->media.Free = S_FreeMusic; music->buffer = buffer; music->rw = rw; music->music = mus; S_RegisterMedia((s_media_t *) music); } else { Com_Debug("S_LoadMusic: Couldn't load %s\n", key); music = NULL; } } if (music) { s_music_state.playlist = g_list_append(s_music_state.playlist, music); } return music; }
/* * @brief */ s_sample_t *S_LoadSample(const char *name) { char key[MAX_QPATH]; s_sample_t *sample; if (!s_env.initialized) return NULL; if (!name || !name[0]) { Com_Error(ERR_DROP, "NULL name\n"); } StripExtension(name, key); if (!(sample = (s_sample_t *) S_FindMedia(key))) { sample = (s_sample_t *) S_AllocMedia(key, sizeof(s_sample_t)); sample->media.Free = S_FreeSample; S_LoadSampleChunk(sample); S_RegisterMedia((s_media_t *) sample); } return sample; }
/** * @brief Inserts the specified media into the shared table. */ void S_RegisterMedia(s_media_t *media) { // check to see if we're already seeded if (media->seed != s_media_state.seed) { s_media_t *m; if ((m = g_hash_table_lookup(s_media_state.media, media->name))) { if (m != media) { Com_Debug(DEBUG_SOUND, "Replacing %s\n", media->name); S_FreeMedia_(NULL, m, m); g_hash_table_replace(s_media_state.media, media->name, media); } else { Com_Debug(DEBUG_SOUND, "Retaining %s\n", media->name); } } else { Com_Debug(DEBUG_SOUND, "Inserting %s\n", media->name); g_hash_table_insert(s_media_state.media, media->name, media); s_media_state.keys = g_list_insert_sorted(s_media_state.keys, media->name, S_RegisterMedia_Compare); } // re-seed the media to retain it media->seed = s_media_state.seed; } // finally re-register all dependencies GList *d = media->dependencies; while (d) { S_RegisterMedia((s_media_t *) d->data); d = d->next; } }
/* * @brief Resolves the specified media if it is already known. The returned * media is re-registered for convenience. * * @return s_media_t The media, or NULL. */ s_media_t *S_FindMedia(const char *name) { s_media_t *media; if ((media = g_hash_table_lookup(s_media_state.media, name))) { S_RegisterMedia(media); } return media; }
/* * @brief Registers and returns a new sample, aliasing the chunk provided by * the specified sample. */ static s_sample_t *S_AliasSample(s_sample_t *sample, const char *alias) { s_sample_t *s = (s_sample_t *) S_AllocMedia(alias, sizeof(s_sample_t)); s->chunk = sample->chunk; S_RegisterMedia((s_media_t *) s); return s; }
/** * @brief Establishes a dependency from the specified dependent to the given * dependency. Dependencies in use by registered media are never freed. */ void S_RegisterDependency(s_media_t *dependent, s_media_t *dependency) { if (dependent) { if (dependency) { if (!g_list_find(dependent->dependencies, dependency)) { Com_Debug(DEBUG_SOUND, "%s -> %s\n", dependent->name, dependency->name); dependent->dependencies = g_list_prepend(dependent->dependencies, dependency); S_RegisterMedia(dependency); } } else { // Com_Debug("Invalid dependency for %s\n", dependent->name); } } else { Com_Warn("Invalid dependent\n"); } }