3 * upkg: tool for manipulating Unreal Tournament packages.
4 * Copyright © 2011 Nick Bowler
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <uobject/exportable.h>
30 #include <uobject/uobject.h>
33 class Engine:Sound from U:Object (dynamic)
34 (interface U:Object:Exportable)
36 interface U:Object:Exportable
37 private int export(U:Object *uo, FILE *outf)
39 struct upkg_file *f = uo->pkg_file;
40 unsigned char buf[1024];
43 if (upkg_export_seek(f, 0, SEEK_SET) != 0)
47 buflen = upkg_export_read(f, buf, sizeof buf);
48 if (fwrite(buf, buflen, 1, outf) != 1)
50 } while (buflen == sizeof buf);
57 interface U:Object:Exportable
58 private int export_name(U:Object *uo, char *buf, size_t n)
60 return snprintf(buf, n, "%s.wav", uo->pkg_file->name);
63 override (U:Object) int deserialize(U:Object *uo)
65 struct upkg_file *f = uo->pkg_file;
66 size_t rc, pos = 0, buflen;
67 unsigned char buf[32];
68 unsigned long end_offset;
74 buflen = upkg_export_read(f, buf, sizeof buf);
76 /* This seems to be the name of the format. The only format
77 * that actually gets used is WAV, so we can check that. */
78 rc = upkg_decode_index(&fmt, buf+pos, buflen-pos);
83 fmt_name = upkg_get_name(f->pkg, fmt);
84 if (!fmt_name || strcasecmp(fmt_name, "wav") != 0) {
85 u_err(uo, "format name is not WAV");
89 /* Like textures, there's an (apparently useless) offset to
90 * the end of the sound data which is implied by the next
91 * field. Just validate it. */
92 if (f->pkg->version >= 63) {
95 end_offset = unpack_32_le(buf+pos);
99 rc = upkg_decode_index(&size, buf+pos, buflen-pos);
100 if (rc == 0 || size < 0 || size > f->len - pos)
106 upkg_export_seek(f, 0, SEEK_SET);
108 if (f->pkg->version >= 63) {
109 if (end_offset != f->base + f->len) {
110 u_err(uo, "end offset does not match size");