jukebox/music

Posted by Typhon on Sun 22 Dec 2002 12:53 PM — 3 posts, 15,254 views.

USA #0
hi there it seems that there isnt any sort of port f the jukebox stuff from rom to smaug so i ported it myself.. however i have run into a little problem and i dont know enough about file manipulation in C to really know what im doing :p... i have grabbed the music.c and music.h from stock rom 2.4 and i rewrote it to work with smaug. only problem is at this point.. when the music file is loaded it reads everything correctly and it puts the artist and song name correctly into the song table but the lyrics it seems to keep screwing up on. it loads a set of numbers (ie: "2 2 0 0 0 0") for every line in the song.. it has the correct number of lines it just isnt readign the lines in at all :p.. ill post the load_song function and an example from the music.txt if anyone see anything i would greatly appreciate the help :)
//this is what hte song tabel looks like..
Quote:

struct song_data
{
char *group;
char *name;
char *lyrics[MAX_LINES];
int lines;
};

struct song_data song_table[MAX_SONGS];


//load_song: reads all the information from a file into a global table
Quote:

void load_songs(void)
{
FILE *fp;
int count = 0, lines, i;
char letter;

if ((fp = fopen(MUSIC_FILE,"r")) == NULL)
{
bug("Couldn't open music file, no songs available.",0);
fclose(fp);
return;
}

for (count = 0; count < MAX_SONGS; count++)
{
letter = fread_letter(fp);
if (letter == '#')
{
if (count < MAX_SONGS)
song_table[count].name = NULL;
fclose(fp);
return;
}
else
ungetc(letter,fp);

song_table[count].group = fread_string(fp);
song_table[count].name = fread_string(fp);

/* read lyrics */
lines = 0;

for ( ; ;)
{
letter = fread_letter(fp);

if (letter == '~')
{
song_table[count].lines = lines;
break;
}
else
ungetc(letter,fp);

if (lines >= MAX_LINES)
{
bug("Too many lines in a song -- limit is %d.",MAX_LINES);
break;
}

song_table[count].lyrics[lines] = fread_line(fp);
lines++;
}
}
return;
}

//part of music.txt... after the lyrics the ~ means the end of the song and the # means the end of the file :p

Quote:

U2~
With or Without You~
See the stone set in your eyes
See the thorn twist in your side
I wait for you
Slight of hand and twist of fate
On a bed of nails she makes me wait
And I wait....without you
With or without you
With or without you
Through the storm we reach the shore
You give it all but I want more
And I'm waiting for you
With or without you
With or without you
I can't live
With or without you
And you give yourself away
And you give yourself away
And you give
And you give
And you give yourself away
My hands are tied
My body bruised, she's got me with
Nothing left to win
And nothing else to lose
With or without you
With or without you
I can't live
With or without you
~
#
Australia Forum Administrator #1
Your problem is with this line:

song_table[count].lyrics[lines] = fread_line(fp);

You are copying a pointer, not what it is pointing to. If you look at fread_line it returns a pointer to a static piece of memory. Each subsequent read will overwrite that piece of memory so your array will be full of the same pointer to the memory in fread_line, namely:

static char line[MAX_STRING_LENGTH];

Something like this is required, although I am just typing it, not testing it ...

(more declarations)

char * lyric;

(replace processing above)

/* read the line */
lyric = fread_line(fp);

/* allocate memory in song table, add 1 to allow for null at end */
CREATE (song_table[count].lyrics[lines] , char, strlen (lyric) + 1);

/* copy lyric into allocated memory */
strcpy (song_table[count].lyrics[lines] , lyric);


Later on when you have finished with the song table, you should use DISPOSE (song_table[count].lyrics[lines]); to free up the memory you allocated.
USA #2
worked like a charm.. if anyone wants the port ill clean it up and post it on my page :)