mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
but the third castle stood!
This commit is contained in:
parent
0045ab7c09
commit
e1b779502a
1 changed files with 115 additions and 43 deletions
158
libs/util/riff.c
158
libs/util/riff.c
|
@ -30,6 +30,12 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include "string.h"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include "strings.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static __attribute__ ((unused)) const char rcsid[] =
|
static __attribute__ ((unused)) const char rcsid[] =
|
||||||
"$Id$";
|
"$Id$";
|
||||||
|
@ -44,42 +50,77 @@ void *alloca(size_t size);
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
#include "QF/riff.h"
|
#include "QF/riff.h"
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
Rread (QFile *f, void *buf, int len)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = Qread (f, buf, len);
|
||||||
|
if (count != len)
|
||||||
|
return 0;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
read_string (QFile *f, int len)
|
read_string (QFile *f, int len)
|
||||||
{
|
{
|
||||||
char c[2] = {0, 0};
|
char c[2] = {0, 0};
|
||||||
char *s;
|
char *s;
|
||||||
int l = len;
|
int l = len;
|
||||||
dstring_t *str = dstring_newstr ();
|
dstring_t *str;
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return 0;
|
||||||
|
str = dstring_newstr ();
|
||||||
while (l--) {
|
while (l--) {
|
||||||
Qread (f, c, 1);
|
if (Qread (f, c, 1) != 1)
|
||||||
|
goto done;
|
||||||
if (!c[0])
|
if (!c[0])
|
||||||
break;
|
break;
|
||||||
dstring_appendstr (str, c);
|
dstring_appendstr (str, c);
|
||||||
}
|
}
|
||||||
|
Qseek (f, l, SEEK_CUR);
|
||||||
|
if (len &1) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if ((c = Qgetc (f)) && c != -1)
|
||||||
|
Qungetc (f, c);
|
||||||
|
}
|
||||||
|
done:
|
||||||
s = str->str;
|
s = str->str;
|
||||||
free (str);
|
free (str);
|
||||||
if (len &1) puts ("bling");
|
|
||||||
Qseek (f, l + (len & 1), SEEK_CUR);
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
read_data (QFile *f, int len)
|
read_data (QFile *f, int len)
|
||||||
{
|
{
|
||||||
void *data = malloc (len);
|
void *data;
|
||||||
|
int count;
|
||||||
|
|
||||||
Qread (f, data, len);
|
if (!len)
|
||||||
if (len &1) puts ("bling");
|
return 0;
|
||||||
Qseek (f, len & 1, SEEK_CUR);
|
data = malloc (len);
|
||||||
|
count = Qread (f, data, len);
|
||||||
|
if (count == len && len &1) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if ((c = Qgetc (f)) && c != -1)
|
||||||
|
Qungetc (f, c);
|
||||||
|
}
|
||||||
|
if (count && count != len)
|
||||||
|
realloc (data, count);
|
||||||
|
if (!count) {
|
||||||
|
free (data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
read_ltxt (QFile *f, int len, d_ltxt_t *ltxt)
|
read_ltxt (QFile *f, int len, d_ltxt_t *ltxt)
|
||||||
{
|
{
|
||||||
Qread (f, ltxt, len);
|
return Qread (f, ltxt, len) == len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -94,7 +135,7 @@ read_adtl (dstring_t *list_buf, QFile *f, int len)
|
||||||
|
|
||||||
list = (list_t *) list_buf->str;
|
list = (list_t *) list_buf->str;
|
||||||
while (len) {
|
while (len) {
|
||||||
r = Qread (f, &ck, sizeof (ck));
|
r = Rread (f, &ck, sizeof (ck));
|
||||||
if (!r) {
|
if (!r) {
|
||||||
len = 0;
|
len = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -102,7 +143,7 @@ read_adtl (dstring_t *list_buf, QFile *f, int len)
|
||||||
len -= r;
|
len -= r;
|
||||||
SWITCH (ck.name) {
|
SWITCH (ck.name) {
|
||||||
case CASE ('l','t','x','t'):
|
case CASE ('l','t','x','t'):
|
||||||
ltxt = malloc (sizeof (ltxt_t));
|
ltxt = calloc (1, sizeof (ltxt_t));
|
||||||
ltxt->ck = ck;
|
ltxt->ck = ck;
|
||||||
read_ltxt (f, ck.len, <xt->ltxt);
|
read_ltxt (f, ck.len, <xt->ltxt);
|
||||||
chunk = <xt->ck;
|
chunk = <xt->ck;
|
||||||
|
@ -111,7 +152,9 @@ read_adtl (dstring_t *list_buf, QFile *f, int len)
|
||||||
case CASE ('n','o','t','e'):
|
case CASE ('n','o','t','e'):
|
||||||
label = malloc (sizeof (label_t));
|
label = malloc (sizeof (label_t));
|
||||||
label->ck = ck;
|
label->ck = ck;
|
||||||
Qread (f, &label->ofs, 4);
|
if (!Rread (f, &label->ofs, 4)) {
|
||||||
|
label->ofs = 0;
|
||||||
|
}
|
||||||
label->label = read_string (f, ck.len - 4);
|
label->label = read_string (f, ck.len - 4);
|
||||||
chunk = &label->ck;
|
chunk = &label->ck;
|
||||||
break;
|
break;
|
||||||
|
@ -137,7 +180,6 @@ read_list (d_chunk_t *ck, QFile *f, int len)
|
||||||
d_chunk_t *chunk = 0;
|
d_chunk_t *chunk = 0;
|
||||||
dstring_t *list_buf;
|
dstring_t *list_buf;
|
||||||
list_t *list;
|
list_t *list;
|
||||||
int r;
|
|
||||||
|
|
||||||
list_buf = dstring_new ();
|
list_buf = dstring_new ();
|
||||||
list_buf->size = sizeof (list_t);
|
list_buf->size = sizeof (list_t);
|
||||||
|
@ -145,19 +187,24 @@ read_list (d_chunk_t *ck, QFile *f, int len)
|
||||||
list = (list_t *)list_buf->str;
|
list = (list_t *)list_buf->str;
|
||||||
list->ck = *ck;
|
list->ck = *ck;
|
||||||
|
|
||||||
len -= Qread (f, list->name, sizeof (list->name));
|
if (!Rread (f, list->name, sizeof (list->name))) {
|
||||||
while (len) {
|
dstring_delete (list_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
len -= sizeof (list->name);
|
||||||
|
while (len > 0) {
|
||||||
SWITCH (list->name) {
|
SWITCH (list->name) {
|
||||||
case CASE ('I','N','F','O'):
|
case CASE ('I','N','F','O'):
|
||||||
{
|
{
|
||||||
data_t *data = malloc (sizeof (data_t));
|
data_t *data = malloc (sizeof (data_t));
|
||||||
chunk = &data->ck;
|
if (!Rread (f, &data->ck, sizeof (data->ck))) {
|
||||||
r = Qread (f, &data->ck, sizeof (data->ck));
|
|
||||||
if (!r) {
|
|
||||||
len = 0;
|
len = 0;
|
||||||
|
free (data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len -= r;
|
chunk = &data->ck;
|
||||||
|
//printf ("%.4s %d\n", data->ck.name, data->ck.len);
|
||||||
|
len -= sizeof (data->ck);
|
||||||
SWITCH (data->ck.name) {
|
SWITCH (data->ck.name) {
|
||||||
case CASE ('I','C','R','D'):
|
case CASE ('I','C','R','D'):
|
||||||
case CASE ('I','S','F','T'):
|
case CASE ('I','S','F','T'):
|
||||||
|
@ -177,10 +224,13 @@ read_list (d_chunk_t *ck, QFile *f, int len)
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
data_t *data = malloc (sizeof (data_t));
|
data_t *data = malloc (sizeof (data_t));
|
||||||
Qread (f, &data->ck, sizeof (data->ck));
|
if (!Rread (f, &data->ck, sizeof (data->ck))) {
|
||||||
data->data = read_data (f, data->ck.len);
|
free (data);
|
||||||
len -= data->ck.len + sizeof (data->ck);
|
} else {
|
||||||
chunk = &data->ck;
|
data->data = read_data (f, data->ck.len);
|
||||||
|
len -= data->ck.len + sizeof (data->ck);
|
||||||
|
chunk = &data->ck;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
len = 0;
|
len = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -202,7 +252,10 @@ read_cue (QFile *f, int len)
|
||||||
{
|
{
|
||||||
d_cue_t *cue = malloc (len);
|
d_cue_t *cue = malloc (len);
|
||||||
|
|
||||||
Qread (f, cue, len);
|
if (!Rread (f, cue, len)) {
|
||||||
|
free (cue);
|
||||||
|
cue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return cue;
|
return cue;
|
||||||
}
|
}
|
||||||
|
@ -221,17 +274,28 @@ riff_read (QFile *f)
|
||||||
dstring_adjust (riff_buf);
|
dstring_adjust (riff_buf);
|
||||||
riff = (list_t *)riff_buf->str;
|
riff = (list_t *)riff_buf->str;
|
||||||
|
|
||||||
Qseek (f, 0, SEEK_END);
|
file_len = Qfilesize (f);
|
||||||
file_len = Qtell (f);
|
|
||||||
Qseek (f, 0, SEEK_SET);
|
|
||||||
|
|
||||||
Qread (f, &riff->ck, sizeof (riff->ck));
|
if (!Rread (f, &riff->ck, sizeof (riff->ck))) {
|
||||||
Qread (f, riff->name, sizeof (riff->name));
|
dstring_delete (riff_buf);
|
||||||
while (Qread (f, &ck, sizeof (ck))) {
|
return 0;
|
||||||
|
}
|
||||||
|
if (!Rread (f, riff->name, sizeof (riff->name))) {
|
||||||
|
dstring_delete (riff_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strncmp (riff->ck.name, "RIFF", 4) || strncmp (riff->name, "WAVE", 4)) {
|
||||||
|
dstring_delete (riff_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (Rread (f, &ck, sizeof (ck))) {
|
||||||
|
//printf ("%.4s %d\n", ck.name, ck.len);
|
||||||
if (ck.len < 0x80000000)
|
if (ck.len < 0x80000000)
|
||||||
len = ck.len;
|
len = ck.len;
|
||||||
else
|
else {
|
||||||
len = file_len - Qtell (f);
|
//puts ("bling");
|
||||||
|
ck.len = len = file_len - Qtell (f);
|
||||||
|
}
|
||||||
SWITCH (ck.name) {
|
SWITCH (ck.name) {
|
||||||
case CASE ('c','u','e',' '):
|
case CASE ('c','u','e',' '):
|
||||||
{
|
{
|
||||||
|
@ -267,6 +331,9 @@ riff_read (QFile *f)
|
||||||
return riff;
|
return riff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_adtl (d_chunk_t *adtl)
|
free_adtl (d_chunk_t *adtl)
|
||||||
{
|
{
|
||||||
|
@ -292,12 +359,14 @@ free_adtl (d_chunk_t *adtl)
|
||||||
case CASE ('n','o','t','e'):
|
case CASE ('n','o','t','e'):
|
||||||
label = (label_t *) adtl;
|
label = (label_t *) adtl;
|
||||||
//printf (" %-8d %s\n", label->ofs, label->label);
|
//printf (" %-8d %s\n", label->ofs, label->label);
|
||||||
free (label->label);
|
if (label->label)
|
||||||
|
free (label->label);
|
||||||
free (label);
|
free (label);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
data = (data_t *) adtl;
|
data = (data_t *) adtl;
|
||||||
free (data->data);
|
if (data->data)
|
||||||
|
free (data->data);
|
||||||
free (data);
|
free (data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +389,8 @@ free_list (list_t *list)
|
||||||
case CASE ('I','S','F','T'):
|
case CASE ('I','S','F','T'):
|
||||||
//printf (" %s\n", data->data);
|
//printf (" %s\n", data->data);
|
||||||
default:
|
default:
|
||||||
free (data->data);
|
if (data->data)
|
||||||
|
free (data->data);
|
||||||
free (data);
|
free (data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +400,8 @@ free_list (list_t *list)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
data = (data_t *) *ck;
|
data = (data_t *) *ck;
|
||||||
free (data->data);
|
if (data->data)
|
||||||
|
free (data->data);
|
||||||
free (data);
|
free (data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -351,8 +422,8 @@ riff_free (list_t *riff)
|
||||||
SWITCH ((*ck)->name) {
|
SWITCH ((*ck)->name) {
|
||||||
case CASE ('c','u','e',' '):
|
case CASE ('c','u','e',' '):
|
||||||
cue = (cue_t *) *ck;
|
cue = (cue_t *) *ck;
|
||||||
/*{
|
if (cue->cue) {
|
||||||
int i;
|
/*int i;
|
||||||
for (i = 0; i < cue->cue->count; i++) {
|
for (i = 0; i < cue->cue->count; i++) {
|
||||||
printf (" %08x %d %.4s %d %d %d\n",
|
printf (" %08x %d %.4s %d %d %d\n",
|
||||||
cue->cue->cue_points[i].name,
|
cue->cue->cue_points[i].name,
|
||||||
|
@ -361,9 +432,9 @@ riff_free (list_t *riff)
|
||||||
cue->cue->cue_points[i].chunk_start,
|
cue->cue->cue_points[i].chunk_start,
|
||||||
cue->cue->cue_points[i].block_start,
|
cue->cue->cue_points[i].block_start,
|
||||||
cue->cue->cue_points[i].sample_offset);
|
cue->cue->cue_points[i].sample_offset);
|
||||||
}
|
}*/
|
||||||
}*/
|
free (cue->cue);
|
||||||
free (cue->cue);
|
}
|
||||||
free (cue);
|
free (cue);
|
||||||
break;
|
break;
|
||||||
case CASE ('L','I','S','T'):
|
case CASE ('L','I','S','T'):
|
||||||
|
@ -372,7 +443,8 @@ riff_free (list_t *riff)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
data = (data_t *) *ck;
|
data = (data_t *) *ck;
|
||||||
free (data->data);
|
if (data->data)
|
||||||
|
free (data->data);
|
||||||
free (data);
|
free (data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue