TempleOSTS_130315.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:45:37 +02:00
1 parent e57428affb
commit 17b71f1a2d
958 files changed
+26043 -15907

No files matched your search

+1
View File
@@ -0,0 +1 @@
MkDir("HOME/Span");
+10
View File
@@ -0,0 +1,10 @@
#help_index "Games"
Cd("/TempleOS/Apps/Span");;
#include "Span.HPP"
#include "SpanDerive"
#include "SpanBridge1"
#include "SpanNew"
#include "SpanMain"
#help_index ""
+3
View File
@@ -0,0 +1,3 @@
Cd("/TempleOS/Apps/Span");;
#include "Load"
Span;
+54
View File
@@ -0,0 +1,54 @@
#define SPAN_VERSION 1.0
class SpanHeader
{
F64 version;
I32 num_masses,num_springs;
};
class MyMass:CMass
{
F64 radius,cost,load_t;
CColorROPU32 color;
} *cursor_mass;
class MySpring:CSpring
{
F64 compression_strength,tensile_strength,cost;
F64 base_compression_strength,base_tensile_strength,
base_constant,base_cost;
CColorROPU32 color;
I32 pen_width;
};
CMathODE *ode=NULL;
CCtrlButtonState snap_button,run_button,mode_button;
CColorROPU32 run_colors[2]={RED,GREEN};
CColorROPU32 snap_colors[2]={RED,GREEN};
#define SNAP_SIZE 4
#define MD_MASS 0
#define MD_CONCRETE 1
#define MD_STEEL 2
#define MD_WIRE 3
#define MD_MOVE 4
#define MD_DELETE 5
#define MD_NUM_MODES 6
CColorROPU32 mode_colors[MD_NUM_MODES]=
{BROWN,LTGRAY,DKGRAY,RED,PURPLE,RED};
DefineLstLoad("ST_SPAN_MODES","Mass\0Concrete\0Steel\0Wire\0Move\0Delete\0");
class SpanAnimateStruct
{
U8 *saved_ode;
F64 elapsed_t,start_wall_t;
} a;
extern MyMass PlaceMass(I64 x, I64 y);
extern F64 SpanTime(CTask *task);
+90
View File
@@ -0,0 +1,90 @@
#define STRENGTH_SCALE 1.5e7
#define SPRING_SCALE 6.0e6
#define COST_SCALE 375.0
#define MASS_RADIUS 3.0
#define MASS_WEIGHT 10.0
#define WIRE_PERCENT 0.99
#define RIVER_BANK_COLS 5
#define SKY_LINES 40
#define FIXED_X1 ((RIVER_BANK_COLS-1)*FONT_WIDTH)
#define FIXED_X2 ((RIVER_BANK_COLS-4)*FONT_WIDTH)
#define FIXED_X3 (TEXT_COLS*FONT_WIDTH>>1)
#define FIXED_Y1 ((SKY_LINES+1)*FONT_HEIGHT)
#define FIXED_Y2 ((SKY_LINES+5)*FONT_HEIGHT)
#define FIXED_Y3 ((TEXT_ROWS-8)*FONT_HEIGHT)
#define LOAD_WEIGHTS 8
U0 SpanBridge1Init(CMathODE *)
{
I64 i;
MyMass *tempm;
tempm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y1);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(GR_WIDTH-FIXED_X2,FIXED_Y1);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y2);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(FIXED_X1,FIXED_Y1);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(FIXED_X2,FIXED_Y1);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(FIXED_X1,FIXED_Y2);
tempm->flags|=MSF_FIXED;
tempm=PlaceMass(FIXED_X3,FIXED_Y3);
tempm->flags|=MSF_FIXED;
for (i=0;i<LOAD_WEIGHTS;i++) {
tempm=PlaceMass(FIXED_X1+(i+1)*(GR_WIDTH-2*FIXED_X1)/(LOAD_WEIGHTS+1),
FIXED_Y1);
tempm->load_t=(i+1.0)/LOAD_WEIGHTS;
tempm->color=RED;
}
"$$CL$$$$BG,LTCYAN$$";
NewLine(SKY_LINES);
for (i=0;i<10;i++) {
"$$BG,BROWN$$";
Spaces(RIVER_BANK_COLS);
"$$BG,LTCYAN$$";
Spaces(TEXT_COLS-2*RIVER_BANK_COLS);
"$$BG,BROWN$$";
Spaces(RIVER_BANK_COLS);
NewLine;
}
for (i=0;i<5;i++) {
"$$BG,BROWN$$";
Spaces(RIVER_BANK_COLS+i);
"$$BG,BLUE$$";
Spaces(TEXT_COLS/2-RIVER_BANK_COLS-2*i);
"$$BG,BROWN$$";
Spaces(2*i);
"$$BG,BLUE$$";
Spaces(TEXT_COLS/2-RIVER_BANK_COLS-2*i);
"$$BG,BROWN$$";
Spaces(RIVER_BANK_COLS+i);
NewLine;
}
}
U0 AdjustLoads(CTask *task,CMathODE *ode)
{
MyMass *tempm=ode->next_mass;
F64 d,tt=SpanTime(task)/10.0;
while (tempm!=&ode->next_mass) {
if (tempm->load_t) {
if (tt) {
d=Abs(Sin(tempm->load_t*ã+tt)); //0.0<=d<=1.0
tempm->mass=100.0*Sqr(Sqr(d+1.0));
tempm->radius=7.0*d+2.0;
} else {
tempm->mass=MASS_WEIGHT;
tempm->radius=MASS_RADIUS;
}
}
tempm=tempm->next;
}
}
+47
View File
@@ -0,0 +1,47 @@
U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
{
//The forces due to springs and drag are
//automatically handled by the
//ode code. We can add new forces
//here.
CTask *task=ode->win_task;
F64 d,dd;
CD3 p,p2;
MyMass *tempm1,*tempm2;
//Collisions
tempm1=ode->next_mass;
while (tempm1!=&ode->next_mass) {
tempm2=tempm1->next;
while (tempm2!=&ode->next_mass) {
D3Sub(&tempm2->state->x,&tempm1->state->x,&p);
dd=D3SqrNorm(&p);
if (dd<=Sqr(tempm1->radius+tempm2->radius)) {
d=Sqrt(dd)+0.0001;
dd=10.0*Sqr(Sqr(Sqr(tempm1->radius+tempm2->radius)-dd));
D3MulEqu(&p,dd/d);
D3AddEqu(&tempm2->DstateDt->DxDt,&p);
D3SubEqu(&tempm1->DstateDt->DxDt,&p);
}
tempm2=tempm2->next;
}
tempm1=tempm1->next;
}
tempm1=ode->next_mass;
while (tempm1!=&ode->next_mass) {
if (!(tempm1->flags&MSF_FIXED))
tempm1->DstateDt->DyDt+=10.0*tempm1->mass; //Gravity
tempm1=tempm1->next;
}
if (cursor_mass) {
p2.x=ipx-task->win_pixel_left-task->win_scroll_x;
p2.y=ipy-task->win_pixel_top-task->win_scroll_y;
p2.z=0;
D3Sub(&p2,&cursor_mass->state->x,&p);
d=10.0*D3SqrNorm(&p);
D3MulEqu(&p,d);
D3AddEqu(&cursor_mass->DstateDt->DxDt,&p);
}
}
+504
View File
@@ -0,0 +1,504 @@
F64 SpanTime()
{
if (run_button.state)
return a.elapsed_t+tT-a.start_wall_t;
else
return a.elapsed_t;
}
F64 Cost(CMathODE *ode)
{
MyMass *tempm;
MySpring *temps;
F64 result=0;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
result+=tempm->cost;
tempm=tempm->next;
}
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
result+=temps->cost;
temps=temps->next;
}
return result;
}
U0 DrawIt(CTask *task,CDC *dc)
{
Bool old_suspend1,old_suspend2;
I64 i,j;
MyMass *tempm;
MySpring *temps;
old_suspend1=Suspend(task);
old_suspend2=Suspend(task->animate_task);
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
if (!(temps->flags&SSF_INACTIVE)) {
dc->color=temps->color;
dc->pen_width=temps->pen_width;
GrLine3(dc,temps->end1->x,temps->end1->y,0,
temps->end2->x,temps->end2->y,0);
}
temps=temps->next;
}
if (cursor_mass) {
dc->color=RED;
dc->pen_width=2;
GrLine3(dc,ipx-task->win_pixel_left-task->win_scroll_x,ipy-task->win_pixel_top-task->win_scroll_y,0,
cursor_mass->x,cursor_mass->y,0);
}
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (!(tempm->flags&MSF_INACTIVE)) {
dc->color=BLACK;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
GrFloodFill(dc,tempm->x,tempm->y,TRUE);
dc->color=tempm->color;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
GrFloodFill(dc,tempm->x,tempm->y,TRUE);
dc->color=BLACK;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
}
tempm=tempm->next;
}
dc->color=BLACK;
if (snap_button.state)
for (j=0;j<GR_HEIGHT;j+=SNAP_SIZE)
for (i=0;i<GR_WIDTH;i+=SNAP_SIZE)
GrPlot(dc,i,j);
dc->color=BLACK;
GrPrintF(dc,90,0,"Cost:%12.2,f",Cost(ode));
GrPrintF(dc,90,FONT_HEIGHT,"Time:%12.2f",SpanTime);
Suspend(task,old_suspend1);
Suspend(task->animate_task,old_suspend2);
}
MyMass PlaceMass(I64 x, I64 y)
{
MyMass *tempm=CAlloc(sizeof(MyMass));
tempm->drag_profile_factor=1.0;
tempm->x=x;
tempm->y=y;
tempm->mass=MASS_WEIGHT;
tempm->radius=MASS_RADIUS;
tempm->cost=25.0*COST_SCALE;
tempm->color=YELLOW;
QueIns(tempm,ode->last_mass);
return tempm;
}
U0 NullSpring(MySpring *temps,F64 scale)
{
F64 d=D3Dist(&temps->end1->x,&temps->end2->x);
temps->rest_len=d*scale;
temps->compression_strength=temps->base_compression_strength/(temps->rest_len+1.0);
temps->tensile_strength=temps->base_tensile_strength/(temps->rest_len+1.0);
temps->constant=temps->base_constant/(temps->rest_len+1.0);
temps->cost=temps->base_cost*temps->rest_len;
}
U0 MoveMass(MyMass *tempm,I64 x, I64 y)
{
MySpring *temps;
tempm->x=x;
tempm->y=y;
tempm->DxDt=0;
tempm->DyDt=0;
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
if (temps->end1==tempm || temps->end2==tempm) {
if (temps->flags&SSF_NO_COMPRESSION)
NullSpring(temps,WIRE_PERCENT);
else
NullSpring(temps,1.0);
}
temps=temps->next;
}
}
U0 DelSpring(MySpring *temps)
{
QueRem(temps);
Free(temps);
}
U0 DelMass(MyMass *tempm)
{
MySpring *temps,*temps1;
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
temps1=temps->next;
if (temps->end1==tempm || temps->end2==tempm)
DelSpring(temps);
temps=temps1;
}
QueRem(tempm);
Free(tempm);
}
U0 DrawSpring(CDC *dc,MyMass *tempm,I64 x,I64 y)
{
switch (mode_button.state) {
case MD_CONCRETE:
dc->color=LTGRAY;
dc->pen_width=2;
break;
case MD_STEEL:
dc->color=DKGRAY;
dc->pen_width=2;
break;
case MD_WIRE:
dc->color=RED;
dc->pen_width=1;
break;
}
GrLine3(dc,tempm->x,tempm->y,0,x,y,0);
}
U0 PlaceSpring(MyMass *tempm1,MyMass *tempm2)
{
MySpring *temps=CAlloc(sizeof(MySpring));
temps->end1=tempm1;
temps->end2=tempm2;
switch (mode_button.state) {
case MD_CONCRETE:
temps->base_constant = 3.00*SPRING_SCALE;
temps->base_compression_strength=10.00*STRENGTH_SCALE;
temps->base_tensile_strength = 0.35*STRENGTH_SCALE;
temps->base_cost = 0.30*COST_SCALE;
NullSpring(temps,1.0);
temps->color=LTGRAY;
temps->pen_width=2;
break;
case MD_STEEL:
temps->base_constant = 1.00*SPRING_SCALE;
temps->base_compression_strength= 1.00*STRENGTH_SCALE;
temps->base_tensile_strength = 1.00*STRENGTH_SCALE;
temps->base_cost = 1.00*COST_SCALE;
NullSpring(temps,1.0);
temps->color=DKGRAY;
temps->pen_width=2;
break;
case MD_WIRE:
temps->base_constant = 0.25*SPRING_SCALE;
temps->base_compression_strength= 0.00;
temps->base_tensile_strength = 0.50*STRENGTH_SCALE;
temps->base_cost = 0.10*COST_SCALE;
NullSpring(temps,WIRE_PERCENT);
temps->color=RED;
temps->pen_width=1;
temps->flags|=SSF_NO_COMPRESSION;
break;
}
QueIns(temps,ode->last_spring);
}
U0 AnimateTask(SpanAnimateStruct *a)
{ //Preemption is off by default.
MySpring *temps,*temps1;
U8 old_run=FALSE,old_snap_state=OFF;
F64 f;
while (TRUE) {
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
temps1=temps->next;
f=temps->f;
if (f>0 && f>temps->compression_strength && !(temps->flags&SSF_NO_COMPRESSION)||
f<0 && -f>temps->tensile_strength && !(temps->flags&SSF_NO_TENSION))
temps->flags|=SSF_INACTIVE;
temps=temps1;
}
AdjustLoads(Fs->parent_task,ode);
WinMgrSync; //CMathODE updated once per refresh.
if (old_run!=run_button.state) {
if (run_button.state) {
if (!a->elapsed_t || !a->saved_ode) {
Free(a->saved_ode);
a->saved_ode=SpanSave(ode);
}
a->start_wall_t=tT;
ode->flags&=~ODEF_PAUSED;
} else {
ode->flags|=ODEF_PAUSED;
a->elapsed_t+=tT-a->start_wall_t;
}
old_run=run_button.state;
}
if (old_snap_state!=snap_button.state) {
if (snap_button.state)
SetSnap(&Fs->parent_task->snap,SNAP_SIZE,1.0);
else
SetSnap(&Fs->parent_task->snap,1,1.0);
old_snap_state=snap_button.state;
}
}
}
U0 Init(SpanAnimateStruct *a)
{
ode=SpanNew;
run_button.state=0;
WinMgrSync; //Allow stop to register in animate task.
WinMgrSync;
if (a->saved_ode)
SpanLoad(ode,a->saved_ode);
else
SpanBridge1Init(ode);
a->elapsed_t=0;
cursor_mass=NULL;
}
U0 SongTask(I64)
{ //Song by Terry A. Davis
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
music_tempo= 3.636;
music_stacatto_factor= 0.902;
while (TRUE) {
Play("W13q.EeDqED2G3DhE");
Play("q.EeDqED2G3DhE");
Play("q.FeEFEqF2G3EhF");
Play("q.FeEFEqF2G3EhF");
}
}
U0 Span()
{
I64 msg_code,p1,p2;
MyMass *tempm1=NULL,*tempm2=NULL;
MySpring *temps;
CCtrl *bt_run,*bt_mode,*bt_snap;
U8 *src;
CDC *dc=DCAlias;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
WinMax;
Fs->song_task=Spawn(&SongTask,NULL,"Song",Fs);
bt_run =CtrlButtonNew(0,0, 80,,2,"Stopped\0Running\0",run_colors,&run_button),
bt_snap=CtrlButtonNew(0,2.5*FONT_HEIGHT,80,,2,"Snap Off\0Snap On\0",snap_colors,&snap_button),
bt_mode=CtrlButtonNew(0,5.0*FONT_HEIGHT,80,,MD_NUM_MODES,Define("ST_SPAN_MODES"),mode_colors,&mode_button);
a.saved_ode=NULL;
//This Preempt() eliminates a lot of hassles.
//The concern is about changing
//que links while the winmgr task
//is updating the ode or screen.
//The Window mgr suspends this
//task while updating the ode. It
//will not be interrupted and with this
//preempt, we will not be interrupted.
//There is little downside to Preempt()
//since we will yield during GetMsg().
Preempt(OFF);
DocCursor;
WinBorder;
WordStat;
Fs->win_inhibit|=WIF_DBL_CLICK;
MenuPush(
"File {"
" New(,CH_CTRLN);"
" Open(,CH_CTRLO);"
" SaveAs(,CH_CTRLA);"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" RunStop(,CH_SPACE);"
" SnapGrid(,'g');"
" Mass(,'m');"
" Concrete(,'c');"
" Steel(,'s');"
" Wire(,'w');"
" Move(,'v');"
" Delete(,'d');"
"}"
);
Init(&a);
Fs->animate_task=Spawn(&AnimateTask,&a,"Animate",Fs);
Fs->draw_it=&DrawIt;
PopUpOk(
"Build a bridge to hold-up the\n"
"red masses. Test your design\n"
"by pressing run/stop.\n\n"
"The lowest cost bridge that\n"
"stays standing wins.\n\n"
"For a variation, try without\n"
"using the center base point.\n"
"\n"
"Use\n"
"\t$$FG,GREEN$$'m'$$FG$$ass\n"
"\t$$FG,GREEN$$'c'$$FG$$oncrete\n"
"\t$$FG,GREEN$$'s'$$FG$$teel\n"
"\t$$FG,GREEN$$'w'$$FG$$ire\n"
"\nto select materials.\n");
try {
while (TRUE) {
msg_code=GetMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_IP_R_DOWN|1<<MSG_IP_L_UP|1<<MSG_KEY_DOWN|1<<MSG_IP_MOVE);
DCFill(dc);
switch (msg_code) {
case MSG_IP_L_DOWN:
cursor_mass=tempm1=tempm2=NULL;
switch (mode_button.state) {
case MD_MASS:
PlaceMass(p1,p2);
break;
case MD_CONCRETE:
case MD_STEEL:
case MD_WIRE:
tempm1=MassFind(ode,p1,p2);
break;
case MD_MOVE:
if (run_button.state)
cursor_mass=MassFind(ode,p1,p2);
else
if (tempm1=MassFind(ode,p1,p2))
MoveMass(tempm1,p1,p2);
break;
case MD_DELETE:
MassOrSpringFind(ode,&tempm1,&temps,p1,p2);
if (tempm1)
DelMass(tempm1);
if (temps)
DelSpring(temps);
break;
}
break;
case MSG_IP_L_UP:
switch (mode_button.state) {
case MD_CONCRETE:
case MD_STEEL:
case MD_WIRE:
if (tempm1 && (tempm2=MassFind(ode,p1,p2)) && tempm1!=tempm2)
PlaceSpring(tempm1,tempm2);
break;
case MD_MOVE:
if (!run_button.state && tempm1)
MoveMass(tempm1,p1,p2);
break;
}
cursor_mass=tempm1=tempm2=NULL;
break;
case MSG_IP_MOVE:
switch (mode_button.state) {
case MD_MOVE:
if (!run_button.state && tempm1)
MoveMass(tempm1,p1,p2);
break;
case MD_CONCRETE:
case MD_STEEL:
case MD_WIRE:
if (tempm1) {
DrawSpring(dc,tempm1,p1,p2);
}
break;
}
break;
case MSG_IP_R_DOWN:
mode_button.state++;
if (mode_button.state>=MD_NUM_MODES)
mode_button.state=0;
cursor_mass=tempm1=tempm2=NULL;
break;
case MSG_KEY_DOWN:
switch (p1) {
case '\n':
if (!SpanTime || !a.saved_ode) {
Free(a.saved_ode);
a.saved_ode=SpanSave(ode);
}
SpanDel(ode);
Init(&a);
break;
case CH_CTRLN:
SpanDel(ode);
Free(a.saved_ode);
a.saved_ode=NULL;
Init(&a);
break;
case CH_CTRLO:
if (src=SpanRead) {
Free(a.saved_ode);
a.saved_ode=src;
SpanDel(ode);
Init(&a);
}
break;
case CH_CTRLA:
if (!SpanTime || !a.saved_ode) {
Free(a.saved_ode);
a.saved_ode=SpanSave(ode);
}
SpanDel(ode);
Init(&a);
SpanWrite(ode);
break;
case CH_SPACE:
run_button.state=!run_button.state;
break;
case 'g':
snap_button.state=!snap_button.state;
break;
case 'c':
mode_button.state=MD_CONCRETE;
break;
case 's':
mode_button.state=MD_STEEL;
break;
case 'w':
mode_button.state=MD_WIRE;
break;
case 'm':
mode_button.state=MD_MASS;
break;
case 'v':
mode_button.state=MD_MOVE;
break;
case 'd':
mode_button.state=MD_DELETE;
break;
case CH_ESC:
if (!SpanTime || !a.saved_ode) {
Free(a.saved_ode);
a.saved_ode=SpanSave(ode);
}
SpanDel(ode);
Init(&a);
SpanWrite(ode);
case CH_SHIFT_ESC:
goto span_done;
}
break;
}
}
span_done: //Don't goto out of try
} catch
CatchAll;
SettingsPop;
CtrlButtonDel(bt_run);
CtrlButtonDel(bt_mode);
CtrlButtonDel(bt_snap);
SpanDel(ode);
DCFill(dc);
DCDel(dc);
MenuPop;
DocBottom;
"$$CL$$$$BG$$\n";
}
+127
View File
@@ -0,0 +1,127 @@
CMathODE *SpanNew()
{
ode=ODENew(0,1e-4,ODEF_HAS_MASSES|ODEF_PAUSED);
ode->derivative=&MyDerivative;
ode->drag_v2=0.002;
ode->drag_v3=0.00001;
ode->acceleration_limit=5e3;
QueIns(ode,Fs->last_ode);
return ode;
}
U0 SpanDel(CMathODE *ode)
{
QueRem(ode);
QueDel(&ode->next_mass,TRUE);
QueDel(&ode->next_spring,TRUE);
ODEDel(ode);
}
#define M_SIZE (sizeof(MyMass)-offset(CMass.start_saved_area))
#define S_SIZE (sizeof(MySpring)-offset(CSpring.start_saved_area))
U8 *SpanSave(CMathODE *ode,I64 *_size=NULL)
{
I64 cnt;
U8 *result,*ptr;
MyMass *tempm;
MySpring *temps;
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;
cnt=sizeof(SpanHeader)+h.num_masses*M_SIZE+h.num_springs*S_SIZE;
ptr=result=MAlloc(cnt);
MemCpy(ptr,&h,sizeof(SpanHeader));
ptr+=sizeof(SpanHeader);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
MemCpy(ptr,&tempm->start_saved_area,M_SIZE);
ptr+=M_SIZE;
tempm=tempm->next;
}
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
MemCpy(ptr,&temps->start_saved_area,S_SIZE);
ptr+=S_SIZE;
temps=temps->next;
}
if (_size) *_size=cnt;
return result;
}
Bool SpanWrite(CMathODE *ode)
{
U8 *name,*buf;
I64 size;
Bool result=FALSE,old_silent=Silent(ON);
MkDir("HOME/Span");
Silent(old_silent);
if (name=PopUpFileName("HOME/Span/Game.DAT")) {
if (buf=SpanSave(ode,&size)) {
FileWrite(name,buf,size);
Free(buf);
result=TRUE;
}
Free(name);
}
return result;
}
U0 SpanLoad(CMathODE *ode,U8 *src)
{
I64 i;
MyMass *tempm;
MySpring *temps;
SpanHeader h;
if (!src) return;
MemCpy(&h,src,sizeof(SpanHeader));
src+=sizeof(SpanHeader);
for (i=0;i<h.num_masses;i++) {
tempm=CAlloc(sizeof(MyMass));
MemCpy(&tempm->start_saved_area,src,M_SIZE);
src+=M_SIZE;
QueIns(tempm,ode->last_mass);
}
for (i=0;i<h.num_springs;i++) {
temps=CAlloc(sizeof(MySpring));
MemCpy(&temps->start_saved_area,src,S_SIZE);
src+=S_SIZE;
QueIns(temps,ode->last_spring);
temps->end1=MassFindNum(ode,temps->end1_num);
temps->end2=MassFindNum(ode,temps->end2_num);
}
}
U8 *SpanRead()
{
U8 *src=NULL,*name;
Bool old_silent=Silent(ON);
MkDir("HOME/Span");
Silent(old_silent);
if (name=PopUpPickFile("HOME/Span")) {
src=FileRead(name);
Free(name);
}
return src;
}