X-Git-Url: http://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/ca8ee16cfde42ea27d40f8e45fa6d96dc24cd5d9..3d673858df99c9ff1a10eb14ca57f8447923b094:/src/engine/music.c
diff --git a/src/engine/music.c b/src/engine/music.c
index f770662..8c17f9d 100644
--- a/src/engine/music.c
+++ b/src/engine/music.c
@@ -1,10 +1,29 @@
+/*
+ * upkg: tool for manipulating Unreal Tournament packages.
+ * Copyright (C) 2009 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 .
+ */
+
#include
#include
#include
-#include "exportable.h"
-#include "loadable.h"
-#include "uobject.h"
+#include
+#include
+#include
+#include "music-module.h"
#include "music.h"
#include "upkg.h"
@@ -12,7 +31,7 @@
G_TYPE_INSTANCE_GET_PRIVATE(o, ENGINE_MUSIC_TYPE, struct music_priv)
struct music_priv {
- struct upkg_file *f;
+ struct music_mod *mod;
unsigned loaded;
};
@@ -27,11 +46,17 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED(EngineMusic, engine_music, U_OBJECT_TYPE, 0,
static int load(GObject *o)
{
struct music_priv *priv = MUSIC_GET_PRIV(o);
+ struct upkg_file *f = U_OBJECT(o)->pkg_file;
if (!priv->loaded) {
- g_return_val_if_fail(priv->f != NULL, -1);
+ g_return_val_if_fail(f != NULL, -1);
- if (upkg_export_seek(priv->f, 0, SEEK_SET) != 0) {
+ if (upkg_export_seek(f, 0, SEEK_SET) != 0) {
+ return -1;
+ }
+
+ priv->mod = music_mod_open(f);
+ if (!priv->mod) {
return -1;
}
}
@@ -45,35 +70,43 @@ static void unload(GObject *o)
struct music_priv *priv = MUSIC_GET_PRIV(o);
g_return_if_fail(priv->loaded > 0);
- --priv->loaded;
+ if (--priv->loaded == 0) {
+ music_mod_close(priv->mod);
+ }
}
static int export(GObject *o, FILE *f)
{
struct music_priv *priv = MUSIC_GET_PRIV(o);
- unsigned char buf[1024];
+ int rc;
- if (!priv->f || upkg_export_seek(priv->f, 0, SEEK_SET) != 0)
+ if (load(o) != 0)
return -1;
- while (!priv->f->eof) {
- size_t rc = upkg_export_read(priv->f, buf, sizeof buf);
- if (rc == 0) {
- if (priv->f->eof) break;
- return -1;
- }
+ rc = music_mod_dump(priv->mod, f);
- if (fwrite(buf, 1, rc, f) != rc)
- return -1;
- }
+ unload(o);
- return 0;
+ return rc;
}
static int export_name(GObject *o, char *buf, size_t n)
{
struct music_priv *priv = MUSIC_GET_PRIV(o);
- return snprintf(buf, n, "%s", priv->f ? priv->f->name : "");
+ const char *type;
+ int rc;
+
+ if (load(o) != 0) {
+ if (n > 0) *buf = 0;
+ return 0;
+ }
+
+ type = music_mod_type(priv->mod);
+ rc = snprintf(buf, n, "%s.%s", U_OBJECT(o)->pkg_file->name, type);
+
+ unload(o);
+
+ return rc;
}
static void exportable_init(UObjectExportable *e)
@@ -88,15 +121,15 @@ static void loadable_init(UObjectLoadable *l)
l->unload = unload;
}
-static int deserialize(UObject *o, struct upkg_file *f)
+static int deserialize(UObject *uo)
{
- struct music_priv *priv = MUSIC_GET_PRIV(o);
- EngineMusic *m = ENGINE_MUSIC(o);
+ struct music_priv *priv = MUSIC_GET_PRIV(uo);
+ struct upkg_file *f = uo->pkg_file;
size_t rc, pos = 0, buflen;
unsigned char buf[32];
long size;
- U_OBJECT_CLASS(engine_music_parent_class)->deserialize(o, f);
+ U_OBJECT_CLASS(engine_music_parent_class)->deserialize(uo);
buflen = upkg_export_read(f, buf, sizeof buf);
@@ -121,8 +154,6 @@ static int deserialize(UObject *o, struct upkg_file *f)
f->len = size;
upkg_export_seek(f, 0, SEEK_SET);
- priv->f = f;
-
return 0;
}
@@ -145,6 +176,8 @@ static void engine_music_finalize(GObject *o)
priv->loaded = 1;
unload(o);
}
+
+ G_OBJECT_CLASS(engine_music_parent_class)->finalize(o);
}
static void engine_music_class_init(EngineMusicClass *class)
@@ -155,8 +188,11 @@ static void engine_music_class_init(EngineMusicClass *class)
uo->deserialize = deserialize;
go->finalize = engine_music_finalize;
+
+ music_mod_init();
}
static void engine_music_class_finalize(EngineMusicClass *class)
{
+ music_mod_exit();
}