diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0772c6536..471fb8d62 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D2X-Rebirth Changelog +20101029 +-------- +arch/sdl/digi_mixer_music, include/hmp.h, misc/hmp.c: Instead of writing converted MIDI to file, write to buffer so it can be played directly + 20101016 -------- D2X.make, arch/sdl/jukebox.c, d2x-rebirth.xcodeproj/project.pbxproj, include/pstypes.h, main/game.c, main/hud.c, main/menu.c, main/newdemo.c, main/titles.c, misc/args.c, misc/physfsx.c: Fix errors for Mac OS 9, Mac OS X 'd2x' target builds again diff --git a/arch/sdl/digi_mixer_music.c b/arch/sdl/digi_mixer_music.c index d88c7d9f8..2c3b08d2f 100644 --- a/arch/sdl/digi_mixer_music.c +++ b/arch/sdl/digi_mixer_music.c @@ -23,7 +23,8 @@ Mix_Music *current_music = NULL; -char *current_music_hndlbuf = NULL; +static unsigned char *current_music_hndlbuf = NULL; + /* * Plays a music file from an absolute path or a relative path @@ -33,9 +34,9 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) { SDL_RWops *rw = NULL; PHYSFS_file *filehandle = NULL; - char midi_filename[PATH_MAX], full_path[PATH_MAX]; - char *basedir = "music", *fptr; - int bufsize = 0; + char full_path[PATH_MAX]; + char *fptr; + unsigned int bufsize = 0; mix_free_music(); // stop and free what we're already playing, if anything @@ -44,23 +45,21 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) if (fptr == NULL) return 0; - // It's a .hmp. Convertchar *current_music_hndlbuf = NULL; to mid, store in music/ and pass the new filename. - if (!stricmp(fptr, ".hmp")) - { - PHYSFS_mkdir(basedir); // ALWAYS attempt to make 'Music': might exist in some searchpath but not the write directory - snprintf(midi_filename, PATH_MAX, "%s/%s", basedir, filename); - midi_filename[PATH_MAX - 1] = '\0'; - change_filename_extension(midi_filename, midi_filename, ".mid"); - hmp2mid(filename, midi_filename); - filename = midi_filename; // finished with hmp - } - loop = loop ? -1 : 1; // loop means loop infinitely, otherwise play once - // try loading music via given filename - current_music = Mix_LoadMUS(filename); + // It's a .hmp. Convert to midi stream and load to current_music + if (!stricmp(fptr, ".hmp")) + { + hmp2mid(filename, ¤t_music_hndlbuf, &bufsize); + rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char)); + current_music = Mix_LoadMUS_RW(rw); + } - // no luck. so either it's in an archive or Searchpath + // try loading music via given filename + if (!current_music) + current_music = Mix_LoadMUS(filename); + + // no luck. so it might be in Searchpath. So try to build absolute path if (!current_music) { PHYSFSX_getRealPath(filename, full_path); @@ -69,15 +68,18 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) filename = full_path; // used later for possible error reporting } + // still nothin'? Let's open via PhysFS in case it's located inside an archive if (!current_music) - filehandle = PHYSFS_openRead(filename); - if (filehandle != NULL) { - current_music_hndlbuf = d_realloc(current_music_hndlbuf, sizeof(char *)*PHYSFS_fileLength(filehandle)); - bufsize = PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), PHYSFS_fileLength(filehandle)); - rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char)); - PHYSFS_close(filehandle); - current_music = Mix_LoadMUS_RW(rw); + filehandle = PHYSFS_openRead(filename); + if (filehandle != NULL) + { + current_music_hndlbuf = d_realloc(current_music_hndlbuf, sizeof(char *)*PHYSFS_fileLength(filehandle)); + bufsize = PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), PHYSFS_fileLength(filehandle)); + rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char)); + PHYSFS_close(filehandle); + current_music = Mix_LoadMUS_RW(rw); + } } if (current_music) @@ -89,12 +91,7 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)()) else { con_printf(CON_CRITICAL,"Music %s could not be loaded\n", filename); - Mix_HaltMusic(); - if (current_music_hndlbuf) - { - d_free(current_music_hndlbuf); - current_music_hndlbuf = NULL; - } + mix_stop_music(); } return 0; diff --git a/include/hmp.h b/include/hmp.h index f8cf70070..7e8ab3e07 100644 --- a/include/hmp.h +++ b/include/hmp.h @@ -54,7 +54,7 @@ typedef struct hmp_file { hmp_file *hmp_open(const char *filename); void hmp_close(hmp_file *hmp); -void hmp2mid(char *hmp_name, char *mid_name); +void hmp2mid(char *hmp_name, unsigned char **midbuf, unsigned int *midlen); #ifdef WIN32 int hmp_play(hmp_file *hmp, int bLoop); #endif diff --git a/misc/hmp.c b/misc/hmp.c index 5f839d339..c5bb70364 100644 --- a/misc/hmp.c +++ b/misc/hmp.c @@ -436,20 +436,21 @@ int hmp_play(hmp_file *hmp, int bLoop) // CONVERSION FROM HMP TO MIDI -static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid) +static unsigned int hmptrk2mid(ubyte* data, int size, unsigned char **midbuf, unsigned int *midlen) { ubyte *dptr = data; ubyte lc1 = 0,last_com = 0; - uint t = 0, d; + uint d; int n1, n2; - int offset = cftell(mid); + unsigned int offset = *midlen; while (data < dptr + size) { if (data[0] & 0x80) { ubyte b = (data[0] & 0x7F); - PHYSFS_write(mid, &b, sizeof (b), 1); - t+=b; + *midbuf = d_realloc(*midbuf, *midlen + 1); + memcpy(&(*midbuf)[*midlen], &b, 1); + *midlen += 1; } else { d = (data[0] & 0x7F); @@ -458,7 +459,6 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid) n1++; d += (data[n1] & 0x7F) << (n1 * 7); } - t += d; n1 = 1; while ((data[n1] & 0x80) == 0) { n1++; @@ -470,13 +470,17 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid) if (n2 != n1) b |= 0x80; - PHYSFS_write(mid, &b, sizeof(b), 1); + *midbuf = d_realloc(*midbuf, *midlen + 1); + memcpy(&(*midbuf)[*midlen], &b, 1); + *midlen += 1; } data += n1; } data++; if (*data == 0xFF) { //meta? - PHYSFS_write(mid, data, 3 + data [2], 1); + *midbuf = d_realloc(*midbuf, *midlen + 3 + data[2]); + memcpy(&(*midbuf)[*midlen], data, 3 + data[2]); + *midlen += 3 + data[2]; if (data[1] == 0x2F) break; } @@ -491,15 +495,27 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid) case 0xB0: case 0xE0: if (lc1 != last_com) - PHYSFS_write(mid, &lc1, sizeof (lc1), 1); - PHYSFS_write(mid, data + 1, 2, 1); + { + *midbuf = d_realloc(*midbuf, *midlen + 1); + memcpy(&(*midbuf)[*midlen], &lc1, 1); + *midlen += 1; + } + *midbuf = d_realloc(*midbuf, *midlen + 2); + memcpy(&(*midbuf)[*midlen], data + 1, 2); + *midlen += 2; data += 3; break; case 0xC0: case 0xD0: if (lc1 != last_com) - PHYSFS_write(mid, &lc1, sizeof (lc1), 1); - PHYSFS_write(mid, data + 1, 1, 1); + { + *midbuf = d_realloc(*midbuf, *midlen + 1); + memcpy(&(*midbuf)[*midlen], &lc1, 1); + *midlen += 1; + } + *midbuf = d_realloc(*midbuf, *midlen + 1); + memcpy(&(*midbuf)[*midlen], data + 1, 1); + *midlen += 1; data += 2; break; default: @@ -508,53 +524,63 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid) last_com = lc1; } } - return (cftell(mid) - offset); + return (*midlen - offset); } ubyte tempo [19] = {'M','T','r','k',0,0,0,11,0,0xFF,0x51,0x03,0x18,0x80,0x00,0,0xFF,0x2F,0}; -void hmp2mid(char *hmp_name, char *mid_name) +void hmp2mid(char *hmp_name, unsigned char **midbuf, unsigned int *midlen) { - PHYSFS_file *mid=NULL; - int mi, i, loc; + int mi, i; short ms; hmp_file *hmp=NULL; hmp = hmp_open(hmp_name); if (hmp == NULL) return; - mid = PHYSFSX_openWriteBuffered(mid_name); - if (mid == NULL) - { - hmp_close(hmp); - return; - } + + *midlen = 0; + // write MIDI-header - PHYSFS_write(mid, "MThd", 4, 1); + *midbuf = d_realloc(*midbuf, *midlen + 4); + memcpy(&(*midbuf)[*midlen], "MThd", 4); + *midlen += 4; mi = MIDIINT(6); - PHYSFS_write(mid, &mi, sizeof(mi), 1); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(mi)); + memcpy(&(*midbuf)[*midlen], &mi, sizeof(mi)); + *midlen += sizeof(mi); ms = MIDISHORT(1); - PHYSFS_write(mid, &ms, sizeof(ms), 1); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(ms)); + memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms)); + *midlen += sizeof(ms); ms = MIDISHORT(hmp->num_trks); - PHYSFS_write(mid, &ms, sizeof(ms), 1); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(ms)); + memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms)); + *midlen += sizeof(ms); ms = MIDISHORT((short) 0xC0); - PHYSFS_write(mid, &ms, sizeof(ms), 1); - PHYSFS_write(mid, tempo, sizeof(tempo), 1); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(ms)); + memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms)); + *midlen += sizeof(ms); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(tempo)); + memcpy(&(*midbuf)[*midlen], &tempo, sizeof(tempo)); + *midlen += sizeof(tempo); // tracks for (i = 1; i < hmp->num_trks; i++) { - PHYSFS_write(mid, "MTrk", 4, 1); - loc = cftell(mid); + int midtrklenpos = 0; + + *midbuf = d_realloc(*midbuf, *midlen + 4); + memcpy(&(*midbuf)[*midlen], "MTrk", 4); + *midlen += 4; + midtrklenpos = *midlen; mi = 0; - PHYSFS_write(mid, &mi, sizeof(mi), 1); - mi = hmptrk2mid(hmp->trks[i].data, hmp->trks[i].len, mid); + *midbuf = d_realloc(*midbuf, *midlen + sizeof(mi)); + *midlen += sizeof(mi); + mi = hmptrk2mid(hmp->trks[i].data, hmp->trks[i].len, midbuf, midlen); mi = MIDIINT(mi); - cfseek(mid, loc, SEEK_SET); - PHYSFS_write(mid, &mi, sizeof(mi), 1); - cfseek(mid, 0, SEEK_END); + memcpy(&(*midbuf)[midtrklenpos], &mi, 4); } hmp_close(hmp); - cfclose(mid); }