]> git.draconx.ca Git - upkg.git/commitdiff
engine: Implement Engine.Sound.
authorNick Bowler <nbowler@draconx.ca>
Sun, 20 May 2012 04:11:52 +0000 (00:11 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sun, 20 May 2012 04:11:52 +0000 (00:11 -0400)
This one's pretty trivial; but now we can export sounds.

MMM-M-M-M-M-MONSTER KILL!

Makefile.am
src/engine/.gitignore
src/engine/engine.c
src/engine/sound.gob [new file with mode: 0644]

index fda499306f5a1d7c4b7fddd0a365e98148e8f2e8..1fc339f14f00bc238af3d8ceb6cb82270a84b527 100644 (file)
@@ -56,7 +56,7 @@ $(libuobject_la): $(LTDLDEPS)
 moduleflags = -module -avoid-version -export-symbols-regex _LTX_
 
 engine_GOBS = src/engine/palette.gob src/engine/texture.gob \
-       src/engine/music.gob
+       src/engine/music.gob src/engine/sound.gob
 
 MAINTAINERCLEANFILES += $(engine_GOBS:.gob=.gobstamp) \
        $(engine_GOBS:.gob=.c) $(engine_GOBS:.gob=.h)
index 85b58305ff08a8c903a7c410ee36987193706f72..5b468a1844a4a5461f0088ab6d61b7ea38aeb68e 100644 (file)
@@ -1,3 +1,4 @@
 palette.[ch]
 texture.[ch]
+sound.[ch]
 music.[ch]
index 3bf27e7f9df7024a963c51e3c34cf2b74af7127d..92cc0c3d17277921877de39c8785cd92a4631089 100644 (file)
@@ -22,6 +22,7 @@
 #include <engine/music.h>
 #include <engine/texture.h>
 #include <engine/palette.h>
+#include <engine/sound.h>
 
 #define init engine_LTX_init
 #define exit engine_LTX_exit
@@ -29,6 +30,7 @@
 int init(GTypeModule *m)
 {
        engine_music_register_type(m);
+       engine_sound_register_type(m);
        engine_texture_register_type(m);
        engine_palette_register_type(m);
        return 0;
diff --git a/src/engine/sound.gob b/src/engine/sound.gob
new file mode 100644 (file)
index 0000000..fd0a060
--- /dev/null
@@ -0,0 +1,117 @@
+%alltop{
+/*
+ *  upkg: tool for manipulating Unreal Tournament packages.
+ *  Copyright © 2011 Nick Bowler
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+%}
+
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <uobject/exportable.h>
+#include "pack.h"
+%}
+
+%h{
+#include <uobject/uobject.h>
+%}
+
+class Engine:Sound from U:Object (dynamic)
+       (interface U:Object:Exportable)
+{
+       interface U:Object:Exportable
+       private int export(U:Object *uo, FILE *outf)
+       {
+               struct upkg_file *f = uo->pkg_file;
+               unsigned char buf[1024];
+               size_t buflen;
+
+               if (upkg_export_seek(f, 0, SEEK_SET) != 0)
+                       return -1;
+
+               do {
+                       buflen = upkg_export_read(f, buf, sizeof buf);
+                       if (fwrite(buf, buflen, 1, outf) != 1)
+                               return -1;
+               } while (buflen == sizeof buf);
+
+               if (!f->eof)
+                       return -1;
+               return 0;
+       }
+
+       interface U:Object:Exportable
+       private int export_name(U:Object *uo, char *buf, size_t n)
+       {
+               return snprintf(buf, n, "%s.wav", uo->pkg_file->name);
+       }
+
+       override (U:Object) int deserialize(U:Object *uo)
+       {
+               struct upkg_file *f = uo->pkg_file;
+               size_t rc, pos = 0, buflen;
+               unsigned char buf[32];
+               unsigned long end_offset;
+               const char *fmt_name;
+               long size, fmt;
+
+               PARENT_HANDLER(uo);
+
+               buflen = upkg_export_read(f, buf, sizeof buf);
+
+               /* This seems to be the name of the format.  The only format
+                * that actually gets used is WAV, so we can check that. */
+               rc = upkg_decode_index(&fmt, buf+pos, buflen-pos);
+               if (rc == 0)
+                       return -1;
+               pos += rc;
+
+               fmt_name = upkg_get_name(f->pkg, fmt);
+               if (!fmt_name || strcasecmp(fmt_name, "wav") != 0) {
+                       u_err(uo, "format name is not WAV");
+                       return -1;
+               }
+
+               /* Like textures, there's an (apparently useless) offset to
+                * the end of the sound data which is implied by the next
+                * field.  Just validate it. */
+               if (f->pkg->version >= 63) {
+                       if (pos + 4 > buflen)
+                               return -1;
+                       end_offset = unpack_32_le(buf+pos);
+                       pos += 4;
+               }
+
+               rc = upkg_decode_index(&size, buf+pos, buflen-pos);
+               if (rc == 0 || size < 0 || size > f->len - pos)
+                       return -1;
+               pos += rc;
+
+               f->base += pos;
+               f->len   = size;
+               upkg_export_seek(f, 0, SEEK_SET);
+
+               if (f->pkg->version >= 63) {
+                       if (end_offset != f->base + f->len) {
+                               u_err(uo, "end offset does not match size");
+                               return -1;
+                       }
+               }
+
+               return 0;
+       }
+}