/* vis500vdu.c - 19:22 GMT +10:00 Thu 29 July 1993 - modifier Geoffrey Tobin */

/* From input file "../include/globals.p" */

#include "config.h"
#include "globals.h"

#include "screenio.h"
#include "vdu.h"

#include "tek4010emu.h"
#include "vis500vdu.h"

/******************************************************************************/

/* Void VIS500StartText: use TEK4010StartText */

/******************************************************************************/

#ifdef __STDC__
Static Void MoveAbs (int row, int col)
#else
Static Void MoveAbs (row, col)
  int row, col;
#endif
{
  /* _Assuming_ we are in VT52 mode (Alphanumeric mode),
     move the cursor to the given row and column.
     Since DVItoVDU assumes top left corner of screen is (row=1,col=1),
     we need to subtract 1 from both coordinates to get the actual
     VT52 position on the screen.
  */

  WriteChar (ESC);
  WriteChar ('Y');
  WriteChar (row + 31);
  WriteChar (col + 31);
  textcolumn = col - 1;
}
/* MoveAbs */

/******************************************************************************/

#ifdef __STDC__
Void VIS500MoveToTextLine (int line)
#else
Void VIS500MoveToTextLine (line)
  int line;
#endif
{
  /* Move current position to start of given line. */

  WriteChar (CAN);

  MoveAbs (line, 1);
}
/* VIS500MoveToTextLine */

/******************************************************************************/

#ifdef __STDC__
Void VIS500ClearTextLine (int line)
#else
Void VIS500ClearTextLine (line)
  int line;
#endif
{
  /* Erase given line; note that DVItoVDU does not assume anything about the
     current position at the end of this routine.
  */

  WriteChar (CAN);   /* switch to Alphanumeric mode */

  MoveAbs (line, 1);   /* move to start of line */
  WriteChar (ESC);
  WriteChar ('K');   /* erase to end of line */
}
/* VIS500ClearTextLine */

/******************************************************************************/

Void VIS500ClearScreen (VOID)
{
  WriteChar (CAN);   /* enable Alphanumeric display */

  WriteChar (ESC);
  WriteChar ('H');   /* move to top left of screen */
  WriteChar (ESC);
  WriteChar ('J');   /* erase to end of screen (Alphanumeric text) */
  TEK4010ClearScreen();   /* erase graphics */
}
/* VIS500ClearScreen */

/******************************************************************************/

/* VIS500StartGraphics: use TEK4010StartGraphics */

/******************************************************************************/

/* VIS500LoadFont: use TEK4010LoadFont */

/******************************************************************************/

#ifdef __STDC__
Void VIS500ShowChar (int screenh, int screenv, Char ch)
#else
Void VIS500ShowChar (screenh, screenv, ch)
  int screenh, screenv;
  Char ch;
#endif
{
  /* The TEK4010 Terse mode characters on the VIS500 need to be dragged down
     so that any descenders will be below the baseline represented by screenv.
  */

  screenv += dragdown;
  if (screenv > 779)   /* drag down as far as possible */
    TEK4010ShowChar (screenh, 779, ch);
  else
    TEK4010ShowChar (screenh, screenv, ch);
}
/* VIS500ShowChar */

/******************************************************************************/

#ifdef __STDC__
Void VIS500ShowRectangle (int screenh, int screenv, int width, int height,
                          Char ch)
#else
Void VIS500ShowRectangle (screenh, screenv, width, height, ch)
  int screenh, screenv;  /* (screenh, screenv) = top left pixel */
  int width, height;     /* (width, height) = size of rectangle */
  Char ch;               /* ch = black pixel */
#endif
{
  /* Display the given rectangle. */

  int pos;

  if (height == 1)
  {
    /* show row vector */
    pos = 779 - screenv;

    WriteChar (GS);

    SendXY (screenh, pos);   /* move cursor to start of row */
    SendXY (screenh + width - 1, pos);   /* draw vector to end of row */
  }
  else if (width == 1)
  {
    /* show column vector */
    pos = 779 - screenv;

    WriteChar (GS);

    SendXY (screenh, pos);   /* move cursor to start of column */
    SendXY (screenh, pos - height + 1);   /* draw vector to end of column */
  }
  else
  {
    /* assume height and width > 1; draw and fill rectangle */
    pos = 780 - height - screenv;

    WriteChar (ESC);
    WriteChar ('/');
    WriteInt (screenh);
    WriteChar (';');   /* left */
    WriteInt (pos);
    WriteChar (';');   /* bottom */
    WriteInt (width - 1);
    WriteChar (';');
    WriteInt (height + 1);
    WriteChar ('y');

    /* Note that there are a few problems with this command:
       - we need to subtract 1 from width.  While this prevents exceeding the
         right edge (reason unknown), it causes missing pixel columns.
       - we need to ADD 1 to height to avoid missing pixel rows.
       - the smallest rectangle drawn is 2 by 2.
       - the new cursor position is undefined.
       These funnies are outweighed by the improved efficiency in drawing large
       rectangles.
    */

    havesentxy = false;   /* need to re-synch cursor position */
  }
}
/* VIS500ShowRectangle */

/******************************************************************************/

Void VIS500ResetVDU (VOID)
{
  WriteChar (CAN);   /* make sure terminal is in Alphanumeric mode */
}
/* VIS500ResetVDU */

/******************************************************************************/

Void InitVIS500 (VOID)
{
  /* The main program only calls this routine after it has parsed the command
     line and successfully opened the given DVI file.
  */

  InitTEK4010emu();

  DVIstatusl = 1;   /* DVItoVDU assumes top text line = 1 */
  windowstatusl = 2;
  messagel = 3;
  commandl = 4;
  bottoml = 33;   /* also number of text lines on VIS500 screen */

  /* The above values _assume_ the VIS500 is in Alphanumeric mode;
     the following values _assume_ it is emulating a Tektronix 4010.
     Note that windowv must be given a value using DVItoVDU's coordinate scheme
     where top left pixel is (0,0).
  */

  windowv = 92;   /* approx. height in TEK4010 pixels of 4 text lines;
                              i.e. 4 * 780/34 */
  windowh = 0;
  windowht = 780 - windowv;
  windowwd = 1024;

  textlinewidth = 72;  /* text characters per line - a guess */

  MoveToTextLine = VIS500MoveToTextLine;
  ClearTextLine  = VIS500ClearTextLine;
  ClearScreen    = VIS500ClearScreen;
  StartText      = TEK4010StartText;
  StartGraphics  = TEK4010StartGraphics;
  LoadFont       = TEK4010LoadFont;
  ShowChar       = VIS500ShowChar;
  ShowRectangle  = VIS500ShowRectangle;
  ResetVDU       = VIS500ResetVDU;

  WriteChar (GS);

  WriteChar (ESC);
  WriteChar ('@');   /* solid fill for rectangular draw and fill */

  WriteChar (CAN);
}
/* InitVIS500 */

/******************************************************************************/

/* end vis500vdu.c */
