Beispiel #1
0
void action(mapping roles)
{
	object exit;
	object target;
	object actor;
	object retexit;

	actor = roles["actor"];
	exit = roles["dob"];

	retexit = exit->query_property("exit_return");

	if (retexit) {
		target = retexit->query_environment();

		if (!target) {
			send_out("Oops, " + TEXT_SUBD->generate_brief_definite(exit) + "'s return exit is lost in the void.\n");
			return;
		}
	} else {
		target = exit->query_property("exit_destination");
	}

	if (!target) {
		send_out("Oops, " + TEXT_SUBD->generate_brief_definite(exit) + " doesn't have a destination.\n");
		return;
	}

	if (actor->query_property("is_immobile")) {
		send_out("You're stuck like glue and can't move.\n");
		return;
	}

	if (query_user()->query_class() >= 2) {
		emit_from(actor, actor, " ", ({ "leave", "leaves" }), " through ", exit, ".");
Beispiel #2
0
void
ve_delete_char (DESCRIPTOR_DATA * c, size_t backup)
{
  int lines_offset;
  int i;
  char *line_ptr;
  char buf[MAX_STRING_LENGTH];

  if (c->col <= 1)
    {				/* Backing up too far */
      ve_beep (c);
      return;
    }

  lines_offset = c->tos_line + c->line - 1;

  line_ptr = c->lines->line[lines_offset];

  if (!line_ptr)
    {
      c->col = 1;
      ve_position (c);
      return;
    }

  if (c->col - backup > strlen (line_ptr))
    {				/* Beyond end of line */
      c->col = strlen (line_ptr) + 1;
      if (!backup)
	c->col--;
      ve_position (c);
      return;
    }

  strcpy (buf, line_ptr);

  c->col -= backup;

  for (i = c->col - 1; buf[i]; i++)
    buf[i] = buf[i + 1];

  mem_free (line_ptr);

  c->lines->line[lines_offset] = str_dup (buf);

  ve_goto (c, c->line, 1);

  send_out (c, c->lines->line[lines_offset]);

  ve_goto (c, c->line, strlen (buf) + 1);
  send_out (c, " ");

  ve_position (c);
}
static int
message_handler(struct skynet_context * ctx, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
	struct package *P = ud;
	switch (type) {
	case PTYPE_TEXT:
		command(ctx, P, session, source, msg, sz);
		break;
	case PTYPE_CLIENT:
		send_out(ctx, P, msg, sz);
		break;
	case PTYPE_RESPONSE:
		// It's timer
		heartbeat(ctx, P);
		break;
	case PTYPE_SOCKET:
		socket_message(ctx, P, msg);
		break;
	case PTYPE_ERROR:
		// ignore error
		break;
	default:
		if (session > 0) {
			// unsupport type, raise error
			skynet_send(ctx, 0, source, PTYPE_ERROR, session, NULL, 0);
		}
		break;
	}
	return 0;
}
Beispiel #4
0
void begin()
{
	int i;

	ACCESS_CHECK(previous_object() == query_user());

	::begin();

	speed = 5.0;
	send_out("\033[1;1H\033[2J");

	particles = allocate(NPARTICLES);

	for (i = 0; i < NPARTICLES; i++) {
		float *particle;
		particle = particles[i] = allocate_float(3);

		do {
			particle[2] = (1.0 - pow(MATHD->rnd(), 2.0)) * 11.0;
		} while (particle[2] < 1.0);

		particle[0] = (MATHD->rnd() * 80.0 - 40.0) * particle[2];
		particle[1] = (MATHD->rnd() * 27.5 - 15.0) * particle[2];
	}
}
Beispiel #5
0
void
ve_beep (DESCRIPTOR_DATA * c)
{
  char *buf = "\07";

  send_out (c, buf);
}
Beispiel #6
0
static void send_next(AVFilterContext *ctx)
{
    AStreamSyncContext *as = ctx->priv;
    int i;

    while (1) {
        if (!as->queue[as->next_out].nb)
            break;
        send_out(ctx, as->next_out);
        if (!as->eof)
            as->next_out = av_expr_eval(as->expr, as->var_values, NULL) >= 0;
    }
    for (i = 0; i < 2; i++)
        if (as->queue[i].nb == QUEUE_SIZE)
            send_out(ctx, i);
}
Beispiel #7
0
void
ve_goto (DESCRIPTOR_DATA * c, int line, int col)
{
  char buf[MAX_STRING_LENGTH];

  sprintf (buf, "\033[%d;%dH", line, col);

  send_out (c, buf);
}
Beispiel #8
0
static int
pk_decode_bitmap (pdf_obj *stream, long wd, long ht,
                  int dyn_f, int run_color, unsigned char *dp, long pl)
{
  unsigned char  *rowptr, c;
  long            i, j, rowbytes;
  const static unsigned char mask[8] = {
    0x80u, 0x40u, 0x20u, 0x10u, 0x08u, 0x04u, 0x02u, 0x01u
  };

  ASSERT( dyn_f == 14 );
  if (run_color != 0) {
    WARN("run_color != 0 for bitmap pk data?");
  } else if (pl < (wd * ht + 7) / 8) {
    WARN("Insufficient bitmap pk data. %ldbytes expected but only %ldbytes read.",
         (wd * ht + 7) / 8, pl);
    return  -1;
  }

  rowbytes = (wd + 7) / 8;
  rowptr   = NEW(rowbytes, unsigned char);
  memset(rowptr, 0, rowbytes);
  /* Flip. PK bitmap is not byte aligned for each rows. */
  for (i = 0, j = 0; i < ht * wd; i++) {
    c = dp[i / 8] & mask[i % 8];
    if (c == 0)
      rowptr[j / 8] |= mask[i % 8]; /* flip bit */
    j++;
    if (j == wd) {
#if  DEBUG == 2
      send_out(rowptr, rowbytes, wd, stream);
#else
      send_out(rowptr, rowbytes, stream);
#endif
      memset(rowptr, 0, rowbytes);
      j = 0;
    }
  }

  return  0;
}
Beispiel #9
0
void
ve_telnet_command (DESCRIPTOR_DATA * c, int subcmd, int action)
{
  char buf[4];

  buf[0] = IAC;
  buf[1] = subcmd;
  buf[2] = action;
  buf[3] = 0;

  send_out (c, buf);
}
Beispiel #10
0
void
ve_process (DESCRIPTOR_DATA * c, char *buf)
{
  while (*buf)
    {

      if (IS_SET (c->edit_mode, MODE_COMMAND))
	ve_command_mode (c, &buf);

      else
	ve_insert_mode (c, &buf);

      if (IS_SET (c->edit_mode, MODE_DONE_EDITING))
	{
	  ve_reconstruct (c);

	  ve_goto (c, 24, 1);

	  ve_telnet_command (c, DONT, TELOPT_SGA);

	  ve_telnet_command (c, DO, TELOPT_LINEMODE);
	  ve_telnet_command (c, WILL, TELOPT_LINEMODE);

	  /* linemode sub-negotiation - local edit mode */

	  ve_telnet_command (c, SB, TELOPT_LINEMODE);

	  buf[0] = LM_MODE;
	  buf[1] = MODE_EDIT;
	  buf[2] = IAC;
	  buf[3] = SE;		/* Stop subnegotion */
	  buf[4] = 0;

	  send_out (c, buf);

	  ve_telnet_command (c, WONT, TELOPT_ECHO);

	  c->character->act &= ~PLR_QUIET;

	  send_to_char ("Press return...your first command won't work\n\r",
			c->character);

	  if (c->proc)
	    (c->proc) (c);
	  else
	    printf ("NO PROC WAS SET.\n");

	  return;
	}
    }
}
Beispiel #11
0
void
ve_position (DESCRIPTOR_DATA * c)
{
  char buf[MAX_STRING_LENGTH];

  ve_goto (c, 24, 60);

  sprintf (buf, "%s%s [%d,%d]      ",
	   c->lines->line[c->line + c->tos_line - 1] ? " " : "*",
	   IS_SET (c->edit_mode, MODE_COMMAND) ? "Cmd" : "Ins",
	   c->line, c->col);
  send_out (c, buf);

  ve_goto (c, c->line, c->col);
}
Beispiel #12
0
void
ve_refresh_screen (DESCRIPTOR_DATA * c)
{
  char buf[MAX_STRING_LENGTH];

  sprintf (buf, "%s", HOME CLEAR);
  send_out (c, buf);

  if (IS_SET (c->edit_mode, MODE_VISMAP))
    ve_display_map (c);
  else
    {
      ve_repaint (c);
      ve_position (c);
    }
}
Beispiel #13
0
void begin()
{
	int i;

	ACCESS_CHECK(previous_object() == query_user());

	::begin();

	send_out("\033[1;1H\033[2J");

	particles = allocate(NPARTICLES);

	for (i = 0; i < NPARTICLES; i++) {
		particles[i] = allocate_float(4);
		particles[i][1] = 25.0;
	}
}
Beispiel #14
0
void
ve_repaint (DESCRIPTOR_DATA * c)
{
  int screen_line;
  char *line_ptr;

  for (screen_line = 1; screen_line < 23; screen_line++)
    {

      line_ptr = c->lines->line[c->tos_line - 1 + screen_line];

      if (!line_ptr)
	return;

      ve_goto (c, screen_line, 1);

      send_out (c, line_ptr);
    }
}
Beispiel #15
0
void
ve_insert_char (DESCRIPTOR_DATA * c, char add_char)
{
  char buf1[MAX_STRING_LENGTH];
  char *line_ptr;
  size_t insert_index;
  size_t i;
  int lines_offset;

  lines_offset = c->tos_line + c->line - 1;

  line_ptr = c->lines->line[lines_offset];

  insert_index = c->col - 1;

  /* Oh gosh...we need to space this out. */

  if (!line_ptr)
    {
      line_ptr = (char *) alloc (insert_index + 2, 9);	/* +1 for new ch; +1 for zero */

      for (i = 0; i < insert_index; i++)
	line_ptr[i] = ' ';

      line_ptr[insert_index] = '\0';
    }

  /* Maybe we need to add a few blank lines above us */

  for (int i = 1; i < lines_offset; i++) /* This may be a little wasteful */
    if (!c->lines->line[i])
      c->lines->line[i] = str_dup ("");

  if (strlen (line_ptr) >= 80)
    {
      ve_beep (c);
      return;
    }

  /* Grab part up to the insert */

  *buf1 = 0;

  if (strlen (line_ptr) < insert_index)
    {
      memcpy (buf1, line_ptr, strlen (line_ptr));
      for (i = strlen (line_ptr); i < insert_index; i++)
	buf1[i] = ' ';
    }
  else if (insert_index)
    memcpy (buf1, line_ptr, insert_index);

  buf1[insert_index] = add_char;	/* Add inserted character */
  buf1[insert_index + 1] = '\0';

  if (strlen (line_ptr) > insert_index)
    strcat (buf1, &line_ptr[insert_index]);

  c->lines->line[lines_offset] = str_dup (buf1);

  mem_free (line_ptr);

  ve_goto (c, c->line, 1);

  send_out (c, c->lines->line[lines_offset]);

  c->col++;

  ve_position (c);
}
Beispiel #16
0
static int
pk_decode_packed (pdf_obj *stream, long wd, long ht,
                  int dyn_f, int run_color, unsigned char *dp, long pl)
{
  unsigned char  *rowptr;
  long            rowbytes;
  long            i, np = 0;
  long            run_count = 0, repeat_count = 0;

  rowbytes = (wd + 7) / 8;
  rowptr   = NEW(rowbytes, unsigned char);
  /* repeat count is applied to the *current* row.
   * "run" can span across rows.
   * If there are non-zero repeat count and if run
   * spans across row, first repeat and then continue.
   */
#ifdef  DEBUG
  MESG("\npkfont>> wd: %ld, ht: %ld, dyn_f: %d\n", wd, ht, dyn_f);
#endif
  for (np = 0, i = 0; i < ht; i++) {
    long  rowbits_left, nbits;

    repeat_count = 0;
    memset(rowptr, 0xff, rowbytes); /* 1 is white */
    rowbits_left = wd;
    /* Fill run left over from previous row */
    if (run_count > 0) {
      nbits = MIN(rowbits_left, run_count);
      switch (run_color) {
      case  0:
        rowbits_left -= fill_black_run(rowptr, 0, nbits);
        break;
      case  1:
        rowbits_left -= fill_white_run(rowptr, 0, nbits);
        break;
      }
      run_count -= nbits;
    }

    /* Read nybbles until we have a full row */
    while (np / 2 < pl && rowbits_left > 0) {
      int  nyb;

      nyb = (np % 2) ? dp[np/2] & 0x0f : (dp[np/2] >> 4) & 0x0f;
#if  DEBUG == 3
      MESG("\npk_nyb: %d", nyb);
#endif
      if (nyb == 14) { /* packed number "repeat_count" follows */
        if (repeat_count != 0)
          WARN("Second repeat count for this row!");
        np++; /* Consume this nybble */
        repeat_count = pk_packed_num(&np, dyn_f, dp, pl);
#if  DEBUG == 3
        MESG(" --> rep: %ld\n", repeat_count);
#endif
      } else if (nyb == 15) {
        if (repeat_count != 0)
          WARN("Second repeat count for this row!");
        np++; /* Consume this nybble */
        repeat_count = 1;
#if  DEBUG == 3
        MESG(" --> rep: %ld\n", repeat_count);
#endif
      } else { /* run_count */
        /* Interprete current nybble as packed number */
        run_count = pk_packed_num(&np, dyn_f, dp, pl);
#if  DEBUG == 3
        MESG(" --> run: %ld (%d)\n", run_count, run_color);
#endif
        nbits = MIN(rowbits_left, run_count);
        run_color  = !run_color;
        run_count -= nbits;
        switch (run_color) {
        case  0:
          rowbits_left -= fill_black_run(rowptr, wd - rowbits_left, nbits);
          break;
        case  1:
          rowbits_left -= fill_white_run(rowptr, wd - rowbits_left, nbits);
          break;
        }
      }
    }
    /* We got bitmap row data. */
#if  DEBUG == 2
    send_out(rowptr, rowbytes, wd, stream);
#else
    send_out(rowptr, rowbytes, stream);
#endif
    for ( ; i < ht && repeat_count > 0; repeat_count--, i++)
#if  DEBUG == 2
      send_out(rowptr, rowbytes, wd, stream);
#else
    send_out(rowptr, rowbytes, stream);
#endif
  }
  RELEASE(rowptr);

  return  0;
}
Beispiel #17
0
void
ve_paint_map (DESCRIPTOR_DATA * c, struct map_data *map_ptr)
{
  int i;
  int j;
  int t1;
  int t2;
  int duplicate_room;
  int same_room;
  int con_to;			/* Connects to another room */
  int con_to_good;		/* Connects to expected room */
  int con_from;			/* Connects from another room */
  int con_from_good;		/* Connects from expected room */
  char buf[MAX_STRING_LENGTH];
  ROOM_DATA *room;		/* From room */
  ROOM_DATA *room2;		/* To room */

  sprintf (buf, "%s", HOME CLEAR);
  send_out (c, buf);

  for (i = 0; i < MAP_MAX_LINE_DIM (c); i++)
    {
      for (j = 0; j < MAP_MAX_COL_DIM (c); j++)
	{

	  if (map_ptr->map[i][j] <= 0)
	    continue;

	  ve_goto (c, i * 4 + 1, j * 10 + 1);

	  duplicate_room = 0;

	  if (j == MAP_MID_OFFSET_COL (c) && i == MAP_MID_OFFSET_LINE (c))
	    sprintf (buf, "%s%5d%s", "#4", map_ptr->map[i][j], "#0");
	  else
	    {
	      for (t1 = 0; t1 < MAP_MAX_LINE_DIM (c) && !duplicate_room; t1++)
		for (t2 = 0; t2 < MAP_MAX_COL_DIM (c); t2++)
		  if ((t1 != i || t2 != j) &&
		      map_ptr->map[t1][t2] == map_ptr->map[i][j])
		    {
		      duplicate_room = 1;
		      break;
		    }

	      if (vtor (map_ptr->map[i][j]) &&
		  !strncmp (vtor (map_ptr->map[i][j])->description,
			    "No Description Set", 18))
		sprintf (buf, "%s%5d%s", "#2", map_ptr->map[i][j], "#0");
	      else if (duplicate_room)
		sprintf (buf, "%s%5d%s", "#1", map_ptr->map[i][j], "#0");
	      else
		sprintf (buf, "%5d", map_ptr->map[i][j]);
	    }

	  send_out (c, buf);

	  if (map_ptr->ups[i][j])
	    {
	      ve_goto (c, i * 4, j * 10 + 2);
	      send_out (c, "#3U#0");
	    }

	  if (map_ptr->downs[i][j])
	    {
	      ve_goto (c, i * 4 + 2, j * 10 + 2);
	      send_out (c, "#3D#0");
	    }

	  if (j + 1 < MAP_MAX_COL_DIM (c) && map_ptr->map[i][j + 1])
	    {

	      con_from = 0;
	      con_from_good = 0;

	      if (map_ptr->map[i][j] == map_ptr->map[i][j + 1])
		same_room = 1;
	      else
		same_room = 0;

	      room = vtor (map_ptr->map[i][j + 1]);
	      if (!room);
	      else if (!room->dir_option[WEST]);
	      else if (room->dir_option[WEST]->to_room == map_ptr->map[i][j])
		{
		  con_from_good = 1;
		  con_from = 1;
		}
	      else if (room->dir_option[WEST]->to_room > 0)
		con_from = 1;

	      con_to = 0;
	      con_to_good = 0;

	      room2 = vtor (map_ptr->map[i][j]);
	      if (!room2);
	      else if (!room2->dir_option[EAST]);
	      else if (room2->dir_option[EAST]->to_room ==
		       map_ptr->map[i][j + 1])
		{
		  con_to_good = 1;
		  con_to = 1;
		}
	      else if (room2->dir_option[EAST]->to_room > 0)
		con_to = 1;

	      *buf = '\0';

	      if (same_room)
		{
		  ve_goto (c, i * 4 + 1, j * 10 + 6);
		  send_out (c, "#1.....#0");
		}

	      else
		{
		  if (con_from_good && con_to_good)
		    strcpy (buf, "<===>");
		  else if (con_from_good)
		    strcpy (buf, "<----");
		  else if (con_to_good)
		    strcpy (buf, "---->");

		  if (*buf)
		    {
		      ve_goto (c, i * 4 + 1, j * 10 + 6);
		      send_out (c, buf);
		    }

		  if (con_to && !con_to_good)
		    {
		      ve_goto (c, i * 4 + 2, j * 10 + 5);
		      send_out (c, "#5>?#0");
		    }

		  if (con_from && !con_from_good)
		    {
		      ve_goto (c, i * 4 + 2, j * 10 + 10);
		      send_out (c, "#5?<#0");
		    }
		}
	    }

	  if (i + 1 < MAP_MAX_LINE_DIM (c) && map_ptr->map[i + 1][j])
	    {

	      con_from = 0;
	      con_from_good = 0;

	      if (map_ptr->map[i][j] == map_ptr->map[i + 1][j])
		same_room = 1;
	      else
		same_room = 0;

	      room = vtor (map_ptr->map[i + 1][j]);
	      if (!room);
	      else if (!room->dir_option[NORTH]);
	      else if (room->dir_option[NORTH]->to_room == map_ptr->map[i][j])
		{
		  con_from_good = 1;
		  con_from = 1;
		}
	      else if (room->dir_option[NORTH]->to_room > 0)
		con_from = 1;

	      con_to = 0;
	      con_to_good = 0;

	      room2 = vtor (map_ptr->map[i][j]);
	      if (!room2);
	      else if (!room2->dir_option[SOUTH]);
	      else if (room2->dir_option[SOUTH]->to_room ==
		       map_ptr->map[i + 1][j])
		{
		  con_to_good = 1;
		  con_to = 1;
		}
	      else if (room2->dir_option[SOUTH]->to_room > 0)
		con_to = 1;

	      *buf = '\0';

	      if (same_room)
		{
		  ve_goto (c, i * 4 + 2, j * 10 + 3);
		  send_out (c, "#1.#0");

		  ve_goto (c, i * 4 + 3, j * 10 + 3);
		  send_out (c, "#1.#0");

		  ve_goto (c, i * 4 + 4, j * 10 + 3);
		  send_out (c, "#1.#0");
		}

	      else
		{
		  if (con_from_good)
		    {
		      ve_goto (c, i * 4 + 2, j * 10 + 3);
		      send_out (c, "^");
		    }

		  if (con_from_good && con_to_good)
		    {
		      ve_goto (c, i * 4 + 3, j * 10 + 3);
		      send_out (c, "#");
		    }

		  else if (con_from_good || con_to_good)
		    {
		      ve_goto (c, i * 4 + 3, j * 10 + 3);
		      send_out (c, "|");
		    }

		  if (con_to_good)
		    {
		      ve_goto (c, i * 4 + 4, j * 10 + 3);
		      send_out (c, "v");
		    }

		  if (con_to && !con_to_good)
		    {
		      ve_goto (c, i * 4 + 2, j * 10 + 2);
		      send_out (c, "#5v#0");
		      ve_goto (c, i * 4 + 3, j * 10 + 2);
		      send_out (c, "#5?#0");
		    }

		  if (con_from && !con_from_good)
		    {
		      ve_goto (c, i * 4 + 4, j * 10 + 4);
		      send_out (c, "#5^#0");
		      ve_goto (c, i * 4 + 3, j * 10 + 4);
		      send_out (c, "#5?#0");
		    }
		}
	    }
	}
    }

  ve_goto (c, c->max_lines, 1);

  sprintf (buf, "[%5d]: %s%s%s", c->character->in_room, "#5",
	   c->character->room->name, "#0");
  send_out (c, buf);
}
Beispiel #18
0
/* Bring the data from the brigade (which represents the result of the
 * request_rec out filter chain) into the h2_mplx for further sending
 * on the master connection. 
 */
static apr_status_t slave_out(h2_task *task, ap_filter_t* f, 
                              apr_bucket_brigade* bb)
{
    apr_bucket *b;
    apr_status_t status = APR_SUCCESS;
    int flush = 0, blocking;
    
    if (task->frozen) {
        h2_util_bb_log(task->c, task->stream_id, APLOG_TRACE2,
                       "frozen task output write, ignored", bb);
        while (!APR_BRIGADE_EMPTY(bb)) {
            b = APR_BRIGADE_FIRST(bb);
            if (AP_BUCKET_IS_EOR(b)) {
                APR_BUCKET_REMOVE(b);
                task->eor = b;
            }
            else {
                apr_bucket_delete(b);
            }
        }
        return APR_SUCCESS;
    }

    /* we send block once we opened the output, so someone is there
     * reading it *and* the task is not assigned to a h2_req_engine */
    blocking = (!task->assigned && task->output.opened);
    if (!task->output.opened) {
        for (b = APR_BRIGADE_FIRST(bb);
             b != APR_BRIGADE_SENTINEL(bb);
             b = APR_BUCKET_NEXT(b)) {
            if (APR_BUCKET_IS_FLUSH(b)) {
                flush = 1;
                break;
            }
        }
    }
    
    if (task->output.bb && !APR_BRIGADE_EMPTY(task->output.bb)) {
        /* still have data buffered from previous attempt.
         * setaside and append new data and try to pass the complete data */
        if (!APR_BRIGADE_EMPTY(bb)) {
            status = ap_save_brigade(f, &task->output.bb, &bb, task->pool);
        }
        if (status == APR_SUCCESS) {
            status = send_out(task, task->output.bb, blocking);
        } 
    }
    else {
        /* no data buffered here, try to pass the brigade directly */
        status = send_out(task, bb, blocking); 
        if (status == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb)) {
            /* could not write all, buffer the rest */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, task->c, APLOGNO(03405)
                          "h2_slave_out(%s): saving brigade", 
                          task->id);
            status = ap_save_brigade(f, &task->output.bb, &bb, task->pool);
            flush = 1;
        }
    }
    
    if (status == APR_SUCCESS && !task->output.opened && flush) {
        /* got a flush or could not write all, time to tell someone to read */
        status = open_output(task);
    }
    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, task->c, 
                  "h2_slave_out(%s): slave_out leave", task->id);    
    return status;
}
Beispiel #19
0
void
ve_help_screen (DESCRIPTOR_DATA * c)
{
  char buf[MAX_STRING_LENGTH];

  sprintf (buf, "%s", HOME CLEAR);
  send_out (c, buf);

  ve_goto (c, 1, 1);
  send_out (c, "  Command Mode commands");
  ve_goto (c, 3, 1);
  send_out (c, "    @   - EXIT editor");
  ve_goto (c, 4, 1);
  send_out (c, "    i   - enter insert mode");
  ve_goto (c, 5, 1);
  send_out (c, "    d   - delete current line");
  ve_goto (c, 6, 1);
  send_out (c, "    j   - down");
  ve_goto (c, 7, 1);
  send_out (c, "    k   - up");
  ve_goto (c, 8, 1);
  send_out (c, "    l   - right");
  ve_goto (c, 9, 1);
  send_out (c, "    h   - left");
  ve_goto (c, 10, 1);
  send_out (c, "    $   - goto end of line");
  ve_goto (c, 11, 1);
  send_out (c, "    o   - insert line below");
  ve_goto (c, 12, 1);
  send_out (c, "    O   - insert line above");
  ve_goto (c, 13, 1);
  send_out (c, "    x   - delete character");
  ve_goto (c, 14, 1);
  send_out (c, "    m   - display map");
  ve_goto (c, 15, 1);
  send_out (c, "    <ctrl-L>    - refresh screen");
  ve_goto (c, 16, 1);
  send_out (c, "    N,S,E,W,U,D - move");

  ve_goto (c, 1, 40);
  send_out (c, "Insert Mode");
  ve_goto (c, 3, 40);
  send_out (c, "  <ctrl-h>  - backspace");
  ve_goto (c, 4, 40);
  send_out (c, "  <esc>     - return to Command Mode");

  ve_goto (c, 8, 40);
  send_out (c, "Map Mode");
  ve_goto (c, 10, 40);
  send_out (c, "  N,S,E,W,U,D - move");
  ve_goto (c, 11, 40);
  send_out (c, "  @           - return to Command Mode");

  c->edit_mode |= MODE_VISHELP;
}