#include #include #include #include "smaze.h" extern unsigned long Step, GoalCount; static Widget Monitor = NULL; static Boolean MonitorOn = False; static Window MonitorWindow; static Pixmap MonitorPixmap = 0; static unsigned int Mwidth, Mheight; static Pixel Mfg, Mbg; #define MXtitle "steps" #define MYoffset 20 static int MXoffset, MYspan, MXtitleX, MXtitleY, MXbase, MYbase; #define MaxNCaptured 10000 static unsigned long NCaptured = 0; static struct { unsigned long step, count; } Record[MaxNCaptured]; extern XFontStruct *stepFont; static int get_tic_span(max,bias) int max, *bias; { int exp = 1; while (max >= 10) { max = (max + 9) / 10; exp *= 10; } *bias = (exp < 10)? 1 : exp / 10; if (exp < 10) return 1; else if (max < 2) return exp/10; else if (max < 3) return 2 * exp/10; else if (max < 5) return 5 * exp/10; else return exp; } #define get_x(i) (((i) * (Mwidth-MXoffset)) / xspan + MXoffset) #define get_y(i) ((GoalCount-(i))*MYspan/GoalCount + MYoffset) displayMonitor() { int i, yorigin = MYoffset+MYspan, xspan = 10; int itic, bias, oldx, newx, y, oldy; char buf[32]; extern Display *dpy; extern GC gc; if (NCaptured > 0 && Record[NCaptured-1].step == Step) i = NCaptured - 1; else { i = NCaptured; if (NCaptured < MaxNCaptured-1) NCaptured ++; } Record[i].step = Step; Record[i].count = GoalCount; if (!MonitorOn) return 0; XSetForeground(dpy,gc,Mbg); XFillRectangle(dpy,MonitorPixmap,gc,0,0,Mwidth,Mheight); XSetForeground(dpy,gc,Mfg); XDrawString(dpy,MonitorPixmap,gc, MXtitleX,MXtitleY,MXtitle,strlen(MXtitle)); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,yorigin,MXoffset,0); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,yorigin,Mwidth-1,yorigin); if (Step > xspan) xspan = Step; itic = get_tic_span(xspan,&bias); if (bias < 10000) bias = 1; else { sprintf(buf," x %d",bias); XDrawString(dpy,MonitorPixmap,gc, Mwidth-XTextWidth(stepFont,buf,strlen(buf))-5, MXtitleY,buf,strlen(buf)); } for (i = 0; i <= Step; i += itic) { oldx = get_x(i); XDrawLine(dpy,MonitorPixmap,gc,oldx,yorigin-5,oldx,yorigin); sprintf(buf,"%d",i/bias); oldx -= XTextWidth(stepFont,buf,strlen(buf))/2; XDrawString(dpy,MonitorPixmap,gc,oldx,MXbase,buf,strlen(buf)); } itic = get_tic_span(GoalCount,&bias); for (i = 0; i <= GoalCount; i += itic) { y = get_y(i); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,y,MXoffset+5,y); sprintf(buf,"%d",i); oldx = MXoffset - XTextWidth(stepFont,buf,strlen(buf)) - 2; XDrawString(dpy,MonitorPixmap,gc,oldx,y,buf,strlen(buf)); } oldx = MXoffset; oldy = yorigin; for (i = 1; i < NCaptured; i ++) { newx = get_x(Record[i].step); y = get_y(Record[i].count); XDrawLine(dpy,MonitorPixmap,gc,oldx,oldy,newx,y); oldy = y; oldx = newx; } XCopyArea(dpy,MonitorPixmap,MonitorWindow,gc,0,0,Mwidth,Mheight,0,0); } static void redisplayMonitorCB(w,cl,cd) Widget w; XtPointer cl,cd; { XEvent *e = ((XmDrawingAreaCallbackStruct *)cd)->event; if (MonitorPixmap) XCopyArea(dpy,MonitorPixmap,MonitorWindow,gc, e->xexpose.x,e->xexpose.y,e->xexpose.width,e->xexpose.height, e->xexpose.x,e->xexpose.y); } monitor_reset() { NCaptured = 0; if (Monitor) { XSetForeground(dpy,gc,Mbg); XFillRectangle(dpy,MonitorPixmap,gc,0,0,Mwidth,Mheight); } } monitor_init() { Widget work; Window root; int x, y; unsigned int border,depth; extern Widget app_sh; Monitor = XtCreatePopupShell("Monitor", topLevelShellWidgetClass,app_sh,NULL,0); XtManageChild(work=XmCreateDrawingArea(Monitor,"work",NULL,0)); XtAddCallback(work,XmNexposeCallback,redisplayMonitorCB,NULL); XtPopup(Monitor,XtGrabNone); MonitorWindow = XtWindow(work); XGetGeometry(dpy,MonitorWindow,&root,&x,&y, &Mwidth,&Mheight,&border,&depth); MonitorPixmap = XCreatePixmap(dpy,root,Mwidth,Mheight,depth); XtVaGetValues(work,XmNforeground,&Mfg,XmNbackground,&Mbg,NULL); MXoffset = XTextWidth(stepFont," 9.999",6); MYspan = Mheight - MYoffset - (stepFont->max_bounds.ascent+stepFont->max_bounds.descent)*2 - 6; MXtitleX = (Mwidth-MXoffset -XTextWidth(stepFont,MXtitle,strlen(MXtitle)))/2 + MXoffset; MXtitleY = Mheight - stepFont->max_bounds.descent - 2; MXbase = MYoffset + MYspan + stepFont->max_bounds.ascent + 2; } Widget create_monitor_shell() { if (!Monitor) monitor_init(); return Monitor; } monitor_switch(flag) int flag; { MonitorOn = flag; } pointer_proc(x,y,b) int x,y,b; { extern Agent A; printf("(%d,%d) U:%g,D:%g,L:%g,R:%g\n",x,y, A.QTable[y][x][ActionUp],A.QTable[y][x][ActionDown], A.QTable[y][x][ActionLeft],A.QTable[y][x][ActionRight]); }