Mercurial > hg > dmlib
view dmtimelinew.c @ 510:43ea59887c69
Start work on making C64 formats encoding possible by changing DMDecodeOps
to DMEncDecOps and adding fields and op enums for custom encode functions, renaming,
etc. Split generic op sanity checking into a separate function in
preparation for its use in generic encoding function.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 19 Nov 2012 15:06:01 +0200 |
parents | 0f290af63fc1 |
children | d4b84101e480 |
line wrap: on
line source
#include "dmengine.h" #include "dmresw.h" static BOOL dmSaveFloatValue(DMResource *res, DMFloat val) { char tmp[DT_FLOAT_STORE_SIZE]; snprintf(tmp, DT_FLOAT_STORE_SIZE, "%f", val); return !dmf_write_str(res, (Uint8 *) tmp, DT_FLOAT_STORE_SIZE); } static int dmSaveTimelinePoints(DMResource *res, DMTimelinePoints *points, int type) { int point; Uint32 npoints; // Save number of points npoints = points->npoints; if (!dmf_write_le32(res, npoints)) return DMERR_FWRITE; // Save points for (point = 0; point < points->npoints; point++) { DMTimelinePoint *pt = &(points->points[point]); Uint32 ptype, ptime; ptype = pt->type; ptime = pt->time; if (!dmf_write_le32(res, ptype) || !dmf_write_le32(res, ptime)) return DMERR_FWRITE; switch (type) { case EFPT_INT: if (!dmf_write_le32(res, pt->vint)) return DMERR_FWRITE; break; case EFPT_FLOAT: if (!dmSaveFloatValue(res, pt->vfloat)) return DMERR_FWRITE; break; case EFPT_VECTOR: if (!dmSaveFloatValue(res, pt->vector.x) || !dmSaveFloatValue(res, pt->vector.y) || !dmSaveFloatValue(res, pt->vector.z) || !dmSaveFloatValue(res, pt->vector.W)) return DMERR_FWRITE; break; case EFPT_MATRIX: { int x, y; for (y = 0; y < DM_MATRIX_SIZE; y++) for (x = 0; x < DM_MATRIX_SIZE; x++) { if (!dmSaveFloatValue(res, pt->matrix.m[y][x])) return DMERR_FWRITE; } } break; } } return DMERR_OK; } static int dmSaveTimelineCurve(DMResource *res, DMTimelineCurve *curve) { int err; dmfputc(curve->enabled, res); if ((err = dmSaveTimelinePoints(res, &(curve->points), EFPT_FLOAT)) != DMERR_OK) return err; return DMERR_OK; } static int dmSaveTimelineEventParam(DMResource *res, DMTimelineEventParam *param) { int err; DMFTimelineEventParam hdr; Uint16 len; strncpy(hdr.name, param->name, sizeof(hdr.name)); hdr.type = param->type; if (!dmf_write_str(res, (Uint8 *) hdr.name, sizeof(hdr.name)) || !dmf_write_le32(res, hdr.type)) return DMERR_FWRITE; switch (param->type) { case EFPT_INT: case EFPT_FLOAT: case EFPT_VECTOR: case EFPT_MATRIX: if ((err = dmSaveTimelinePoints(res, ¶m->pts, param->type)) != DMERR_OK) return err; break; case EFPT_STRING: len = strlen(param->vstr); if (!dmf_write_le16(res, len)) return DMERR_FWRITE; if (!dmf_write_str(res, (Uint8 *) param->vstr, len)) return DMERR_FWRITE; break; } return DMERR_OK; } static int dmSaveTimelineEvent(DMResource *res, DMTimelineEvent *event) { int param, err; DMFTimelineEvent hdr; strncpy(hdr.effectName, event->effect->name, sizeof(hdr.effectName)); hdr.start = event->start; hdr.duration = event->duration; hdr.nparams = event->nparams; if (!dmf_write_le32(res, hdr.start) || !dmf_write_le32(res, hdr.duration) || !dmf_write_str(res, (Uint8 *) hdr.effectName, sizeof(hdr.effectName)) || !dmf_write_le32(res, hdr.nparams)) return DMERR_FWRITE; for (param = 0; param < event->nparams; param++) { if ((err = dmSaveTimelineEventParam(res, &(event->params[param]))) != DMERR_OK) return err; } return DMERR_OK; } static int dmSaveTimelineTrack(DMResource *res, DMTimelineTrack *track) { int event, err; DMFTimelineTrack hdr; strncpy(hdr.name, track->name, sizeof(hdr.name)); hdr.enabled = track->enabled; hdr.nevents = track->nevents; if (!dmf_write_str(res, (Uint8 *) &hdr.name, sizeof(hdr.name))) return DMERR_FWRITE; dmfputc(hdr.enabled, res); if (!dmf_write_le32(res, hdr.nevents)) return DMERR_FWRITE; for (event = 0; event < track->nevents; event++) { if ((err = dmSaveTimelineEvent(res, track->events[event])) != DMERR_OK) return err; } if ((err = dmSaveTimelineCurve(res, &(track->composite))) != DMERR_OK) return err; return DMERR_OK; } int dmSaveTimeline(DMResource *res, DMTimeline *tl) { int track, err; DMFTimeline hdr; memcpy(&hdr.magic, DT_MAGIC_ID, sizeof(hdr.magic)); strncpy(hdr.name, tl->name, sizeof(hdr.name)); hdr.ntracks = tl->ntracks; hdr.duration = tl->duration; if (!dmf_write_str(res, (Uint8 *) hdr.magic, sizeof(hdr.magic)) || !dmf_write_str(res, (Uint8 *) hdr.name, sizeof(hdr.name)) || !dmf_write_le32(res, hdr.ntracks) || !dmf_write_le32(res, hdr.duration)) return DMERR_FWRITE; for (track = 0; track < tl->ntracks; track++) { if ((err = dmSaveTimelineTrack(res, tl->tracks[track])) != DMERR_OK) return err; } return DMERR_OK; } int dmTimelineNew(DMTimeline **ptl, const char *name) { DMTimeline *tl; if ((*ptl = tl = dmMalloc0(sizeof(DMTimeline))) == NULL) return DMERR_MALLOC; tl->name = dm_strdup(name); return DMERR_OK; } int dmTimelineAddTrack(DMTimeline *tl, DMTimelineTrack **ptrack, const char *name) { DMTimelineTrack *track; if ((*ptrack = track = dmMalloc0(sizeof(DMTimelineTrack))) == NULL) return DMERR_MALLOC; track->name = dm_strdup(name); track->enabled = TRUE; if (tl->ntracks + 1 >= tl->nallocated) { tl->nallocated += 16; tl->tracks = dmRealloc(tl->tracks, sizeof(DMTimelineTrack *) * tl->nallocated); if (tl->tracks == NULL) return DMERR_MALLOC; } tl->tracks[tl->ntracks] = track; tl->ntracks++; return DMERR_OK; } int dmTimelineTrackAddEvent(DMTimelineTrack *track, int start, int duration, DMTimelineEvent **pev) { DMTimelineEvent *ev; if ((*pev = ev = dmMalloc0(sizeof(DMTimelineEvent))) == NULL) return DMERR_MALLOC; ev->start = start; ev->duration = duration; if (track->nevents + 1 >= track->nallocated) { track->nallocated += 16; track->events = dmRealloc(track->events, sizeof(DMTimelineEvent *) * track->nallocated); if (track->events == NULL) return DMERR_MALLOC; } track->events[track->nevents] = ev; track->nevents++; return DMERR_OK; } int dmTimelineEventSetEffect(DMTimelineEvent *event, DMEffect *ef) { int param; if (ef == NULL) return DMERR_INVALID_DATA; event->effect = ef; event->nparams = ef->nparams; event->params = dmCalloc(ef->nparams, sizeof(DMTimelineEventParam)); if (event->params == NULL) return DMERR_MALLOC; for (param = 0; param < ef->nparams; param++) { DMTimelineEventParam *psrc = &ef->params[param], *pdst = &event->params[param]; pdst->name = dm_strdup(psrc->name); pdst->type = psrc->type; pdst->vstr = dm_strdup(psrc->vstr); if (psrc->pts.points != NULL && psrc->pts.npoints > 0) { pdst->pts.npoints = psrc->pts.npoints; pdst->pts.nallocated = psrc->pts.nallocated; pdst->pts.points = dmMalloc(psrc->pts.nallocated * sizeof(DMTimelinePoint)); if (pdst->pts.points == NULL) return DMERR_MALLOC; memcpy(pdst->pts.points, psrc->pts.points, pdst->pts.npoints * sizeof(DMTimelinePoint)); } } return DMERR_OK; } int dmTimelineEventSetEffectByIndex(DMTimelineEvent *event, const int index) { if (index < 0 || index >= nengineEffects) return DMERR_INVALID_DATA; return dmTimelineEventSetEffect(event, &engineEffects[index]); } int dmTimelineEventSetEffectByName(DMTimelineEvent *event, const char *name) { return dmTimelineEventSetEffect(event, engineFindEffectByName(name)); } DMTimelineEvent *dmTimelineGetEventAt(DMTimelineTrack *track, const int time) { int event; for (event = 0; event < track->nevents; event++) { DMTimelineEvent *ev = track->events[event]; if (time >= ev->start && time <= ev->start + ev->duration) return ev; } return NULL; } int dmCopyTimelinePoints(const DMTimelinePoints *src, DMTimelinePoints *dst) { if (src->points == NULL || src->npoints <= 0 || src->nallocated <= 0) return DMERR_OK; dst->npoints = src->npoints; dst->nallocated = src->nallocated; dst->points = dmCalloc(src->nallocated, sizeof(DMTimelinePoint)); if (dst->points == NULL) return DMERR_MALLOC; memcpy(dst->points, src->points, sizeof(DMTimelinePoint) * src->npoints); return DMERR_OK; } int dmCopyTimelineEventParam(const DMTimelineEventParam *src, DMTimelineEventParam *dst) { dst->name = dm_strdup(src->name); dst->type = src->type; dst->vstr = dm_strdup(src->vstr); return dmCopyTimelinePoints(&src->pts, &dst->pts); } int dmCopyTimelineEvent(const DMTimelineEvent *src, DMTimelineEvent **pdst) { int param; DMTimelineEvent *dst; if ((*pdst = dst = dmMalloc0(sizeof(DMTimelineEvent))) == NULL) return DMERR_MALLOC; dst->start = src->start; dst->duration = src->duration; dst->nparams = src->nparams; dst->effect = src->effect; dst->params = dmCalloc(src->nparams, sizeof(DMTimelineEventParam)); if (dst->params == NULL) return DMERR_MALLOC; for (param = 0; param < src->nparams; param++) { int err; if ((err = dmCopyTimelineEventParam(&(src->params[param]), &(dst->params[param]))) != DMERR_OK) return err; } return DMERR_OK; } int dmCopyTimelineCurve(const DMTimelineCurve *src, DMTimelineCurve *dst) { dst->enabled = src->enabled; return dmCopyTimelinePoints(&(src->points), &(dst->points)); } int dmCopyTimelineTrack(const DMTimelineTrack *src, DMTimelineTrack **pdst) { int event, err; DMTimelineTrack *dst; if ((*pdst = dst = dmMalloc0(sizeof(DMTimelineTrack))) == NULL) return DMERR_MALLOC; if ((dst->events = dmCalloc(src->nevents, sizeof(DMTimelineEvent *))) == NULL) return DMERR_MALLOC; dst->name = dm_strdup(src->name); dst->enabled = src->enabled; dst->nevents = src->nevents; for (event = 0; event < src->nevents; event++) { if ((err = dmCopyTimelineEvent(src->events[event], &(dst->events[event]))) != DMERR_OK) return err; } if ((err = dmCopyTimelineCurve(&(src->composite), &(dst->composite))) != DMERR_OK) return err; return DMERR_OK; } int dmCopyTimeline(const DMTimeline *src, DMTimeline **pdst) { int track, err; DMTimeline *dst; if ((*pdst = dst = dmMalloc0(sizeof(DMTimeline))) == NULL) return DMERR_MALLOC; dst->tracks = (DMTimelineTrack **) dmCalloc(src->ntracks, sizeof(DMTimelineTrack *)); if (dst->tracks == NULL) return DMERR_MALLOC; dst->name = dm_strdup(src->name); dst->duration = src->duration; dst->ntracks = src->ntracks; for (track = 0; track < src->ntracks; track++) { if ((err = dmCopyTimelineTrack(src->tracks[track], &(dst->tracks[track]))) != DMERR_OK) return err; } return DMERR_OK; }