X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Fbocfel%2Fblorb.c;fp=interpreters%2Fbocfel%2Fblorb.c;h=456e97655af0c2deb4a09154e5035a1f03be3b86;hb=3c59ba5eef5cb4d39c06eb7f523b9c3b026bdc9b;hp=0000000000000000000000000000000000000000;hpb=ed91d840318ed6ebfe3a5a77fa17114ddbf56640;p=projects%2Fchimara%2Fchimara.git
diff --git a/interpreters/bocfel/blorb.c b/interpreters/bocfel/blorb.c
new file mode 100644
index 0000000..456e976
--- /dev/null
+++ b/interpreters/bocfel/blorb.c
@@ -0,0 +1,121 @@
+/*-
+ * Copyright 2010-2012 Chris Spiegel.
+ *
+ * This file is part of Bocfel.
+ *
+ * Bocfel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version
+ * 2 or 3, as published by the Free Software Foundation.
+ *
+ * Bocfel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Bocfel. If not, see .
+ */
+
+#include
+#include
+#include
+
+#include "blorb.h"
+#include "iff.h"
+#include "io.h"
+
+struct zterp_blorb
+{
+ struct zterp_io *io;
+ struct zterp_iff *iff;
+
+ size_t nchunks;
+ zterp_blorb_chunk *chunks;
+};
+
+struct zterp_blorb *zterp_blorb_parse(zterp_io *io)
+{
+ uint32_t size;
+ uint32_t nresources;
+ zterp_iff *iff;
+ struct zterp_blorb *blorb = NULL;
+
+ iff = zterp_iff_parse(io, "IFRS");
+ if(!zterp_iff_find(iff, "RIdx", &size)) goto err;
+ zterp_iff_free(iff);
+
+ if(!zterp_io_read32(io, &nresources)) goto err;
+
+ if((nresources * 12) + 4 != size) goto err;
+
+ blorb = malloc(sizeof *blorb);
+ if(blorb == NULL) goto err;
+
+ blorb->io = io;
+ blorb->nchunks = 0;
+ blorb->chunks = NULL;
+
+ for(uint32_t i = 0; i < nresources; i++)
+ {
+ uint32_t usage, number, start, type;
+ zterp_blorb_chunk *new;
+ long saved;
+ uint32_t idx;
+
+ if(!zterp_io_read32(io, &usage) || !zterp_io_read32(io, &number) || !zterp_io_read32(io, &start)) goto err;
+
+ if(usage != BLORB_PICT && usage != BLORB_SND && usage != BLORB_EXEC) goto err;
+
+ saved = zterp_io_tell(io);
+ if(saved == -1) goto err;
+
+ if(zterp_io_seek(io, start, SEEK_SET) == -1) goto err;
+
+ if(!zterp_io_read32(io, &type) || !zterp_io_read32(io, &size)) goto err;
+
+ if(zterp_io_seek(io, saved, SEEK_SET) == -1) goto err;
+
+ if(type == STRID("FORM"))
+ {
+ start -= 8;
+ size += 8;
+ }
+
+ /* Not really efficient, but does it matter? */
+ new = realloc(blorb->chunks, sizeof *new * ++blorb->nchunks);
+ if(new == NULL) goto err;
+ blorb->chunks = new;
+
+ idx = blorb->nchunks - 1;
+
+ new[idx].usage = usage;
+ new[idx].number = number;
+ new[idx].type = type;
+ memcpy(new[idx].name, IDSTR(type), 5);
+ new[idx].offset = start + 8;
+ new[idx].size = size;
+ }
+
+ return blorb;
+
+err:
+ zterp_blorb_free(blorb);
+
+ return NULL;
+}
+
+void zterp_blorb_free(struct zterp_blorb *blorb)
+{
+ if(blorb != NULL) free(blorb->chunks);
+ free(blorb);
+}
+
+const zterp_blorb_chunk *zterp_blorb_find(struct zterp_blorb *blorb, uint32_t usage, int number)
+{
+ for(size_t i = 0; i < blorb->nchunks; i++)
+ {
+ if(blorb->chunks[i].usage == usage && blorb->chunks[i].number == number) return &blorb->chunks[i];
+ }
+
+ return NULL;
+}