📄 xhamster.c
字号:
/* --- evaluate command --- */ switch (cmd) { /* evaluate command read */ case '@': /* --- error in child process */ stop((id) ? E_EXEC : E_POPEN); return; /* stop execution */ case 'c': /* --- create hamster */ if (hamster) { /* if a hamster already exists */ sprintf(hmscb[0].reply, "c -1\n"); break; /* deny creation request and */ } /* abort command evaluation */ hmscb[0].sprite = /* create a sprite */ spr_create(w_maze, SPRITEWD, SPRITEWD, hms_bmap, red); if (!hmscb[0].sprite) { stop(E_NOMEM); return; } hmscb[0].hamster = /* create a hamster */ hamster = hms_create(maze, 0, HMS_EAST, hms_disp); if (!hamster) { stop(E_NOMEM); return; } hms_pos(hamster, &x, &y); /* get hamster position */ sprintf(hmscb[0].reply, "c %d %d %d %d %d %d %d\n", hms_id(hamster), x, y, hms_dir(hamster), hms_look(hamster), hms_corn(hamster), hms_load(hamster)); break; /* send hamster data */ case 'd': /* --- delete hamster */ fprintf(p_out, "d 0\n"); /* echo delete command, */ fflush(p_out); /* flush pipe buffer */ stop(E_NONE); return; /* and stop execution */ case 'm': /* --- move hamster */ hms_move(hamster); /* move hamster forward */ hms_pos(hamster, &x, &y); /* and get new position */ sprintf(hmscb[id].reply, "m %d %d %d %d %d\n", hms_id(hamster), x, y, hms_look(hamster), hms_corn(hamster)); break; /* reply with new hamster data */ case 't': /* --- turn hamster */ hms_turn(hamster, arg); /* turn hamster around */ sprintf(hmscb[id].reply, "t %d %d %d\n", hms_id(hamster), hms_dir(hamster), hms_look(hamster)); break; /* reply with new hamster data */ case 'l': /* --- take/drop corn */ hms_take(hamster, arg); /* take/drop some corn */ sprintf(hmscb[id].reply, "l %d %d %d\n", hms_id(hamster), hms_corn(hamster), hms_load(hamster)); break; /* send new hamster data */ default: /* --- unknown command */ stop(E_PREAD); return; /* stop execution */ } if (!spr_busy(hmscb[id].sprite)) /* if the sprite is not busy, */ reply(NULL, NULL, NULL); /* send reply directly */} /* icb_pipe() *//*--------------------------------------------------------------------*/static void start (void){ /* --- start hamster */ int p2c[2]; /* pipe from parent to child */ int c2p[2]; /* pipe from child to parent */ int fd_out, fd_in; /* buffers for file descriptors */ if (running) return; /* if hamster is running, abort */ mn_visible(menu, MN_ITEMS, 5);/* show/hide menu items */ mn_enable (menu, MN_ITEMS, 4);/* enable/disable menu items */ #ifdef DEMO /* for the demonstration version */ { FILE *t; /* wait for a file `demo' */ do { t = fopen("demo", "r");/* to be created, before */ } while (!t); fclose(t); } /* starting the hamster */ #endif if ((pipe(p2c) != 0) || (pipe(c2p) != 0)) { error(E_POPEN); return; } /* create pipes and */ pid = fork(); /* fork child process */ if (pid == -1) { error(E_FORK); return; } /* --- child process --- */ if (pid == 0) { /* if this is the child process */ close(STDOUT_FILENO); /* connect first pipe to stdout */ fd_out = dup2(c2p[1], STDOUT_FILENO); close(STDIN_FILENO); /* connect second pipe to stdin */ fd_in = dup2(p2c[0], STDIN_FILENO); close(c2p[0]); close(c2p[1]); /* close pipe handles */ close(p2c[0]); close(p2c[1]); /* and check for success */ if ((fd_out != STDOUT_FILENO) || (fd_in != STDIN_FILENO)) { printf("@ 0\n"); fflush(stdout); _exit(-1); } execl(appdata.fn_hms, appdata.fn_hms, NULL); printf("@ 1\n"); fflush(stdout); _exit(-1); } /* execute child program */ /* --- parent process --- */ close(p2c[0]); close(c2p[1]); /* close child ends of pipes */ p_in = fdopen(c2p[0], "r"); /* if this is the parent process, */ p_out = fdopen(p2c[1], "w"); /* open streams on both pipes */ if (!p_in || !p_out) { /* and check for success */ close(p2c[1]); close(c2p[0]); kill(pid, SIGKILL); error(E_POPEN); return; /* if an error occurred, */ } /* close pipes and terminate child */ ip_pipe = XtAppAddInput(appctx, c2p[0], (XtPointer)XtInputReadMask, icb_pipe, NULL); /* install pipe read procedure */ running = 1; /* set running flag and resize window */ resize(appdata.xext, appdata.yext);} /* start() *//*---------------------------------------------------------------------- Action Functions----------------------------------------------------------------------*/static void load (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- File > (Re)Load Maze... */ CCHAR *t; /* buffer for dialog box title */ if (running || (*c != 1)) /* if running or wrong number */ return; /* of arguments, abort function */ if (((*s)[0] == '0') /* if to reload maze */ && (strcmp(appdata.fn_maze, NONAME) != 0)) dcb_load(NULL, (void*)1, appdata.fn_maze); else { /* if to load new maze */ mn_enable(menu, MN_MENU, 0);/* disable menu bar */ XtVaGetValues(XtNameToWidget(mn_menubar(menu), "*load"), XtNlabel, &t, NULL); /* get menu item text */ if (fselect(w_top, t, NULL, NULL, dcb_load) != 0) { error(E_DIALOG); mn_enable(menu, MN_MENU, 1); } } /* get maze file name */} /* load() *//*--------------------------------------------------------------------*/static void save (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- File > Save Maze... */ CCHAR *t; /* buffer for dialog box title */ if (running || (*c != 1)) /* if running or wrong number */ return; /* of arguments, abort function */ if (((*s)[0] == '0') /* if to save maze */ && (strcmp(appdata.fn_maze, NONAME) != 0)) dcb_save(NULL, (void*)1, appdata.fn_maze); else { /* if to save under a new name */ mn_enable(menu, MN_MENU, 0);/* disable menu bar */ XtVaGetValues(XtNameToWidget(mn_menubar(menu), "*save"), XtNlabel, &t, NULL); /* get menu item text */ if (fselect(w_top, t, NULL, NULL, dcb_save) != 0) { error(E_DIALOG); mn_enable(menu, MN_MENU, 1); } } /* get maze file name */} /* save() *//*--------------------------------------------------------------------*/static void select (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- File > Select Hamster... */ CCHAR *t; /* buffer for dialog box title */ if (running) return; /* get name of hamster file to load */ mn_enable(menu, MN_MENU, 0); /* disable menu bar */ XtVaGetValues(XtNameToWidget(mn_menubar(menu), "*select"), XtNlabel, &t, NULL); /* get menu item text */ if (fselect(w_top, t, NULL, NULL, dcb_select) != 0) { error(E_DIALOG); mn_enable(menu, MN_MENU, 1); }} /* select() *//*--------------------------------------------------------------------*/static void quit (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- File > Quit */ if (running) stop(E_NONE); /* if hamster is running, stop it */ if (w_top) XtDestroyApplicationContext(appctx); exit(0); /* terminate program */} /* quit() *//*--------------------------------------------------------------------*/static void redraw (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Redraw */ XRectangle rc; /* clipping rectangle */ int xext, yext; /* maze extension */ int x, y; /* loop variables */ int t; /* result of spr_undraw */ if (!gc) { /* if graphics context not created */ gc = XCreateGC(display, window, 0, NULL); if (!gc) { error(E_GRAPH); return; } } /* create a graphics context */ if (e && (e->type == Expose)){/* if called by Xt, */ rc.x = e->xexpose.x; /* build and set */ rc.y = e->xexpose.y; /* clipping rectangle */ rc.width = e->xexpose.width; rc.height = e->xexpose.height; XSetClipRectangles(display, gc, 0, 0, &rc, 1, Unsorted); } t = (hmscb[0].sprite) /* undraw sprite */ ? spr_undraw(hmscb[0].sprite) : 1; mz_exts(maze, &xext, &yext); /* get maze extensions */ for (x = xext; --x >= 0; ) /* traverse columns */ for (y = yext; --y >= 0; ) /* traverse lines of column */ draw_field(x, y); /* and draw field */ if (t == 0) /* if sprite was drawn, redraw it */ spr_draw(hmscb[0].sprite, INT_MIN, INT_MIN); if (!running) /* if not running, */ mn_info(menu, ""); /* clear the score */ XFlush(display); /* flush buffered drawing commands */ XSetClipMask(display, gc, None); /* and clear clipping mask */} /* redraw() *//*--------------------------------------------------------------------*/static void size (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Set Maze Size... */ static char buf[16]; /* buffer to format values */ if (running) return; /* if a hamster is running, abort */ if (!psh_size) { /* if dialog box is not created */ psh_size = psh_create("sizeDlg", w_top, 1); if (!psh_size) return; /* create a property sheet */ if ((psh_addline(psh_size, "xExtLabel") != 0) || (psh_additem(psh_size, "xExt", PSH_EDIT, 0) != 0) || (psh_addline(psh_size, "yExtLabel") != 0) || (psh_additem(psh_size, "yExt", PSH_EDIT, 0) != 0)) { psh_delete(psh_size); error(E_WIDGET); } } /* set browse button callback */ mn_enable(menu, MN_MENU, 0); /* disable menu bar */ sprintf(buf, "%d", appdata.xext); psh_setval(psh_size, "xExt", buf); sprintf(buf, "%d", appdata.yext); psh_setval(psh_size, "yExt", buf); psh_handle(psh_size, dcb_size); /* set values and handle dialog */} /* size() *//*--------------------------------------------------------------------*/static void random (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Randomize Maze... */ static char buf[16]; /* buffer to format values */ if (running) return; /* if a hamster is running, abort */ if (!psh_random) { /* if dialog box is not created */ psh_random = psh_create("randomDlg", w_top, 1); if (!psh_random) return; /* create a property sheet */ if ((psh_addline(psh_random, "wallProbLabel") != 0) || (psh_additem(psh_random, "wallProb", PSH_EDIT, 0) != 0) || (psh_addline(psh_random, "totalLabel") != 0) || (psh_additem(psh_random, "total", PSH_EDIT, 0) != 0) || (psh_addline(psh_random, "maxHeapLabel") != 0) || (psh_additem(psh_random, "maxHeap", PSH_EDIT, 0) != 0)) { psh_delete(psh_random); error(E_WIDGET); } } /* set browse button callback */ mn_enable(menu, MN_MENU, 0); /* disable menu bar */ sprintf(buf, "%d", (int)(appdata.wallprob *100 +0.5)); psh_setval(psh_random, "wallProb", buf); sprintf(buf, "%d", appdata.total); psh_setval(psh_random, "total", buf); sprintf(buf, "%d", appdata.maxheap); psh_setval(psh_random, "maxHeap", buf); psh_handle(psh_random, dcb_random); /* set values and handle dialog */} /* random() *//*--------------------------------------------------------------------*/static void speed (Widget w, XEvent *e, String *s, Cardinal *c){ /* --- Actions > Set Hamster Speed... */ static char buf[16]; /* buffer to format values */ if (!psh_speed) { /* if dialog box is not created */ psh_speed = psh_create("speedDlg", w_top, 1); if (!psh_speed) return; /* create a property sheet */ if ((psh_addline(psh_speed, "speedLabel") != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -