From: ian Date: Sun, 26 Jun 2005 17:48:03 +0000 (+0000) Subject: display much better and does edges too X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=27048c69019784e3a346bdcd33e9046bb30d90d1;p=trains.git display much better and does edges too --- diff --git a/TODO b/TODO index 790488d..0c391e0 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ layout polarity diagram colourful segment encoding: - wire layout diagram thing into Tcl and see speed etc. make moveable feature selection in subseg2display bitwise rather than setwise +safety system no crashes at crossovers please + 1. Write lots and lots and lots of PIC programs diff --git a/hostside/__oop-read-copy.c b/hostside/__oop-read-copy.c index 8cd5c67..38cba00 100644 --- a/hostside/__oop-read-copy.c +++ b/hostside/__oop-read-copy.c @@ -236,7 +236,11 @@ static void *on_process(oop_source *oop, oop_read *rd, int try_read) { if (rd->discard) { rd->used -= rd->discard; - rd->neednotcheck -= rd->discard; + if (rd->neednotcheck > rd->discard) { + rd->neednotcheck -= rd->discard; + } else { + rd->neednotcheck= 0; + } memmove(buf, buf + rd->discard, rd->used); rd->discard= 0; } diff --git a/hostside/gui-displayer b/hostside/gui-displayer index 25f5caa..7a66bf3 100755 --- a/hostside/gui-displayer +++ b/hostside/gui-displayer @@ -34,6 +34,7 @@ proc update_push {} { # $power = 0 or 1 # $segrev($segname) = 0 or 1 # $segdet($segname) = 0 or 1 +# $segown($segname) = {} or t or f # $movpos($segname/$movfeat) = $pos (number) or {} meaning unknown proc P {onoff} { # power @@ -52,18 +53,21 @@ proc R {args} { # reverse segnames update_push } -proc D0 {args} { train_presence 0 $args } -proc D1 {args} { train_presence 1 $args } - -proc train_presence {yn l} { +proc setsegs {segfoo value l} { foreach segname $l { - upvar #0 segdet($segname) d - set d $yn + upvar #0 ${segfoo}($segname) d + set d $value update_seg $segname } update_push } +proc D0 {args} { setsegs segdet 0 $args } +proc D1 {args} { setsegs segdet 1 $args } +proc OT {args} { setsegs segown t $args } +proc OF {args} { setsegs segown f $args } +proc ON {args} { setsegs segown {} $args } + proc M {segname mp {movfeat P}} { # mp==x is unknown upvar #0 movpos($segname/$movfeat) p upvar #0 movconfs($segname/$movfeat) n @@ -82,6 +86,7 @@ proc update_allsegs {} { proc update_seg {segname} { upvar #0 segrev($segname) r upvar #0 segdet($segname) d + upvar #0 segown($segname) o upvar #0 segmovs($segname) movs global power @@ -92,6 +97,7 @@ proc update_seg {segname} { } else { set command [expr {$d ? "det" : "on"}] if {$r} { set command "i$command" } + set command $o$command } setsegbyname $segname $command @@ -108,7 +114,7 @@ proc update_seg {segname} { proc setup {} { global segnum segmovs movconfs - global power segrev segdet movpos + global power segrev segdet segown movpos set power 0 set f [open ../layout/ours.dgram-bot.segcmap] while {[gets $f l] >= 0} { @@ -117,6 +123,7 @@ proc setup {} { set segmovs($segname) {} set segrev($segname) 0 set segdet($segname) 0 + set segown($segname) {} } elseif {[regexp {^F (\w+) \w+ (\w+) \w+ (\w+)$} \ $l dummy segname movfeat mc]} { set segnum($segname) diff --git a/hostside/gui-plan.c b/hostside/gui-plan.c index 1f0b62e..0dc518d 100644 --- a/hostside/gui-plan.c +++ b/hostside/gui-plan.c @@ -3,8 +3,8 @@ * protocol on stdin: * series of lines * off [/[] - * [i]on [[/] ] - * [i]det [[/] ] + * [t|f][i]on [[/] ] + * [t|f][i]det [[/] ] */ #include @@ -21,23 +21,24 @@ #include #include -typedef struct PosnState PosnState; -struct PosnState { - int x, y, width, height; - Pixmap pm; -}; - typedef struct MaskState MaskState; struct MaskState { int x, y, width, height; GC gc; }; +typedef struct PosnState PosnState; +struct PosnState { + int x, y, width, height; + Pixmap pm; + MaskState edge; +}; + typedef struct SegmovfeatState SegmovfeatState; struct SegmovfeatState { SegmovfeatState *next; - int invert, det, posn, redraw_needed; - MaskState mask; + int invert, det, trainown, posn, redraw_needed; + MaskState whole; PosnState (*posns)[2/*i*/][2/*det*/]; /* posns[n_posns]=unknown if n_posns>1 */ }; @@ -50,6 +51,7 @@ static oop_source_sys *sys_events; static Window w; static int redraw_needed_count, expose_count; static Pixmap bg_pixmap; +static unsigned long train_pixel, owned_pixel; static void diex(const char *fn, const char *w) __attribute__((noreturn)); static void diex(const char *fn, const char *w) { @@ -138,9 +140,9 @@ static void xlib_expose(XExposeEvent *ev) { fs= fs->next) { if (fs->redraw_needed) continue; - if (!range_overlap(fs->mask.x, fs->mask.width, + if (!range_overlap(fs->whole.x, fs->whole.width, ev->x, ev->width)) continue; - if (!range_overlap(fs->mask.y, fs->mask.height, + if (!range_overlap(fs->whole.y, fs->whole.height, ev->y, ev->height)) continue; fs->redraw_needed= 1; redraw_needed_count++; @@ -149,24 +151,34 @@ static void xlib_expose(XExposeEvent *ev) { static void redraw(SegmovfeatState *fs) { PosnState *src; + XGCValues gcv; if (fs->redraw_needed) { fs->redraw_needed= 0; redraw_needed_count--; } - if (fs->invert < 0) { - XCALL( XCopyArea, "redraw", - (d, bg_pixmap, w, fs->mask.gc, - fs->mask.x, fs->mask.y, - fs->mask.width, fs->mask.height, - fs->mask.x, fs->mask.y) ); - } else { + src= 0; + XCALL( XCopyArea, "redraw", + (d, bg_pixmap, w, fs->whole.gc, + fs->whole.x, fs->whole.y, + fs->whole.width, fs->whole.height, + fs->whole.x, fs->whole.y) ); + if (fs->invert >= 0) { src= &fs->posns[fs->posn][fs->invert][fs->det]; XCALL( XCopyArea, "redraw", - (d, src->pm, w, fs->mask.gc, + (d, src->pm, w, fs->whole.gc, 0,0, src->width, src->height, src->x, src->y) ); } + if (fs->trainown && src && src->edge.x >= 0) { + gcv.foreground= fs->trainown>1 ? train_pixel : owned_pixel; + XCALL( XChangeGC, "train/own", + (d, src->edge.gc, GCForeground, &gcv) ); + XCALL( XFillRectangle, "train/own", + (d,w, src->edge.gc, + src->edge.x, src->edge.y, + src->edge.width, src->edge.height) ); + } } static void redraw_as_needed(void) { @@ -210,13 +222,21 @@ static void *xlib_readable(oop_source *evts, int fd, xlib_process(); return OOP_CONTINUE; } - + +static int thiswordeatonechar(ParseState *ps, int c) { + if (ps->thisword[0] == c) { + ps->thisword++; ps->lthisword--; + return 1; + } + return 0; +} + static void *stdin_ifok(oop_source *evts, oop_read *cl_read, oop_rd_event evt, const char *errmsg, int errnoval, const char *data, size_t recsz, void *cl_v) { const char *slash, *movfeatname; ParseState ps; - int invert, det, segment_ix, movfeat_ix, lmovfeatname; + int invert, det, trainown, segment_ix, movfeat_ix, lmovfeatname; long posn; const PlanSegmentData *segment_d; const PlanSegmovfeatData *movfeat_d; @@ -236,8 +256,10 @@ static void *stdin_ifok(oop_source *evts, oop_read *cl_read, invert= -1; det= 0; } else { - invert= (ps.thisword[0]=='i'); - if (invert) { ps.thisword++; ps.lthisword--; } + trainown= + thiswordeatonechar(&ps,'t') ? 2 : + thiswordeatonechar(&ps,'f') ? 1 : 0; + invert= thiswordeatonechar(&ps,'i'); det= (!thiswordstrcmp(&ps,"on") ? 0 : !thiswordstrcmp(&ps,"det") ? 1 : (badcmd(&ps,"unknown command"),-1)); @@ -278,6 +300,7 @@ static void *stdin_ifok(oop_source *evts, oop_read *cl_read, fs= &state[segment_ix][movfeat_ix]; fs->invert= invert; fs->det= det; + fs->trainown= trainown; fs->posn= posn; redraw(fs); @@ -286,22 +309,47 @@ static void *stdin_ifok(oop_source *evts, oop_read *cl_read, return OOP_CONTINUE; } -int main(int argc, const char *const *argv) { +static void loadmask(MaskState *out, const PlanPixmapDataRef *ppd, + XGCValues *gcv, long gcv_mask) { static XpmColorSymbol coloursymbols[2]= { { (char*)"space", 0, 0 }, { (char*)"mark", 0, 1 } }; + XpmAttributes mattribs; + Pixmap pm; + + out->x= ppd->x; + out->y= ppd->y; + mattribs.valuemask= XpmDepth | XpmColorSymbols; + mattribs.depth= 1; + mattribs.colorsymbols= coloursymbols; + mattribs.numsymbols= sizeof(coloursymbols) / sizeof(*coloursymbols); + XPMCALL( XpmCreatePixmapFromData, "mask", + (d,w, (char**)ppd->d, &pm,0, &mattribs) ); + out->width= mattribs.width; + out->height= mattribs.height; + + gcv->clip_x_origin= out->x; + gcv->clip_y_origin= out->y; + gcv->clip_mask= pm; + out->gc= XCreateGC(d,w, + gcv_mask | GCClipXOrigin | GCClipYOrigin | GCClipMask, + gcv); + XCALL( XFreePixmap, "mask", (d,pm) ); +} + +int main(int argc, const char *const *argv) { oop_read *rd; const char *arg; - Pixmap mask; XpmAttributes mattribs; XWindowAttributes wattribs; int segment_ix, movfeat_ix, posn, invert, det, oor; + XGCValues gcv; + XColor colour; SegmovfeatState *fs; const PlanSegmentData *segment_d; const PlanSegmovfeatData *movfeat_d; - XGCValues gcv; d= XOpenDisplay(0); if (!d) die("XOpenDisplay failed"); @@ -332,6 +380,16 @@ int main(int argc, const char *const *argv) { XCALL( XSetWindowBackgroundPixmap, 0, (d,w,bg_pixmap) ); + XCALL( XAllocNamedColor, "white", + (d, wattribs.colormap, "#ffffff", + &colour, &colour) ); + train_pixel= colour.pixel; + + XCALL( XAllocNamedColor, "owned", + (d, wattribs.colormap, "#a0a0a0", + &colour, &colour) ); + owned_pixel= colour.pixel; + state= mmalloc(sizeof(*state) * ui_plan_data.n_segments); for (segment_ix= 0, segment_d= ui_plan_data.segments; segment_ix < ui_plan_data.n_segments; @@ -344,36 +402,23 @@ int main(int argc, const char *const *argv) { fs->next= states_head; states_head= fs; fs->invert= -1; fs->det= 0; + fs->trainown= 0; fs->posn= movfeat_d->n_posns; if (fs->posn==1) fs->posn= 0; - fs->mask.x= movfeat_d->mask.x; - fs->mask.y= movfeat_d->mask.y; fs->redraw_needed= 0; - - mattribs.valuemask= XpmDepth | XpmColorSymbols; - mattribs.depth= 1; - mattribs.colorsymbols= coloursymbols; - mattribs.numsymbols= sizeof(coloursymbols) / sizeof(*coloursymbols); - XPMCALL( XpmCreatePixmapFromData, "mask", - (d,w, (char**)movfeat_d->mask.d, &mask,0, &mattribs) ); - fs->mask.width= mattribs.width; - fs->mask.height= mattribs.height; - - gcv.clip_x_origin= fs->mask.x; - gcv.clip_y_origin= fs->mask.y; - gcv.clip_mask= mask; - fs->mask.gc= XCreateGC(d,w, - GCClipXOrigin | GCClipYOrigin | GCClipMask, - &gcv); - XCALL( XFreePixmap, "mask", (d,mask) ); + + loadmask(&fs->whole, &movfeat_d->mask, &gcv, 0); fs->posns= mmalloc(sizeof(*fs->posns)*(fs->posn+1)); for (posn= 0; posn <= fs->posn; posn++) for (invert=0; invert<2; invert++) for (det=0; det<2; det++) { PosnState *ps= &fs->posns[posn][invert][det]; - const PlanPixmapDataRef *ppdr= posn < movfeat_d->n_posns - ? &movfeat_d->posns[posn].on[invert][det] + const PlanPixmapOnData *ppod= + posn < movfeat_d->n_posns + ? &movfeat_d->posns[posn] : 0; + const PlanPixmapDataRef *ppdr= ppod + ? &ppod->on[invert][det] : &movfeat_d->unknown[invert][det]; ps->x= ppdr->x; ps->y= ppdr->y; @@ -385,6 +430,12 @@ int main(int argc, const char *const *argv) { 0, &mattribs) ); ps->width= mattribs.width; ps->height= mattribs.height; + if (ppod) { + loadmask(&ps->edge, &ppod->pedge, &gcv, 0); + } else { + ps->edge.x= -1; + ps->edge.gc= None; + } } } } diff --git a/layout/layout b/layout/layout index 0a1f6fa..3f5f6b5 100755 --- a/layout/layout +++ b/layout/layout @@ -158,7 +158,7 @@ our $psu_sleeperlw= 15; our $psu_raillw= 1.0; our $psu_thinlw= 1.0; our %psu_subseglw; -$psu_subseglw{'e'}= 25.0; +$psu_subseglw{'e'}= 20.0; $psu_subseglw{'m'}= 15.0; our $lmu_marklw= 4; diff --git a/layout/plan-to-gui-data b/layout/plan-to-gui-data index 52c1149..6b6e323 100755 --- a/layout/plan-to-gui-data +++ b/layout/plan-to-gui-data @@ -344,6 +344,7 @@ sub angle_to_colour ($) { [ $U, 0, $D ], [ 1, $u, $d ])[$s]; $R->[1] *= 0.9; + $R->[2] *= 0.9; return @$R; } @@ -389,8 +390,8 @@ sub cmaps_define () { ' ', @background, '!', @otherposn); } - xpm_cmap_angular("${inv}on", !!$inv, 600, qw(0 0 0)); - xpm_cmap_angular("${inv}det",!!$inv, 330, qw(1000 1000 1000)); + xpm_cmap_angular("${inv}on", !!$inv, 650, qw(0 0 0)); + xpm_cmap_angular("${inv}det",!!$inv, 650, qw(1000 1000 1000)); } }