Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!amdcad!sun!pitstop!sundc!seismo!uunet!mcvax!philmds!leo
From: leo@philmds.UUCP (Leo de Wit)
Newsgroups: comp.sys.atari.st
Subject: Re: Read Screen Character
Message-ID: <525@philmds.UUCP>
Date: 25 Jun 88 16:56:45 GMT
References: <272@scolex> <1871@brahma.cs.hw.ac.uk>
Reply-To: leo@philmds.UUCP (L.J.M. de Wit)
Organization: Philips I&E DTS Eindhoven
Lines: 197

In article <1871@brahma.cs.hw.ac.uk> neil@cs.hw.ac.uk (Neil Forsyth) writes:
>In article <272@scolex> kurth@sco.COM (Kurt Hutchison) writes:
>>It *IS* possible to get the current cursor location by sending the cursor
>>save string to the roms and then looking in the documented location for
>>the saved cursor address.
>
>Excuse me bt i have never seen this variable location documented anywhere.
>Where is it? If it's not an official location just ignore this message.

As far as I can judge it is a constant location (in fact two), but it
could probably vary from ROM to ROM (not being a system variable). But
anyway, there is a clean way of doing it (that does not destroy a
previous saved location): use the VDI ESC 15 function, fetch cursor
position, or if you use a C library, it is probably called:

