2 * upkg: tool for manipulating Unreal Tournament packages.
3 * Copyright © 2009-2011 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <glib-object.h>
23 #include <uobject/uobject.h>
24 #include <uobject/exportable.h>
25 #include <uobject/loadable.h>
26 #include <engine/music.h>
27 #include "music-module.h"
30 #define MUSIC_GET_PRIV(o) \
31 G_TYPE_INSTANCE_GET_PRIVATE(o, ENGINE_MUSIC_TYPE, struct music_priv)
34 struct music_mod *mod;
38 static void exportable_init(UObjectExportableIface *);
39 static void loadable_init(UObjectLoadableIface *);
41 G_DEFINE_DYNAMIC_TYPE_EXTENDED(EngineMusic, engine_music, U_TYPE_OBJECT, 0,
42 G_IMPLEMENT_INTERFACE(U_TYPE_OBJECT_EXPORTABLE, exportable_init)
43 G_IMPLEMENT_INTERFACE(U_TYPE_OBJECT_LOADABLE, loadable_init)
46 static int load(GObject *o)
48 struct music_priv *priv = MUSIC_GET_PRIV(o);
49 struct upkg_file *f = U_OBJECT(o)->pkg_file;
52 g_return_val_if_fail(f != NULL, -1);
54 if (upkg_export_seek(f, 0, SEEK_SET) != 0) {
58 priv->mod = music_mod_open(f);
68 static void unload(GObject *o)
70 struct music_priv *priv = MUSIC_GET_PRIV(o);
71 g_return_if_fail(priv->loaded > 0);
73 if (--priv->loaded == 0) {
74 music_mod_close(priv->mod);
78 static int export(GObject *o, FILE *f)
80 struct music_priv *priv = MUSIC_GET_PRIV(o);
86 rc = music_mod_dump(priv->mod, f);
93 static int export_name(GObject *o, char *buf, size_t n)
95 struct music_priv *priv = MUSIC_GET_PRIV(o);
104 type = music_mod_type(priv->mod);
105 rc = snprintf(buf, n, "%s.%s", U_OBJECT(o)->pkg_file->name, type);
112 static void exportable_init(UObjectExportableIface *e)
115 e->export_name = export_name;
118 static void loadable_init(UObjectLoadableIface *l)
124 static int deserialize(UObject *uo)
126 struct music_priv *priv = MUSIC_GET_PRIV(uo);
127 struct upkg_file *f = uo->pkg_file;
128 size_t rc, pos = 0, buflen;
129 unsigned char buf[32];
132 U_OBJECT_CLASS(engine_music_parent_class)->deserialize(uo);
134 buflen = upkg_export_read(f, buf, sizeof buf);
136 /* Random field #1 */
137 if (buflen - pos < 1)
141 if (uo->pkg->version > 61) {
142 /* Random field #2 */
143 if (buflen - pos < 4)
148 rc = upkg_decode_index(&size, buf+pos, buflen-pos);
149 if (rc == 0 || size < 0)
155 upkg_export_seek(f, 0, SEEK_SET);
160 void music_register(GTypeModule *m)
162 engine_music_register_type(m);
165 static void engine_music_init(EngineMusic *m)
167 struct music_priv *priv = MUSIC_GET_PRIV(m);
168 *priv = (struct music_priv){0};
171 static void engine_music_finalize(GObject *o)
173 struct music_priv *priv = MUSIC_GET_PRIV(o);
175 if (priv->loaded >= 1) {
180 G_OBJECT_CLASS(engine_music_parent_class)->finalize(o);
183 static void engine_music_class_init(EngineMusicClass *class)
185 UObjectClass *uo = U_OBJECT_CLASS(class);
186 GObjectClass *go = G_OBJECT_CLASS(class);
187 g_type_class_add_private(class, sizeof (struct music_priv));
189 uo->deserialize = deserialize;
190 go->finalize = engine_music_finalize;
195 static void engine_music_class_finalize(EngineMusicClass *class)