void * _GetMusicData (uio_Stream *fp, DWORD length) { MUSIC_REF h; TFB_SoundSample *sample; TFB_SoundDecoder *decoder; char filename[256]; if (!_cur_resfile_name) return NULL; strncpy (filename, _cur_resfile_name, sizeof(filename) - 1); filename[sizeof(filename) - 1] = '\0'; CheckMusicResName (filename); log_add (log_Info, "_GetMusicData(): loading %s", filename); decoder = SoundDecoder_Load (contentDir, filename, 4096, 0, 0); if (!decoder) { log_add (log_Warning, "_GetMusicData(): couldn't load %s", filename); return NULL; } h = AllocMusicData (sizeof (void *)); if (!h) { SoundDecoder_Free (decoder); return NULL; } sample = TFB_CreateSoundSample (decoder, 64, NULL); *h = sample; log_add (log_Info, " decoder: %s, rate %d format %x", SoundDecoder_GetName (sample->decoder), sample->decoder->frequency, sample->decoder->format); (void) fp; /* satisfy compiler (unused parameter) */ (void) length; /* satisfy compiler (unused parameter) */ return (h); }
// XXX: This code and the entire trackplayer are begging to be overhauled void SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, CallbackFunction cb) { static UNICODE last_track_name[128] = ""; static unsigned long dec_offset = 0; #define MAX_PAGES 50 UNICODE *pages[MAX_PAGES]; sint32 time_stamps[MAX_PAGES]; int num_pages; int page; if (!TrackText) return; if (!TrackName) { // Appending a piece of subtitles to the last track int slen1, slen2; if (track_count == 0) { log_add (log_Warning, "SpliceTrack(): Tried to append a subtitle," " but no current track"); return; } if (!last_sub || !last_sub->text) { log_add (log_Warning, "SpliceTrack(): Tried to append a subtitle" " to a NULL string"); return; } num_pages = SplitSubPages (TrackText, pages, time_stamps, MAX_PAGES); if (num_pages == 0) { log_add (log_Warning, "SpliceTrack(): Failed to parse subtitles"); return; } // The last page's stamp is a suggested value. The track should // actually play to the end. time_stamps[num_pages - 1] = -time_stamps[num_pages - 1]; // Add the first piece to the last subtitle page slen1 = strlen (last_sub->text); slen2 = strlen (pages[0]); last_sub->text = HRealloc (last_sub->text, slen1 + slen2 + 1); strcpy (last_sub->text + slen1, pages[0]); HFree (pages[0]); // Add the rest of the pages for (page = 1; page < num_pages; ++page) { TFB_SoundChunk *next_sub = find_next_page (last_sub); if (next_sub) { // nodes prepared by previous call, just fill in the subs next_sub->text = pages[page]; last_sub = next_sub; } else { // probably no timestamps were provided, so need more work TFB_SoundDecoder *decoder = SoundDecoder_Load (contentDir, last_track_name, 4096, dec_offset, time_stamps[page]); if (!decoder) { log_add (log_Warning, "SpliceTrack(): couldn't load %s", TrackName); break; } dec_offset += (unsigned long)(decoder->length * 1000); chunks_tail->next = create_SoundChunk (decoder, sound_sample->length); chunks_tail = chunks_tail->next; chunks_tail->tag_me = 1; chunks_tail->track_num = track_count - 1; chunks_tail->text = pages[page]; chunks_tail->callback = cb; // TODO: We may have to tag only one page with a callback //cb = NULL; last_sub = chunks_tail; sound_sample->length += decoder->length; } } } else { // Adding a new track int num_timestamps = 0; utf8StringCopy (last_track_name, sizeof (last_track_name), TrackName); num_pages = SplitSubPages (TrackText, pages, time_stamps, MAX_PAGES); if (num_pages == 0) { log_add (log_Warning, "SpliceTrack(): Failed to parse sutitles"); return; } // The last page's stamp is a suggested value. The track should // actually play to the end. time_stamps[num_pages - 1] = -time_stamps[num_pages - 1]; if (no_page_break && track_count) { int slen1, slen2; slen1 = strlen (last_sub->text); slen2 = strlen (pages[0]); last_sub->text = HRealloc (last_sub->text, slen1 + slen2 + 1); strcpy (last_sub->text + slen1, pages[0]); HFree (pages[0]); } else track_count++; log_add (log_Info, "SpliceTrack(): loading %s", TrackName); if (TimeStamp) { num_timestamps = GetTimeStamps (TimeStamp, time_stamps) + 1; if (num_timestamps < num_pages) { log_add (log_Warning, "SpliceTrack(): number of timestamps" " doesn't match number of pages!"); } else if (num_timestamps > num_pages) { // We most likely will get more subtitles appended later // Set the last page to the rest of the track time_stamps[num_timestamps - 1] = -100000; } } else { num_timestamps = num_pages; } // Reset the offset for the new track dec_offset = 0; for (page = 0; page < num_timestamps; ++page) { TFB_SoundDecoder *decoder = SoundDecoder_Load (contentDir, TrackName, 4096, dec_offset, time_stamps[page]); if (!decoder) { log_add (log_Warning, "SpliceTrack(): couldn't load %s", TrackName); break; } if (!sound_sample) { sound_sample = TFB_CreateSoundSample (NULL, 8, &trackCBs); chunks_head = create_SoundChunk (decoder, 0.0); chunks_tail = chunks_head; } else { chunks_tail->next = create_SoundChunk (decoder, sound_sample->length); chunks_tail = chunks_tail->next; } dec_offset += (unsigned long)(decoder->length * 1000); #if 0 log_add (log_Debug, "page (%d of %d): %d ts: %d", page, num_pages, dec_offset, time_stamps[page]); #endif sound_sample->length += decoder->length; chunks_tail->track_num = track_count - 1; if (!no_page_break) { chunks_tail->tag_me = 1; if (page < num_pages) { chunks_tail->text = pages[page]; last_sub = chunks_tail; } chunks_tail->callback = cb; // TODO: We may have to tag only one page with a callback //cb = NULL; } no_page_break = 0; } } }
// decodes several tracks into one and adds it to queue // track list is NULL-terminated // May only be called after at least one SpliceTrack(). This is a limitation // for the sake of timestamps, but it does not have to be so. void SpliceMultiTrack (UNICODE *TrackNames[], UNICODE *TrackText) { #define MAX_MULTI_TRACKS 20 #define MAX_MULTI_BUFFERS 100 TFB_SoundDecoder* track_decs[MAX_MULTI_TRACKS + 1]; int tracks; int slen1, slen2; if (!TrackText) { log_add (log_Debug, "SpliceMultiTrack(): no track text"); return; } if (!sound_sample || !chunks_tail) { log_add (log_Warning, "SpliceMultiTrack(): Cannot be called before SpliceTrack()"); return; } log_add (log_Info, "SpliceMultiTrack(): loading..."); for (tracks = 0; *TrackNames && tracks < MAX_MULTI_TRACKS; TrackNames++, tracks++) { track_decs[tracks] = SoundDecoder_Load (contentDir, *TrackNames, 32768, 0, - 3 * TEXT_SPEED); if (track_decs[tracks]) { log_add (log_Info, " track: %s, decoder: %s, rate %d format %x", *TrackNames, SoundDecoder_GetName (track_decs[tracks]), track_decs[tracks]->frequency, track_decs[tracks]->format); SoundDecoder_DecodeAll (track_decs[tracks]); chunks_tail->next = create_SoundChunk (track_decs[tracks], sound_sample->length); chunks_tail = chunks_tail->next; chunks_tail->track_num = track_count - 1; sound_sample->length += track_decs[tracks]->length; } else { log_add (log_Warning, "SpliceMultiTrack(): couldn't load %s\n", *TrackNames); tracks--; } } track_decs[tracks] = 0; // term if (tracks == 0) { log_add (log_Warning, "SpliceMultiTrack(): no tracks loaded"); return; } slen1 = strlen (last_sub->text); slen2 = strlen (TrackText); last_sub->text = HRealloc (last_sub->text, slen1 + slen2 + 1); strcpy (last_sub->text + slen1, TrackText); no_page_break = 1; }
MEM_HANDLE _GetSoundBankData (uio_Stream *fp, DWORD length) { int snd_ct, n; DWORD opos; char CurrentLine[1024], filename[1024]; #define MAX_FX 256 TFB_SoundSample *sndfx[MAX_FX]; STRING_TABLE Snd; (void) length; // ignored opos = uio_ftell (fp); { char *s1, *s2; if (_cur_resfile_name == 0 || (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) n = 0; else { if (s2 > s1) s1 = s2; n = s1 - _cur_resfile_name + 1; strncpy (filename, _cur_resfile_name, n); } } snd_ct = 0; while (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) && snd_ct < MAX_FX) { if (sscanf(CurrentLine, "%s", &filename[n]) == 1) { log_add (log_Info, "_GetSoundBankData(): loading %s", filename); sndfx[snd_ct] = (TFB_SoundSample *) HCalloc (sizeof (TFB_SoundSample)); sndfx[snd_ct]->decoder = SoundDecoder_Load (contentDir, filename, 4096, 0, 0); if (!sndfx[snd_ct]->decoder) { log_add (log_Warning, "_GetSoundBankData(): couldn't load %s", filename); HFree (sndfx[snd_ct]); } else { uint32 decoded_bytes; decoded_bytes = SoundDecoder_DecodeAll (sndfx[snd_ct]->decoder); log_add (log_Info, "_GetSoundBankData(): decoded_bytes %d", decoded_bytes); sndfx[snd_ct]->num_buffers = 1; sndfx[snd_ct]->buffer = (audio_Object *) HMalloc ( sizeof (audio_Object) * sndfx[snd_ct]->num_buffers); audio_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer); audio_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format, sndfx[snd_ct]->decoder->buffer, decoded_bytes, sndfx[snd_ct]->decoder->frequency); SoundDecoder_Free (sndfx[snd_ct]->decoder); sndfx[snd_ct]->decoder = NULL; ++snd_ct; } } else { log_add (log_Warning, "_GetSoundBankData: Bad file!"); } // pkunk insult fix 2002/11/12 (ftell shouldn't be needed for loop to terminate) /*if (uio_ftell (fp) - opos >= length) break;*/ } Snd = 0; if (snd_ct && (Snd = AllocStringTable ( sizeof (STRING_TABLE_DESC) + (sizeof (DWORD) * snd_ct) + (sizeof (sndfx[0]) * snd_ct) ))) { STRING_TABLEPTR fxTab; LockStringTable (Snd, &fxTab); if (fxTab == 0) { while (snd_ct--) { if (sndfx[snd_ct]->decoder) SoundDecoder_Free (sndfx[snd_ct]->decoder); HFree (sndfx[snd_ct]); } FreeStringTable (Snd); Snd = 0; } else { DWORD *offs, StringOffs; fxTab->StringCount = snd_ct; fxTab->flags = 0; offs = fxTab->StringOffsets; StringOffs = sizeof (STRING_TABLE_DESC) + (sizeof (DWORD) * snd_ct); memcpy ((BYTE *)fxTab + StringOffs, sndfx, sizeof (sndfx[0]) * snd_ct); do { *offs++ = StringOffs; StringOffs += sizeof (sndfx[0]); } while (snd_ct--); UnlockStringTable (Snd); } } return ((MEM_HANDLE)Snd); }
void * _GetSoundBankData (uio_Stream *fp, DWORD length) { int snd_ct, n; DWORD opos; char CurrentLine[1024], filename[1024]; #define MAX_FX 256 TFB_SoundSample *sndfx[MAX_FX]; STRING_TABLE Snd; (void) length; // ignored opos = uio_ftell (fp); { char *s1, *s2; if (_cur_resfile_name == 0 || (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) n = 0; else { if (s2 > s1) s1 = s2; n = s1 - _cur_resfile_name + 1; strncpy (filename, _cur_resfile_name, n); } } snd_ct = 0; while (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) && snd_ct < MAX_FX) { if (sscanf(CurrentLine, "%s", &filename[n]) == 1) { log_add (log_Info, "_GetSoundBankData(): loading %s", filename); sndfx[snd_ct] = (TFB_SoundSample *) HCalloc (sizeof (TFB_SoundSample)); sndfx[snd_ct]->decoder = SoundDecoder_Load (contentDir, filename, 4096, 0, 0); if (!sndfx[snd_ct]->decoder) { log_add (log_Warning, "_GetSoundBankData(): couldn't load %s", filename); HFree (sndfx[snd_ct]); } else { uint32 decoded_bytes; decoded_bytes = SoundDecoder_DecodeAll (sndfx[snd_ct]->decoder); log_add (log_Info, "_GetSoundBankData(): decoded_bytes %d", decoded_bytes); sndfx[snd_ct]->num_buffers = 1; sndfx[snd_ct]->buffer = (audio_Object *) HMalloc ( sizeof (audio_Object) * sndfx[snd_ct]->num_buffers); audio_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer); audio_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format, sndfx[snd_ct]->decoder->buffer, decoded_bytes, sndfx[snd_ct]->decoder->frequency); SoundDecoder_Free (sndfx[snd_ct]->decoder); sndfx[snd_ct]->decoder = NULL; ++snd_ct; } } else { log_add (log_Warning, "_GetSoundBankData: Bad file!"); } // pkunk insult fix 2002/11/12 (ftell shouldn't be needed for loop to terminate) /*if (uio_ftell (fp) - opos >= length) break;*/ } Snd = NULL; if (snd_ct && (Snd = AllocStringTable (snd_ct, 0))) { STRING_TABLE fxTab = Snd; if (fxTab == 0) { while (snd_ct--) { if (sndfx[snd_ct]->decoder) SoundDecoder_Free (sndfx[snd_ct]->decoder); HFree (sndfx[snd_ct]); } FreeStringTable (Snd); Snd = 0; } else { STRING str; int i; str = fxTab->strings; for (i = 0; i < snd_ct; i++) { TFB_SoundSample **target = HMalloc (sizeof (sndfx[0])); *target = sndfx[i]; str->data = (STRINGPTR)target; str->length = sizeof (sndfx[0]); str++; } } } return Snd; }