vq_curaddress(handle,&row,&col); with WORD handle,row,col. This
requires a handle but in this case you can use 0 (Desktop's handle).

Furthermore I would like to offer the readers of this newsgroup the
source of a module that reads a character from the screen, using the
current TOS font.  The relevant function is copied with slight
modification from the fastdump program that was on the
comp.sources.atari.st newsgroup just a while ago.  If there are any
objections against me posting such a long article, I would also like to
hear (but then, you can always hit 'n'). As it is, the source
represents a tiny demo program (just to show that it works). By
removing main you get a module that can be linked with your program
(about 738 bytes in size). Enjoy!

    Leo

============================== C U T   H E R E ==============================
/*
 ******************************************************************************
 *                                                                            *
 *    vtchar.c    version 1.0 of 25 June 1988    (C) L.J.M. de Wit 1988       *
 *                                                                            *
 * This software may be used and distributed freely if not used commercially  *
 * and the originator (me) is mentioned.                                      *
 *                                                                            *
 ******************************************************************************
 *
 *     This program demonstrates the reading of characters from the screen.
 *  The upper left quadrant of the screen is copied to the other three using
 *  this technique.
 *     If you want to use get_schar() from your own programs, just remove the
 *  function main() from this file and compile it as a separate module. Then
 *  link it with your program.
 *     To use it, call prep_schar() first; this sets the correct parameters
 *  (need to be done only once). Then you can use get_schar(r,c) with r the
 *  row and c the column to read from.
 *     An unrecognized character will be presented by a space.
 *     Inverse video is not yet supported (most probably it becomes a space
 *  now), but this is not difficult to implement.
 */

#include 
#include 

/* font definitions */
typedef struct font_header {
   WORD f_id;       /* font identifier; system font = 1 */
   WORD f_point;    /* font size in points */
   char f_name[32]; /* font name */
   WORD f_low;      /* lowest ascii code in font */
   WORD f_high;     /* highest ascii code in font */
   WORD f_top;      /* relative distance of top to base line */
   WORD f_ascent;   /* relative distance of ascent to base line */
   WORD f_half;     /* relative distance of half to base line */
   WORD f_descent;  /* relative distance of descent to base line */
   WORD f_bottom;   /* relative distance of bottom to base line */
   WORD f_maxcharw; /* maximal character width in font */
   WORD f_maxcellw; /* maximal cell width in font */
   WORD f_loffset;  /* left offset */
   WORD f_roffset;  /* right offset */
   WORD f_fatsiz;   /* degree of fattening */
   WORD f_ulsiz;    /* underline degree */
   WORD f_normask;  /* normal cancelled mask */
   WORD f_skewmask; /* skewing cancelled mask */
   WORD f_flag;     /* flag:
                     *  bit 0: system font;
                     *  bit 1: hor. offset;
                     *  bit 2: byte swap;
                     *  bit 3: non proportional font
                     */
   WORD *f_horoff;  /* pointer to horizontal offsets table */
   WORD *f_charoff; /* pointer to character offsets table */
   char *f_data;    /* pointer to font data table */
   WORD f_fontw;    /* total width of all chars in font */
   WORD f_fonth;    /* height of font (# scanlines) */
   struct font_header
          *f_next;  /* pointer to next font header */
} font_header;

static UWORD g_fheader[] = {  0xA000,        /* LineA exception 0   */
                              0x222F,0x0004, /* MOVE.L  4(SP),D1    */
                              0xE581,        /* ASL.L   #2,D1       */
                              0x2031,0x1800, /* MOVE.L  0(A1,D1),D0 */
                              0x4E75 };      /* RTS                 */

static WORD planes;
static font_header *fhp;
static WORD rows, cols;                   /* Rows & columns of screen    */
static int physbase;

BYTE get_schar();
void prep_schar();

main()
{
   int i, j, rows2, cols2;
   char line[82];

   prep_schar();
   cols2 = cols/2; rows2 = rows/2;
   Bconout(2,'\33');   Bconout(2,'f');
   for (i = 0; i < rows2; i++) {
      for (j = 0; j < cols2; j++) {
         line[j] = get_schar(i,j);
      }
      line[cols2] = '\0';
      Bconout(2,'\33');          Bconout(2,'Y');
      Bconout(2,' '+ i);         Bconout(2,' '+cols2);
      Cconws(line);
      Bconout(2,'\33');          Bconout(2,'Y');
      Bconout(2,' '+ i+rows2);   Bconout(2,' ');
      Cconws(line);
      Cconws(line);
   }
   Bconout(2,'\33');   Bconout(2,'e');
}

void prep_schar()
{
   BYTE rez;                              /* resolution 2 high 1 med 0 low*/

   rez = Getrez();
   fhp = (*(font_header *(*)())g_fheader)
         ((rez == 2) ? 2 : 1);            /* pointer to standard font    */
   planes = 4 >> rez;                     /* # of bit planes: 4, 2 or 1  */
   rows = 25;
   cols = (rez == 0) ? 40 : 80;
   physbase = Physbase();
}

BYTE get_schar(i,j)                       /* Find match in a font for    */
WORD i,j;                                 /* the character bit image at  */
{                                         /* position (i,j)              */
   register WORD l;                       /* line counter                */
   register BYTE *cpd,                    /* char ptr into font_data     */
                 *cps;                    /* char ptr into ch_img[]      */
   register WORD p, c;
   WORD *curadd,                          /* screen address of top word  */
        sval;                             /* will hold a word of image   */
   BYTE ch_img[16],                       /* will hold image as bytes    */
        or_all;                           /* OR of all bytes of image    */
   UWORD w_p_l,                           /* # words per line            */
         maxl;                            /* height of a char in lines   */

   w_p_l = (planes == 1) ? 40 : 80;
   maxl = (planes == 1) ? 16 : 8;
   curadd = (WORD *)(physbase + i * 1280 + (j & ~1) * planes);

   /* prepare ch_img[] to hold a adjusted copy of the bit image */
   or_all = 0;
   for (l = 0; l < maxl; l++) {
      sval = 0;
      for (p = 0; p < planes; p++) {      /* OR in all colour bit planes */
         sval |= curadd[l * w_p_l + p];
      }

      ch_img[l] = (j & 1) ? sval & 0xff   /* Take lower or upper byte    */
                   : (sval >> 8) & 0xff;  /* as appropriate              */
      or_all |= ch_img[l];                /* Keeps inclusive Or of all   */
   }

   /* search */
   if (or_all == 0) {                     /* Not a pixel set             */
      c = ' ';                            /* then space will be printed  */
   } else {                               /* else for each char in font  */
      for (c = fhp->f_low; c <= fhp->f_high; c++) {
         cpd = fhp->f_data + (fhp->f_charoff[c] >> 3);
         cps = ch_img;
         for (l = 0; l < maxl; l++) {     /* Compare each line (byte)    */
            if (*cps++ != *cpd) break;    /* Match failed at this line   */
            cpd += fhp->f_fontw;
         }
         if (l >= maxl) break;            /* All lines matched           */
      }

      if ((c == '\0') || (c > fhp->f_high)) { /* If no match             */
         c = ' ';                         /* use space instead           */
      }
   }

   return (BYTE)c;                        /* Return matched char or space*/
}