/* * upkg: tool for manipulating Unreal Tournament packages. * Copyright © 2009-2011, 2019 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 "modplug-types.h" #include "music-module.h" #include "upkg.h" struct music_mod { ModPlugFile *f; size_t len, alloc; unsigned char buf[]; }; #define BUF_INIT_SIZE 65536 int music_mod_init(void) { ModPlug_Settings settings = { .mFlags = MODPLUG_ENABLE_OVERSAMPLING, .mChannels = 2, .mFrequency = 44100, .mResamplingMode = MODPLUG_RESAMPLE_SPLINE, .mLoopCount = -1, }; ModPlug_SetSettings(&settings); return 0; } void music_mod_exit(void) { } static struct music_mod *readfile(struct upkg_file *f) { struct music_mod *m = malloc(sizeof *m + BUF_INIT_SIZE); if (!m) return NULL; *m = (struct music_mod) { .alloc = BUF_INIT_SIZE }; while (1) { struct music_mod *tmp; size_t sz = m->alloc - m->len; m->len += upkg_export_read(f, m->buf + m->len, sz); if (m->alloc != m->len) { if (f->eof) { tmp = realloc(m, sizeof *m + m->len); return tmp ? tmp : m; } break; } tmp = realloc(m, sizeof *m + 2*m->alloc); if (!tmp) break; m = tmp; m->alloc *= 2; } free(m); return NULL; } struct music_mod *music_mod_open(struct upkg_file *f) { struct music_mod *m = readfile(f); if (!m) return NULL; m->f = ModPlug_Load(m->buf, m->len); if (!m->f) { free(m); return NULL; } return m; } int music_mod_dump(struct music_mod *m, FILE *of) { if (fwrite(m->buf, m->len, 1, of) != 1) return -1; return 0; } void music_mod_close(struct music_mod *m) { ModPlug_Unload(m->f); free(m); } const char *music_mod_type(struct music_mod *m) { int type = ModPlug_GetModuleType(m->f); if (type & MOD_TYPE_MOD) return "mod"; if (type & MOD_TYPE_S3M) return "s3m"; if (type & MOD_TYPE_XM) return "xm"; if (type & MOD_TYPE_IT) return "it"; return "unknown"; }