CMathODE *SpanNew() { CMathODE *ode = ODENew(0, 1e-4, ODEF_HAS_MASSES | ODEF_PAUSED); ode->derive = &MyDerivative; ode->drag_v2 = 0.002; ode->drag_v3 = 0.00001; ode->acceleration_limit = 5e3; QueueInsert(ode, Fs->last_ode); return ode; } U0 SpanDel(CMathODE *ode) { if (ode) { QueueRemove(ode); QueueDel(&ode->next_mass, TRUE); QueueDel(&ode->next_spring, TRUE); ODEDel(ode); } } #define M_SIZE (sizeof(MyMass) - offset(CMass.start)) #define S_SIZE (sizeof(MySpring) - offset(CSpring.start)) U8 *SpanSave(CMathODE *ode, I64 *_size=NULL) { I64 count; U8 *res, *ptr; MyMass *tmpm; MySpring *tmps; SpanHeader h; ODERenum(ode); h.version = SPAN_VERSION; if (ode->next_mass != &ode->next_mass) h.num_masses = ode->last_mass->num + 1; else h.num_masses = 0; if (ode->next_spring != &ode->next_spring) h.num_springs = ode->last_spring->num + 1; else h.num_springs = 0; count = sizeof(SpanHeader) + h.num_masses * M_SIZE + h.num_springs * S_SIZE; ptr = res = MAlloc(count); MemCopy(ptr, &h, sizeof(SpanHeader)); ptr += sizeof(SpanHeader); tmpm = ode->next_mass; while (tmpm != &ode->next_mass) { MemCopy(ptr, &tmpm->start, M_SIZE); ptr += M_SIZE; tmpm = tmpm->next; } tmps = ode->next_spring; while (tmps != &ode->next_spring) { MemCopy(ptr, &tmps->start, S_SIZE); ptr += S_SIZE; tmps = tmps->next; } if (_size) *_size = count; return res; } Bool SpanWrite(CMathODE *ode) { U8 *name, *buf; I64 size; Bool res = FALSE, old_silent = Silent; DirMake("~/Span"); Silent(old_silent); if (name = PopUpFileName("~/Span/Game.DATA")) { if (buf = SpanSave(ode, &size)) { FileWrite(name, buf, size); Free(buf); res = TRUE; } Free(name); } return res; } U0 SpanLoad(CMathODE *ode, U8 *src) { I64 i; MyMass *tmpm; MySpring *tmps; SpanHeader h; if (!src) return; MemCopy(&h, src, sizeof(SpanHeader)); src += sizeof(SpanHeader); for (i = 0; i < h.num_masses; i++) { tmpm = CAlloc(sizeof(MyMass)); MemCopy(&tmpm->start, src, M_SIZE); src += M_SIZE; QueueInsert(tmpm, ode->last_mass); } for (i = 0; i < h.num_springs; i++) { tmps = CAlloc(sizeof(MySpring)); MemCopy(&tmps->start, src, S_SIZE); src += S_SIZE; QueueInsert(tmps, ode->last_spring); tmps->end1 = MassFindNum(ode, tmps->end1_num); tmps->end2 = MassFindNum(ode, tmps->end2_num); } } U8 *SpanRead() { U8 *src = NULL, *name; Bool old_silent = Silent; DirMake("~/Span"); Silent(old_silent); if (name = PopUpPickFile("~/Span")) { src = FileRead(name); Free(name); } return src; }