Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
@@ -0,0 +1 @@
|
||||
MkDir("~/Span");
|
||||
@@ -0,0 +1,10 @@
|
||||
#help_index "Games"
|
||||
|
||||
Cd(__DIR__);;
|
||||
#include "Span.HH"
|
||||
#include "SpanDerive"
|
||||
#include "SpanBridge"
|
||||
#include "SpanNew"
|
||||
#include "SpanMain"
|
||||
|
||||
#help_index ""
|
||||
@@ -0,0 +1,3 @@
|
||||
Cd(__DIR__);;
|
||||
#include "Load"
|
||||
Span;
|
||||
@@ -0,0 +1,49 @@
|
||||
#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_const,base_cost;
|
||||
|
||||
CColorROPU32 color;
|
||||
I32 pen_width;
|
||||
};
|
||||
|
||||
CMathODE *ode=NULL;
|
||||
|
||||
CCtrlBttnState run_bttn,mode_bttn;
|
||||
|
||||
CColorROPU32 run_colors[2]={RED,GREEN};
|
||||
|
||||
#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_MODES_NUM 6
|
||||
CColorROPU32 mode_colors[MD_MODES_NUM]=
|
||||
{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();
|
||||
@@ -0,0 +1,80 @@
|
||||
#define STRENGTH_SCALE 1.5e7
|
||||
#define SPRING_SCALE 6.0e6
|
||||
#define COST_SCALE 375.0
|
||||
#define MASS_RADIUS 3.0
|
||||
#define MASS_MASS 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 *tmpm;
|
||||
tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y1);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(GR_WIDTH-FIXED_X2,FIXED_Y1);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y2);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(FIXED_X1,FIXED_Y1);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(FIXED_X2,FIXED_Y1);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(FIXED_X1,FIXED_Y2);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
tmpm=PlaceMass(FIXED_X3,FIXED_Y3);
|
||||
tmpm->flags|=MSF_FIXED;
|
||||
|
||||
for (i=0;i<LOAD_WEIGHTS;i++) {
|
||||
tmpm=PlaceMass(FIXED_X1+(i+1)*(GR_WIDTH-2*FIXED_X1)/(LOAD_WEIGHTS+1),
|
||||
FIXED_Y1);
|
||||
tmpm->load_t=(i+1.0)/LOAD_WEIGHTS;
|
||||
tmpm->color=RED;
|
||||
}
|
||||
|
||||
DocClear;
|
||||
"$$BG,LTCYAN$$%h*c",SKY_LINES,'\n';
|
||||
for (i=0;i<10;i++) {
|
||||
"$$BG,BROWN$$%h*c",RIVER_BANK_COLS,CH_SPACE;
|
||||
"$$BG,LTCYAN$$%h*c",TEXT_COLS-2*RIVER_BANK_COLS,CH_SPACE;
|
||||
"$$BG,BROWN$$%h*c\n",RIVER_BANK_COLS,CH_SPACE;
|
||||
}
|
||||
for (i=0;i<5;i++) {
|
||||
"$$BG,BROWN$$%h*c",RIVER_BANK_COLS+i,CH_SPACE;
|
||||
"$$BG,BLUE$$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
|
||||
"$$BG,BROWN$$%h*c",2*i,CH_SPACE;
|
||||
"$$BG,BLUE$$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
|
||||
"$$BG,BROWN$$%h*c\n",RIVER_BANK_COLS+i,CH_SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 AdjustLoads(CMathODE *ode)
|
||||
{
|
||||
MyMass *tmpm=ode->next_mass;
|
||||
F64 d,tt=SpanTime/10.0;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (tmpm->load_t) {
|
||||
if (tt) {
|
||||
d=Abs(Sin(tmpm->load_t*ã+tt)); //0.0<=d<=1.0
|
||||
tmpm->mass=100.0*Sqr(Sqr(d+1.0));
|
||||
tmpm->radius=7.0*d+2.0;
|
||||
} else {
|
||||
tmpm->mass=MASS_MASS;
|
||||
tmpm->radius=MASS_RADIUS;
|
||||
}
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
@@ -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 *tmpm1,*tmpm2;
|
||||
|
||||
//Collisions
|
||||
tmpm1=ode->next_mass;
|
||||
while (tmpm1!=&ode->next_mass) {
|
||||
tmpm2=tmpm1->next;
|
||||
while (tmpm2!=&ode->next_mass) {
|
||||
D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
|
||||
dd=D3NormSqr(&p);
|
||||
if (dd<=Sqr(tmpm1->radius+tmpm2->radius)) {
|
||||
d=Sqrt(dd)+0.0001;
|
||||
dd=10.0*Sqr(Sqr(Sqr(tmpm1->radius+tmpm2->radius)-dd));
|
||||
D3MulEqu(&p,dd/d);
|
||||
D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
|
||||
D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
|
||||
}
|
||||
tmpm2=tmpm2->next;
|
||||
}
|
||||
tmpm1=tmpm1->next;
|
||||
}
|
||||
|
||||
tmpm1=ode->next_mass;
|
||||
while (tmpm1!=&ode->next_mass) {
|
||||
if (!(tmpm1->flags&MSF_FIXED))
|
||||
tmpm1->DstateDt->DyDt+=10.0*tmpm1->mass; //Gravity
|
||||
tmpm1=tmpm1->next;
|
||||
}
|
||||
|
||||
if (cursor_mass) {
|
||||
p2.x=ms.pos.x-task->pix_left-task->scroll_x;
|
||||
p2.y=ms.pos.y-task->pix_top-task->scroll_y;
|
||||
p2.z=0;
|
||||
D3Sub(&p,&p2,&cursor_mass->state->x);
|
||||
d=10.0*D3NormSqr(&p);
|
||||
D3MulEqu(&p,d);
|
||||
D3AddEqu(&cursor_mass->DstateDt->DxDt,&p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
F64 SpanTime()
|
||||
{
|
||||
if (run_bttn.state)
|
||||
return a.elapsed_t+tS-a.start_wall_t;
|
||||
else
|
||||
return a.elapsed_t;
|
||||
}
|
||||
|
||||
F64 Cost(CMathODE *ode)
|
||||
{
|
||||
MyMass *tmpm;
|
||||
MySpring *tmps;
|
||||
F64 res=0;
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
res+=tmpm->cost;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
res+=tmps->cost;
|
||||
tmps=tmps->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 DrawIt(CTask *task,CDC *dc)
|
||||
{
|
||||
MyMass *tmpm;
|
||||
MySpring *tmps;
|
||||
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
if (!(tmps->flags&SSF_INACTIVE)) {
|
||||
dc->color=tmps->color;
|
||||
dc->pen_width=tmps->pen_width;
|
||||
GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
|
||||
tmps->end2->x,tmps->end2->y,0);
|
||||
}
|
||||
tmps=tmps->next;
|
||||
}
|
||||
|
||||
if (cursor_mass) {
|
||||
dc->color=RED;
|
||||
dc->pen_width=2;
|
||||
GrLine3(dc,ms.pos.x-task->pix_left-task->scroll_x,
|
||||
ms.pos.y-task->pix_top-task->scroll_y,0,
|
||||
cursor_mass->x,cursor_mass->y,0);
|
||||
}
|
||||
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (!(tmpm->flags&MSF_INACTIVE)) {
|
||||
dc->color=BLACK;
|
||||
GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
|
||||
GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
|
||||
dc->color=tmpm->color;
|
||||
GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
|
||||
GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
|
||||
dc->color=BLACK;
|
||||
GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
|
||||
dc->color=BLACK;
|
||||
GrPrint(dc,90,0,"Cost:%12.2,f",Cost(ode));
|
||||
GrPrint(dc,90,FONT_HEIGHT,"Time:%12.2f",SpanTime);
|
||||
}
|
||||
|
||||
MyMass *PlaceMass(I64 x, I64 y)
|
||||
{
|
||||
MyMass *tmpm=CAlloc(sizeof(MyMass));
|
||||
tmpm->drag_profile_factor=1.0;
|
||||
tmpm->x=x;
|
||||
tmpm->y=y;
|
||||
tmpm->mass=MASS_MASS;
|
||||
tmpm->radius=MASS_RADIUS;
|
||||
tmpm->cost=25.0*COST_SCALE;
|
||||
tmpm->color=YELLOW;
|
||||
QueIns(tmpm,ode->last_mass);
|
||||
return tmpm;
|
||||
}
|
||||
|
||||
U0 NullSpring(MySpring *tmps,F64 scale)
|
||||
{
|
||||
F64 d=D3Dist(&tmps->end1->x,&tmps->end2->x);
|
||||
tmps->rest_len=d*scale;
|
||||
tmps->compression_strength=
|
||||
tmps->base_compression_strength/(tmps->rest_len+1.0);
|
||||
tmps->tensile_strength=tmps->base_tensile_strength/(tmps->rest_len+1.0);
|
||||
tmps->const=tmps->base_const/(tmps->rest_len+1.0);
|
||||
tmps->cost=tmps->base_cost*tmps->rest_len;
|
||||
}
|
||||
|
||||
U0 MoveMass(MyMass *tmpm,I64 x, I64 y)
|
||||
{
|
||||
MySpring *tmps;
|
||||
tmpm->x=x;
|
||||
tmpm->y=y;
|
||||
tmpm->DxDt=0;
|
||||
tmpm->DyDt=0;
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
if (tmps->end1==tmpm || tmps->end2==tmpm) {
|
||||
if (tmps->flags&SSF_NO_COMPRESSION)
|
||||
NullSpring(tmps,WIRE_PERCENT);
|
||||
else
|
||||
NullSpring(tmps,1.0);
|
||||
}
|
||||
tmps=tmps->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DelSpring(MySpring *tmps)
|
||||
{
|
||||
QueRem(tmps);
|
||||
Free(tmps);
|
||||
}
|
||||
|
||||
U0 DelMass(MyMass *tmpm)
|
||||
{
|
||||
MySpring *tmps,*tmps1;
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
tmps1=tmps->next;
|
||||
if (tmps->end1==tmpm || tmps->end2==tmpm)
|
||||
DelSpring(tmps);
|
||||
tmps=tmps1;
|
||||
}
|
||||
QueRem(tmpm);
|
||||
Free(tmpm);
|
||||
}
|
||||
|
||||
U0 DrawSpring(CDC *dc,MyMass *tmpm,I64 x,I64 y)
|
||||
{
|
||||
switch (mode_bttn.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,tmpm->x,tmpm->y,0,x,y,0);
|
||||
}
|
||||
|
||||
U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
|
||||
{
|
||||
MySpring *tmps=CAlloc(sizeof(MySpring));
|
||||
tmps->end1=tmpm1;
|
||||
tmps->end2=tmpm2;
|
||||
switch (mode_bttn.state) {
|
||||
case MD_CONCRETE:
|
||||
tmps->base_const = 3.00*SPRING_SCALE;
|
||||
tmps->base_compression_strength=10.00*STRENGTH_SCALE;
|
||||
tmps->base_tensile_strength = 0.35*STRENGTH_SCALE;
|
||||
tmps->base_cost = 0.30*COST_SCALE;
|
||||
NullSpring(tmps,1.0);
|
||||
tmps->color=LTGRAY;
|
||||
tmps->pen_width=2;
|
||||
break;
|
||||
case MD_STEEL:
|
||||
tmps->base_const = 1.00*SPRING_SCALE;
|
||||
tmps->base_compression_strength= 1.00*STRENGTH_SCALE;
|
||||
tmps->base_tensile_strength = 1.00*STRENGTH_SCALE;
|
||||
tmps->base_cost = 1.00*COST_SCALE;
|
||||
NullSpring(tmps,1.0);
|
||||
tmps->color=DKGRAY;
|
||||
tmps->pen_width=2;
|
||||
break;
|
||||
case MD_WIRE:
|
||||
tmps->base_const = 0.25*SPRING_SCALE;
|
||||
tmps->base_compression_strength= 0.00;
|
||||
tmps->base_tensile_strength = 0.50*STRENGTH_SCALE;
|
||||
tmps->base_cost = 0.10*COST_SCALE;
|
||||
NullSpring(tmps,WIRE_PERCENT);
|
||||
tmps->color=RED;
|
||||
tmps->pen_width=1;
|
||||
tmps->flags|=SSF_NO_COMPRESSION;
|
||||
break;
|
||||
}
|
||||
QueIns(tmps,ode->last_spring);
|
||||
}
|
||||
|
||||
U0 AnimateTask(SpanAnimateStruct *a)
|
||||
{
|
||||
MySpring *tmps,*tmps1;
|
||||
Bool old_run=FALSE;
|
||||
F64 f;
|
||||
while (TRUE) {
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
tmps1=tmps->next;
|
||||
f=tmps->f;
|
||||
if (f>0 && f>tmps->compression_strength &&
|
||||
!(tmps->flags&SSF_NO_COMPRESSION)||
|
||||
f<0 && -f>tmps->tensile_strength &&
|
||||
!(tmps->flags&SSF_NO_TENSION))
|
||||
tmps->flags|=SSF_INACTIVE;
|
||||
tmps=tmps1;
|
||||
}
|
||||
AdjustLoads(ode);
|
||||
Refresh; //CMathODE updated once per refresh.
|
||||
if (old_run!=run_bttn.state) {
|
||||
if (run_bttn.state) {
|
||||
if (!a->elapsed_t || !a->saved_ode) {
|
||||
Free(a->saved_ode);
|
||||
a->saved_ode=SpanSave(ode);
|
||||
}
|
||||
a->start_wall_t=tS;
|
||||
ode->flags&=~ODEF_PAUSED;
|
||||
} else {
|
||||
ode->flags|=ODEF_PAUSED;
|
||||
a->elapsed_t+=tS-a->start_wall_t;
|
||||
}
|
||||
old_run=run_bttn.state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 Init(SpanAnimateStruct *a)
|
||||
{
|
||||
SpanDel(ode);
|
||||
ode=SpanNew;
|
||||
|
||||
run_bttn.state=0;
|
||||
Refresh(2); //Allow stop to reg in animate task.
|
||||
|
||||
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("5q.EeDqED4G5DhE");
|
||||
Play("5q.EeDqED4G5DhE");
|
||||
Play("5q.FeEFEqF4G5EhF");
|
||||
Play("5q.FeEFEqF4G5EhF");
|
||||
}
|
||||
}
|
||||
|
||||
U0 Span()
|
||||
{
|
||||
I64 msg_code,arg1,arg2;
|
||||
MyMass *tmpm1=NULL,*tmpm2=NULL;
|
||||
MySpring *tmps;
|
||||
CCtrl *bt_run,*bt_mode;
|
||||
U8 *src;
|
||||
CDC *dc=DCAlias;
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
Fs->text_attr=BROWN<<4+BLACK;
|
||||
AutoComplete;
|
||||
WinBorder;
|
||||
WinMax;
|
||||
DocCursor;
|
||||
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
|
||||
|
||||
bt_run =CtrlBttnNew(0,0, 80,,
|
||||
2,"Stopped\0Running\0",run_colors,&run_bttn);
|
||||
bt_mode=CtrlBttnNew(0,3.0*FONT_HEIGHT,80,,
|
||||
MD_MODES_NUM,Define("ST_SPAN_MODES"),mode_colors,&mode_bttn);
|
||||
a.saved_ode=NULL;
|
||||
|
||||
Fs->win_inhibit|=WIG_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);"
|
||||
" Mass(,'m');"
|
||||
" Concrete(,'c');"
|
||||
" Steel(,'s');"
|
||||
" Wire(,'w');"
|
||||
" Move(,'v');"
|
||||
" Delete(,'d');"
|
||||
"}"
|
||||
);
|
||||
|
||||
ode=NULL;
|
||||
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$$GREEN$$'m'$$FG$$ass\n"
|
||||
"\t$$GREEN$$'c'$$FG$$oncrete\n"
|
||||
"\t$$GREEN$$'s'$$FG$$teel\n"
|
||||
"\t$$GREEN$$'w'$$FG$$ire\n"
|
||||
"\nto sel materials.\n");
|
||||
|
||||
try {
|
||||
while (TRUE) {
|
||||
msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|
|
||||
1<<MSG_MS_L_UP|1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE);
|
||||
DCFill(dc);
|
||||
switch (msg_code) {
|
||||
case MSG_MS_L_DOWN:
|
||||
cursor_mass=tmpm1=tmpm2=NULL;
|
||||
switch (mode_bttn.state) {
|
||||
case MD_MASS:
|
||||
PlaceMass(arg1,arg2);
|
||||
break;
|
||||
case MD_CONCRETE:
|
||||
case MD_STEEL:
|
||||
case MD_WIRE:
|
||||
tmpm1=MassFind(ode,arg1,arg2);
|
||||
break;
|
||||
case MD_MOVE:
|
||||
if (run_bttn.state)
|
||||
cursor_mass=MassFind(ode,arg1,arg2);
|
||||
else
|
||||
if (tmpm1=MassFind(ode,arg1,arg2))
|
||||
MoveMass(tmpm1,arg1,arg2);
|
||||
break;
|
||||
case MD_DELETE:
|
||||
MassOrSpringFind(ode,&tmpm1,&tmps,arg1,arg2);
|
||||
if (tmpm1)
|
||||
DelMass(tmpm1);
|
||||
if (tmps)
|
||||
DelSpring(tmps);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSG_MS_L_UP:
|
||||
switch (mode_bttn.state) {
|
||||
case MD_CONCRETE:
|
||||
case MD_STEEL:
|
||||
case MD_WIRE:
|
||||
if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)
|
||||
PlaceSpring(tmpm1,tmpm2);
|
||||
break;
|
||||
case MD_MOVE:
|
||||
if (!run_bttn.state && tmpm1)
|
||||
MoveMass(tmpm1,arg1,arg2);
|
||||
break;
|
||||
}
|
||||
cursor_mass=tmpm1=tmpm2=NULL;
|
||||
break;
|
||||
case MSG_MS_MOVE:
|
||||
switch (mode_bttn.state) {
|
||||
case MD_MOVE:
|
||||
if (!run_bttn.state && tmpm1)
|
||||
MoveMass(tmpm1,arg1,arg2);
|
||||
break;
|
||||
case MD_CONCRETE:
|
||||
case MD_STEEL:
|
||||
case MD_WIRE:
|
||||
if (tmpm1) {
|
||||
DrawSpring(dc,tmpm1,arg1,arg2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSG_MS_R_DOWN:
|
||||
mode_bttn.state++;
|
||||
if (mode_bttn.state>=MD_MODES_NUM)
|
||||
mode_bttn.state=0;
|
||||
cursor_mass=tmpm1=tmpm2=NULL;
|
||||
break;
|
||||
case MSG_KEY_DOWN:
|
||||
switch (arg1) {
|
||||
case '\n':
|
||||
if (!SpanTime || !a.saved_ode) {
|
||||
Free(a.saved_ode);
|
||||
a.saved_ode=SpanSave(ode);
|
||||
}
|
||||
Init(&a);
|
||||
break;
|
||||
case CH_CTRLN:
|
||||
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;
|
||||
Init(&a);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLA:
|
||||
if (!SpanTime || !a.saved_ode) {
|
||||
Free(a.saved_ode);
|
||||
a.saved_ode=SpanSave(ode);
|
||||
}
|
||||
Init(&a);
|
||||
SpanWrite(ode);
|
||||
break;
|
||||
case CH_SPACE:
|
||||
run_bttn.state=!run_bttn.state;
|
||||
break;
|
||||
case 'c':
|
||||
mode_bttn.state=MD_CONCRETE;
|
||||
break;
|
||||
case 's':
|
||||
mode_bttn.state=MD_STEEL;
|
||||
break;
|
||||
case 'w':
|
||||
mode_bttn.state=MD_WIRE;
|
||||
break;
|
||||
case 'm':
|
||||
mode_bttn.state=MD_MASS;
|
||||
break;
|
||||
case 'v':
|
||||
mode_bttn.state=MD_MOVE;
|
||||
break;
|
||||
case 'd':
|
||||
mode_bttn.state=MD_DELETE;
|
||||
break;
|
||||
case CH_ESC:
|
||||
if (!SpanTime || !a.saved_ode) {
|
||||
Free(a.saved_ode);
|
||||
a.saved_ode=SpanSave(ode);
|
||||
}
|
||||
Init(&a);
|
||||
SpanWrite(ode);
|
||||
case CH_SHIFT_ESC:
|
||||
goto span_done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
span_done: //Don't goto out of try
|
||||
GetMsg(,,1<<MSG_KEY_UP);
|
||||
} catch
|
||||
PutExcept;
|
||||
DocClear;
|
||||
SettingsPop;
|
||||
CtrlBttnDel(bt_run);
|
||||
CtrlBttnDel(bt_mode);
|
||||
SpanDel(ode);
|
||||
DCFill(dc);
|
||||
DCDel(dc);
|
||||
MenuPop;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
CMathODE *SpanNew()
|
||||
{
|
||||
CMathODE *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)
|
||||
{
|
||||
if (ode) {
|
||||
QueRem(ode);
|
||||
QueDel(&ode->next_mass,TRUE);
|
||||
QueDel(&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 cnt;
|
||||
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;
|
||||
|
||||
cnt=sizeof(SpanHeader)+h.num_masses*M_SIZE+h.num_springs*S_SIZE;
|
||||
|
||||
ptr=res=MAlloc(cnt);
|
||||
MemCpy(ptr,&h,sizeof(SpanHeader));
|
||||
ptr+=sizeof(SpanHeader);
|
||||
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
MemCpy(ptr,&tmpm->start,M_SIZE);
|
||||
ptr+=M_SIZE;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
MemCpy(ptr,&tmps->start,S_SIZE);
|
||||
ptr+=S_SIZE;
|
||||
tmps=tmps->next;
|
||||
}
|
||||
if (_size) *_size=cnt;
|
||||
return res;
|
||||
}
|
||||
|
||||
Bool SpanWrite(CMathODE *ode)
|
||||
{
|
||||
U8 *name,*buf;
|
||||
I64 size;
|
||||
Bool res=FALSE,old_silent=Silent;
|
||||
MkDir("~/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;
|
||||
|
||||
MemCpy(&h,src,sizeof(SpanHeader));
|
||||
src+=sizeof(SpanHeader);
|
||||
|
||||
for (i=0;i<h.num_masses;i++) {
|
||||
tmpm=CAlloc(sizeof(MyMass));
|
||||
MemCpy(&tmpm->start,src,M_SIZE);
|
||||
src+=M_SIZE;
|
||||
QueIns(tmpm,ode->last_mass);
|
||||
}
|
||||
|
||||
for (i=0;i<h.num_springs;i++) {
|
||||
tmps=CAlloc(sizeof(MySpring));
|
||||
MemCpy(&tmps->start,src,S_SIZE);
|
||||
src+=S_SIZE;
|
||||
QueIns(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;
|
||||
MkDir("~/Span");
|
||||
Silent(old_silent);
|
||||
if (name=PopUpPickFile("~/Span")) {
|
||||
src=FileRead(name);
|
||||
Free(name);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user