home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / gl_plot / part01 next >
Text File  |  1989-03-23  |  36KB  |  1,033 lines

  1. Subject:  v18i059:  GL Graphics Library for AT-clone Unix, Part01/07
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: clip!lewis%dtlewis%m-net@uunet.UU.NET
  7. Posting-number: Volume 18, Issue 59
  8. Archive-name: gl_plot/part01
  9.  
  10.  
  11. The "gl" collection of routines provides graphic device support for a 
  12. number of video adapters and printers for PC/AT class computers running
  13. under Microport System V/AT, Xenix or MS-DOS.    The routines emulate
  14. the BSD plot(3) library, as well as provide new routines.  It runs
  15. under MSDOS/ System V/AT, SCO Xenix 286, and with Hercules, CGA, EGA,
  16. and Epson printer devices.
  17.  
  18. # To recover, type "sh archive"
  19. echo restoring Readme
  20. sed 's/^X//' > Readme <<XxX--EOF--XxX
  21. X
  22. XGraphics Library for AT Computers Running UNIX (System V/AT, Xenix) and DOS
  23. X---------------------------------------------------------------------------
  24. X
  25. XThe "gl" collection of routines provides graphic device support for a 
  26. Xnumber of video adapters and printers for PC/AT class computers running
  27. Xunder Microport System V/AT, Xenix or MS-DOS.  
  28. X
  29. XVarious output devices are supported.  For each type of device, one or
  30. Xmore graphics "modes" is defined in modes.h, and the corresponding bitmaps
  31. Xare defined in bitmaps.h.  These modes roughly correspond to the BIOS
  32. Xvideo modes defined for MS-DOS, with additional modes defined for Hercules
  33. Xcompatible modes and for printer output.  The gl.h file should be included 
  34. Xinto user code to declare the graphics routines.  The config.h file may 
  35. Xalso be included for user programs when needed (the other header files are 
  36. Xintended to be used only by the gl routines). 
  37. X
  38. XTested system configurations include the following:
  39. X
  40. XOS        Compiler        Device
  41. X--------------- ----------------------- -----------------------------------
  42. XSystem V/AT    cc            Hercules compatible
  43. XSystem V/AT    cc            CGA compatible
  44. XSystem V/AT    cc            EGA compatible
  45. XSystem V/AT    cc            IBM or Epson compatible printer
  46. XSCO Xenix 286    Microsoft C        EGA compatible (including CGA modes)
  47. XMS-DOS        Microsoft C (Xenix)    EGA compatible (including CGA modes)
  48. XMS-DOS        Microsoft C (DOS)    EGA compatible (including CGA modes)
  49. XMS-DOS        Borland Turbo-C        EGA compatible (including CGA modes)
  50. X
  51. XOther combinations of systems, compilers and output devices should work with 
  52. Xlittle or no modification.  
  53. X
  54. XCurrently supported video adapters include:
  55. X
  56. X-Hercules compatible monochrome (page 0 and page 1)
  57. X-CGA (modes 4 and 6)
  58. X-EGA (no color in EGA mode 16)
  59. X-VGA (EGA and CGA modes only)
  60. X
  61. XCurrently supported printers include:
  62. X
  63. X-IBM graphics printer
  64. X-IBM Proprinter
  65. X-Epson FX85, 
  66. X-Epson LQ1500
  67. X-Star10X
  68. X-Tandy DMP130
  69. X-HP Laserjet+
  70. X
  71. XAdditional device support is straightforward, as all routines call 
  72. Xp_wr_pix() to do output.
  73. X
  74. XThe routines are:
  75. X
  76. X    g_init()    Initialize device, buffers, variables.  Attach
  77. X            to shared memory segment or malloc'ed buffers.
  78. X    g_finish()    Release resources, detach segments.
  79. X    g_clear()    Clear screen.
  80. X    p_wr_pix()    Write one pixel.
  81. X    n_movepen()    Move logical cursor in 32768 x 32768 address space.
  82. X    n_point()    Draw point in 32768 x 32768 address space.
  83. X    n_draw()    Draw vector.    
  84. X    n_line()    Draw line.
  85. X    n_box()        Draw box.
  86. X    n_ellipse()    Draw ellipse.
  87. X    n_arc()        Draw elliptical arc.
  88. X    n_grafchar()    Display a vectorized text character (stroke font).
  89. X    n_grafstr()    Display a character string, stroke font.
  90. X    g_fontctl()    Control size, aspect ratio, spacing, angle and slant 
  91. X            of stroke font.
  92. X    c_cellchar()    Display a bit mapped character.
  93. X    c_cellstr()    Display a string, bit mapped characters.
  94. X    c_cursor()    Move to character column and row for c_cellstr().
  95. X    g_pix_mode()    Establish OR mode or XOR mode pixel setting, returns
  96. X            previous mode value.
  97. X    g_pix_color()    Set pixel color, returns previous color value.
  98. X    g_weight()    Set line thickness, returns previous value.
  99. X    g_style()    Set line style (e.g. dot-dash), returns previous value.
  100. X
  101. XAdditional routines:
  102. X
  103. X    plot(3)        Emulation of the BSD plot(3) library:  openpl(), 
  104. X            erase(), label(), line(), circle(), arc(), move(), 
  105. X            cont(), point(), linemod(), space(), closepl().
  106. X
  107. XRequirements:
  108. X-------------
  109. X
  110. X1)  A graphics capable video adapter and/or printer (see above for supported
  111. Xdevices).  
  112. X
  113. X2)  Access to video memory.  For System V/AT, this requires an entry in 
  114. X/etc/rc.d/shm.rc to define the shared memory key for your graphics board 
  115. XA sample entry for EGA is:
  116. X
  117. X    /etc/shmcreate 0xa0000 a0000 65535        # ega high res
  118. X
  119. XXenix requires only the appropriate device driver (/dev/EGA), and MS-DOS
  120. Xhas nothing to worry about.  Requirements for 386 UNIX are unknown at this
  121. Xtime.  MS-DOS has no special requirements.
  122. X
  123. X3)  A program or shell script which will cause the graphics adapter to
  124. Xswitch from text to graphics modes, and vice versa (not required for DOS,
  125. Xbut handy nonetheless).  For most configurations, this can be just a shell 
  126. Xscript which echoes the appropriate escape sequences to the console.  The 
  127. Xmode.sh and mode.xenix scripts are supplied for this purpose, but should 
  128. Xbe tested and modified as needed for your system.  The program mode.c is 
  129. Xalso supplied for use with the Everex Edge.  This program can be modified 
  130. Xto support various other video adapters which may not respond to the 
  131. Xconsole escape sequences (mode.c probably works with a Hercules board, 
  132. Xalso, but this is not tested).  For System V/AT, mode.c needs to be suid 
  133. Xto root and placed in an appropriate safe directory, but a simple shell 
  134. Xscript (for most video boards on System V/AT or Xenix) will need no special 
  135. Xtreatment.  For MS-DOS, mode switching is done with BIOS calls.
  136. X
  137. X4)  For graphics printing, the printer driver must be in "transparency"
  138. Xmode, to allow binary data to be sent to the printer without modifications
  139. X(such as conversion of <lf> to <cr><lf>).  
  140. X
  141. XFor System V/AT, this is done with the "lpget" and "lpset" commands.  
  142. XThe plotting routines do not set this for you, since the printer is on a 
  143. Xqueue and is assumed to be a shared device.  If more than one person uses 
  144. Xthe printer, it may be a good idea to leave the driver in transparency
  145. Xmode, and write a filter for normal text line printer output to handle
  146. Xconversion of <cr> to <cr><lf> along with any other output formatting
  147. Xthat may be required for text.  An alternative method, based on an
  148. Xundocumented feature of the System V/AT lp driver, is to use minor
  149. Xnumbers 128 and 129 of the lp driver, rather than 0 and 1.  This device
  150. Xwill correspond to the transparent mode of the lp device driver.  The
  151. Xcommands "mknod /dev/lpt0 c 0 128", "link /dev/lpt0 /dev/lpt",
  152. X"lpadmin -plpt -v/dev/lpt -elp", "enable lpt" and "/usr/lib/accept lpt"
  153. Xmay be used to set this up (you may need to use "mknod /dev/lpt1 c 0 129"
  154. Xand "link /dev/lpt0 /dev/lpt", depending on which printer port you are
  155. Xusing.  The lp command then becomes "lp -dlp" (set PRINTPROG in config.h
  156. Xaccordingly).  If the environment variable "PLOTDEV" is defined, it will be
  157. Xused as the name of the output printer (e.g. "PLOTDEV=lpt; export PLOTDEV"
  158. Xto use the transparent printer device).
  159. X
  160. XFor Xenix, you should configure a printer interface program for transparent
  161. Xprinting (see lpadmin(C) and parallel(HW), along with the section on 
  162. X"Printer Interface Programs" in the "Xenix Operations Guide).  This can
  163. Xbe done by modifying one of the supplied printer interface programs (such
  164. Xas /usr/spool/lp/crnlmap.sh) to include the command "stty -onlcr 0<&1".
  165. X
  166. XFor MS-DOS versions, printing is done with BIOS calls, so no special setups
  167. Xare required.  However, graphics printing may not be done through the
  168. Xnormal MS-DOS print spooler or MS-DOS "PRN:" device, due to unwanted
  169. Xcharacter conversion.
  170. X
  171. XSee the "INSTALL" file for specific instructions for installing on Microport 
  172. XSystem V/AT, Xenix System V 286, or MS-DOS.
  173. X
  174. XHow it works:
  175. X-------------
  176. X
  177. XFor System V/AT, g_init() attaches the shared memory segment for your video
  178. Xboard to your process address space.  For Xenix, g_init opens a device file
  179. Xand obtains a pointer to video memory.  The pointer to the video memory
  180. Xsegment is used for direct read and write access to bit mapped graphics.
  181. X
  182. XIn the case of a printer, g_init() simply allocates some memory buffers which
  183. Xit treats as the bit map for the printer, then adds some escape codes and
  184. Xspools the whole mess off to the lp program.
  185. X
  186. XThe screen (or printer page) is represented by a normalized address
  187. Xspace of 32768 by 32768.  This gives a reasonable amount of resolution,
  188. Xand allows valid addresses to be represented by non-negative short integers,
  189. Xgiving efficient calculations and easy checking for addresses that would
  190. Xbe "off the edge of the screen."  All of the output routines, except
  191. Xp_wr_pix(), use this normalized address space, regardless of the pixel
  192. Xaspect ratio or the aspect ratio of the physical screen.  
  193. X
  194. XThe p_wr_pix() routine uses physical pixel coordinates (row,col)
  195. Xto access one pixel on the graphics device.  All output, whether lines,
  196. Xdots or text, use the p_wr_pix() routine at the lowest level.  In
  197. Xthis way, all knowledge of the display bit map, interleaving and 
  198. Xsegmentation are localized to the p_wr_pix() routine.  To add 
  199. Xsupport for a new device type, only p_wr_pix() is changed, along 
  200. Xwith the appropriate parameters in bitmaps.h and the g_init() and 
  201. Xg_finish() routines (for initializing and releasing graphics resources, 
  202. Xrespectively).
  203. X
  204. XPositioning on the screen is done with a "graphics cursor" (not visible
  205. Xon the screen), which is used to position all graphics and text output.
  206. XThe cursor is positioned in normalized coordinates using the n_movepen()
  207. Xroutine.  Routines such as n_draw() cause the cursor to be moved to new
  208. Xpositions.
  209. X
  210. XThe n_box(), n_line(), n_ellipse() and n_arc() routines, as well as the
  211. Xstroke font text, call n_movepen() and n_draw() to position the cursor
  212. Xand draw a vector, respectively.  This is the basis of all the graphical
  213. Xoutput, with the low level output handled by p_wr_pix(). 
  214. X
  215. XTwo types of text output are supported.  A stroke font is invoked by
  216. Xn_grafstr(), and a bit cell font is invoked by c_cellstr().  N_grafchar()
  217. Xand c_cellchar() are single character versions which should normally
  218. Xnot be directly called (just use the n_grafstr() and c_cellstr() versions).
  219. XC_cursor() is used to position the graphics cursor in terms of character
  220. Xrows and columns, as if it were a text cursor.  G_fontctl() is used to
  221. Xcontrol attributes of the stroke font.
  222. X
  223. XThe g_finish() routine detaches shared memory, frees resources, and 
  224. Xsends any output to the print queue.
  225. X
  226. XAll routines are written in C (no assembler at all) and use short integer
  227. Xarithmetic wherever possible.  Long integers are used when more accuracy
  228. Xis required, and floats and doubles are avoided wherever possible.  Trig
  229. Xfunctions may be done with tables and integer math (if NOFLOAT is defined
  230. Xin config.h).  The overall performance is quite acceptable, even for text 
  231. Xoutput, and is in fact considerably faster than similar code under MS-DOS 
  232. Xusing BIOS rather than p_wr_pix().  The development machine for this 
  233. Xcode is a 6 MHz Zenith 241 with no 80287 coprocessor, hence the avoidance 
  234. Xof floating point math.
  235. X
  236. XBugs:
  237. X-----
  238. X
  239. X-Pix_mode() does not set XOR mode for EGA high res graphics.  
  240. X-Pix_color() does not do anything for EGA high res graphics.
  241. X-G_weight() does not do anything (not yet implemented).
  242. X-The arc() routine in plot(3) varies slightly from the BSD version in its 
  243. X calculation of the second arc endpoint.
  244. X-G_init() sets a signal handler to clean up the screen before exiting, and
  245. X-g_finish() restores the handler to its previous value.  This may interfere
  246. X with an application's intended signal handling (the DO_CLEANUP macro in
  247. X config.h can eliminate this behavior).
  248. X-For MS-DOS versions, graphics printer output must be done with BIOS calls.  
  249. X Therefore, the default system printer device must be used, and the 
  250. X PLOTDEV environment variable has no meaning.
  251. X
  252. XLimitations:
  253. X------------
  254. X
  255. XNo checking is done to control ownership of the console output.  The
  256. Xuser of the program is assumed to be at the console.  Any checks for
  257. Xthis would have to be done by an application program using these
  258. Xroutines.
  259. X
  260. XThe EGA and VGA adapters control color and writing modes (OR or XOR)
  261. Xwith output to port addresses on the EGA/VGA card.  On System V/AT,
  262. Xthis requires use of the outb() subroutine with write access to /dev/mem.
  263. XSince this would require the application program to be suid to root,
  264. Xsupport for color and writing modes has not yet been implemented.
  265. X
  266. XThe graphics.h file has declarations for parameters that will be used
  267. Xfor various coordinate transformations.  However, none of this is
  268. Ximplemented at the present time (except for the plot(3) interface, with
  269. Xits "space()" routine).  The only coordinate system which the application 
  270. Xprogram should refer to is the normalized 2-D space used to represent 
  271. Xthe screen.
  272. X
  273. XCredits:
  274. X--------
  275. X
  276. XThanks to John Antypas, Denis Fortin and Bill Rankin for assistance in
  277. Xtesting and developing the code.  
  278. X
  279. XThe font.h and cellfont.h files contain data for stroke fonts and bit cell
  280. Xfonts, respectively.  Copyright status of this data is uncertain.  Data 
  281. Xfor the stroke font are derived from listings in _Advanced_Graphics_in_C_, 
  282. Xby Nelson Johnson (McGraw-Hill, 1987).  The copyright notice for this book
  283. Xspecifically allows copying of the code, but does not say if you need to
  284. Xhave purchased the book to be so entitled.  I recommend the book, in any
  285. Xcase, so you may wish to buy a copy.  The bit cell font was received third
  286. Xor fourth hand, and is presumed public domain unless I hear otherwise.  The
  287. Xname at the head of the data file is:
  288. X
  289. X    /* RAM-Loadable Character Sets for the IBM PC
  290. X     Richard Wilton
  291. X     July 1986 */
  292. X
  293. XIn any case, if you can locate the font data in your machine's BIOS, you
  294. Xcan use that instead, and you are presumably licenced to do so by virtue
  295. Xhaving bought the machine.
  296. X
  297. XThe setmode.c code comes from Jeff Turner, and was posted to Usenet
  298. Xa while back.  It has been modified by me for Everex Edge and Hercules
  299. Xgraphics, and is presumed in the public domain.  
  300. X
  301. XThe rest of the material is copyrighted by me, but may be used and
  302. Xcopied by anybody, as long as it is not used for commercial profit.
  303. XI would very much appreciate hearing about any bug fixes and new 
  304. Xdevice support that may be forthcoming.  Thanks. 
  305. X
  306. X
  307. X                David T. Lewis  
  308. X                umix!m-net!dtlewis!lewis
  309. X                122 S. Seventh
  310. X                Ann Arbor MI  48103
  311. X
  312. X                system5 dtlewis 2 2.4.0-U AT
  313. X                Tue Feb 21 05:44:01 EST 1989
  314. X
  315. XxX--EOF--XxX
  316. echo restoring c_cellch.c
  317. sed 's/^X//' > c_cellch.c <<XxX--EOF--XxX
  318. X#ifndef lint
  319. Xstatic char sccsid[] = "@(#) c_cellch.c 5.1 89/02/20";
  320. X#endif
  321. X
  322. X/*
  323. X *    Copyright (c) David T. Lewis 1988
  324. X *    All rights reserved.
  325. X *
  326. X *    Permission is granted to use this for any personal noncommercial use.
  327. X *    You may not distribute source or executable code for profit, nor
  328. X *    may you distribute it with a commercial product without the written
  329. X *    consent of the author.  Please send modifications to the author for
  330. X *    inclusion in updates to the program.  Thanks.
  331. X */
  332. X
  333. X/* Write a graphics character to the screen.                */
  334. X/* This routine uses bit mapped character cell fonts.            */
  335. X/* The character will be drawn such that the current graphics cursor    */
  336. X/* denotes the upper left corner of the character cell.  The graphics    */
  337. X/* cursor will be incremented in the X direction by an amount corres-    */
  338. X/* ponding to one character cell.  The location of the graphics cursor    */
  339. X/* may be set by calls to either c_cursor() or p_movepen() prior    */
  340. X/* calling this routine.                         */
  341. X
  342. X/* Tue Mar 15 22:46:31 EST 1988                        */
  343. X/* system5 dtlewis 2 2.3.0-U AT                        */
  344. X
  345. X#include "config.h"
  346. X#include "bitmaps.h"
  347. X#include "graphics.h"
  348. X#include "cellfont.h"
  349. X
  350. Xextern struct GL_graphics graphics;
  351. Xextern int p_wr_pix(), n_movepen();
  352. X
  353. Xint c_cellchar(asc_char)  
  354. Xunsigned char asc_char;
  355. X{
  356. X    int x, y, i, j;
  357. X    int istat = 0;
  358. X
  359. X    char *bits; 
  360. X
  361. X    /* Get the pixel location.                    */
  362. X    x = n_to_p_x(graphics.x_cursor);
  363. X    y = n_to_p_y(graphics.y_cursor);
  364. X
  365. X    /* Check for x or y off the screen.            */
  366. X#if INT16
  367. X    /* 16 bit integers, use simple check.            */
  368. X        if (x < 0 ) return(1);
  369. X        if (y < 0 ) return(1);
  370. X#else
  371. X    /* Use explicit check.                    */
  372. X        if ((x < 0) || (x > NRM_X_RANGE)) return(1);
  373. X        if ((y < 0) || (y > NRM_X_RANGE)) return(1);
  374. X#endif /* INT16 */
  375. X
  376. X    /* Increment the graphics cursor.                */
  377. X
  378. X    if (n_movepen(graphics.x_cursor + graphics.cellfont.xtic,
  379. X        graphics.y_cursor)) istat = 1;
  380. X
  381. X    /* Point at the character bit map to print.            */
  382. X    bits = (char *) &(charcell[asc_char * Y_CELL_BITS]);
  383. X
  384. X    /* Write the character.                        */
  385. X    for (i=y; i < y + Y_CELL_BITS; i++, bits++) {
  386. X        j=x;
  387. X        if (*bits & 0x80) if (p_wr_pix(j,i)) istat = 1; j++;
  388. X        if (*bits & 0x40) if (p_wr_pix(j,i)) istat = 1; j++;
  389. X        if (*bits & 0x20) if (p_wr_pix(j,i)) istat = 1; j++;
  390. X        if (*bits & 0x10) if (p_wr_pix(j,i)) istat = 1; j++;
  391. X        if (*bits & 0x08) if (p_wr_pix(j,i)) istat = 1; j++;
  392. X        if (*bits & 0x04) if (p_wr_pix(j,i)) istat = 1; j++;
  393. X        if (*bits & 0x02) if (p_wr_pix(j,i)) istat = 1; j++;
  394. X        if (*bits & 0x01) if (p_wr_pix(j,i)) istat = 1; j++;
  395. X    }
  396. X
  397. X    return(istat);
  398. X}
  399. XxX--EOF--XxX
  400. echo restoring c_cellst.c
  401. sed 's/^X//' > c_cellst.c <<XxX--EOF--XxX
  402. X#ifndef lint
  403. Xstatic char sccsid[] = "@(#) c_cellst.c 5.1 89/02/20";
  404. X#endif
  405. X
  406. X/*
  407. X *    Copyright (c) David T. Lewis 1988
  408. X *    All rights reserved.
  409. X *
  410. X *    Permission is granted to use this for any personal noncommercial use.
  411. X *    You may not distribute source or executable code for profit, nor
  412. X *    may you distribute it with a commercial product without the written
  413. X *    consent of the author.  Please send modifications to the author for
  414. X *    inclusion in updates to the program.  Thanks.
  415. X */
  416. X
  417. X/* Write string of a graphics characters to the screen.            */
  418. X/* Sat Mar 19 23:56:46 EST 1988                        */
  419. X/* system5 dtlewis 2 2.3.0-U AT                        */
  420. X
  421. X/* Routine to display cell mode text string with upper left corner of    */
  422. X/* first character located at the current graphics cursor.  The        */
  423. X/* graphics cursor is incremented as characters are written.        */
  424. X
  425. X#include <stdio.h>
  426. X#include "config.h"
  427. Xextern int c_cellchar();
  428. X
  429. Xint c_cellstr(strng)  
  430. Xchar strng[];
  431. X{
  432. X    int i;
  433. X    for(i=0; strng[i] != 0; i++)  {
  434. X        if (c_cellchar(strng[i])) return(1);
  435. X    }
  436. X    return(0);
  437. X}
  438. X
  439. XxX--EOF--XxX
  440. echo restoring c_cursor.c
  441. sed 's/^X//' > c_cursor.c <<XxX--EOF--XxX
  442. X#ifndef lint
  443. Xstatic char sccsid[] = "@(#) c_cursor.c 5.1 89/02/20";
  444. X#endif
  445. X
  446. X/*
  447. X *    Copyright (c) David T. Lewis 1988
  448. X *    All rights reserved.
  449. X *
  450. X *    Permission is granted to use this for any personal noncommercial use.
  451. X *    You may not distribute source or executable code for profit, nor
  452. X *    may you distribute it with a commercial product without the written
  453. X *    consent of the author.  Please send modifications to the author for
  454. X *    inclusion in updates to the program.  Thanks.
  455. X */
  456. X
  457. X/* Move the graphics cursor as if it were a text cursor.  The cursor    */
  458. X/* is positioned such that a cell character may be drawn at the        */
  459. X/* specified character row and column.                    */
  460. X/* This routine uses bit mapped character cell fonts.            */
  461. X/* The character will be drawn such that the current graphics cursor    */
  462. X/* denotes the upper left corner of the character cell.            */
  463. X
  464. X/* Columns and rows are numbered 1 through N, not 0 through N !!!!    */
  465. X
  466. X#include "config.h"
  467. X#include "bitmaps.h"
  468. X#include "graphics.h"
  469. X
  470. Xextern struct GL_graphics graphics;
  471. Xextern int n_movepen();
  472. X
  473. Xint c_cursor(row, col)
  474. Xint row, col;
  475. X{
  476. X    long xval, yval;
  477. X
  478. X    /* Check valid range for this screen type.            */
  479. X    if (col <= 0 || col > graphics.cellfont.chars_per_line) return(1);
  480. X    if (row <= 0 || row > graphics.cellfont.lines_per_screen) return(1);
  481. X
  482. X    /* Move the graphics cursor.                    */
  483. X
  484. X    /* Calculate size of pixel, and move cursor accordingly.  The    */
  485. X    /* calculations are rearranged for computational accuracy, and    */
  486. X    /* the results rounded up to put us on the correct pixel.    */
  487. X
  488. X    xval = NRM_X_RANGE * X_CELL_BITS * (col-1) / graphics.x_extent;
  489. X    xval++;    /* Round up.    */
  490. X
  491. X    yval = NRM_Y_RANGE * Y_CELL_BITS * (row-1) / graphics.y_extent;
  492. X    yval++;
  493. X
  494. X    if (n_movepen((int)xval, (int)yval)) return(1);
  495. X
  496. X    return(0);
  497. X}
  498. XxX--EOF--XxX
  499. echo restoring g_clear.c
  500. sed 's/^X//' > g_clear.c <<XxX--EOF--XxX
  501. X#ifndef lint
  502. Xstatic char sccsid[] = "@(#) g_clear.c 5.1 89/02/20";
  503. X#endif
  504. X
  505. X/*
  506. X *    Copyright (c) David T. Lewis 1987, 1988
  507. X *    All rights reserved.
  508. X *
  509. X *    Permission is granted to use this for any personal noncommercial use.
  510. X *    You may not distribute source or executable code for profit, nor
  511. X *    may you distribute it with a commercial product without the written
  512. X *    consent of the author.  Please send modifications to the author for
  513. X *    inclusion in updates to the program.  Thanks.
  514. X */
  515. X
  516. X/*
  517. X *    Routine to clear video memory (or print buffer memory).  
  518. X *    dtlewis 6-28-87
  519. X *    Sun Mar 13 21:13:59 EST 1988
  520. X */
  521. X
  522. X#include "config.h"
  523. X#include "bitmaps.h"
  524. X#include "graphics.h"
  525. X#include "modes.h"
  526. X
  527. Xextern int g_init(), g_finish();
  528. X
  529. Xint g_clear()  
  530. X{
  531. X    extern struct GL_graphics graphics;
  532. X    int i, j;
  533. X    int istat;
  534. X
  535. X#if MIX_C
  536. X    /* No long pointers with this compiler.  Cheat and use BIOS.    */
  537. X    g_setmod(graphics.grafmode);
  538. X    return(0);
  539. X#endif /* MIX_C */
  540. X
  541. X    switch (graphics.grafmode) {
  542. X        case CGA_COLOR_MODE:
  543. X            for(i=0; i<100; i++)  {
  544. X                for(j=0; j<80; j++)  {
  545. X                    (graphics.cgamem)->page1[i][j] = 0x0;
  546. X                    (graphics.cgamem)->page2[i][j] = 0x0;
  547. X                }
  548. X            }
  549. X            break;
  550. X
  551. X        case CGA_HI_RES_MODE:
  552. X            for(i=0; i<100; i++)  {
  553. X                for(j=0; j<80; j++)  {
  554. X                    (graphics.cgamem)->page1[i][j] = 0x0;
  555. X                    (graphics.cgamem)->page2[i][j] = 0x0;
  556. X                }
  557. X            }
  558. X            break;
  559. X
  560. X        case EGA_COLOR_MODE:
  561. X            for (i=0 ; i<350 ; i++) {
  562. X                for (j=0 ; j<80 ; j++) {
  563. X                    (graphics.egamem)->mem[i][j] = 0x0;
  564. X                }
  565. X            }
  566. X            break;
  567. X
  568. X        case HERC_P0_MODE:
  569. X        case HERC_P1_MODE:
  570. X            for(i=0; i<87; i++)  {
  571. X                for(j=0; j<90; j++)  {
  572. X                    (graphics.hercmem)->page1[i][j] = 0x0;
  573. X                    (graphics.hercmem)->page2[i][j] = 0x0;
  574. X                    (graphics.hercmem)->page3[i][j] = 0x0;
  575. X                    (graphics.hercmem)->page4[i][j] = 0x0;
  576. X                }
  577. X            }
  578. X            break;
  579. X
  580. X        /* For hard copy, there is no point in clearing    */
  581. X        /* memory.  We will interpret this call as    */
  582. X        /* "done with this page; send it to the printer    */
  583. X        /* and get ready for another."            */
  584. X
  585. X        case IBM_PRINTER:
  586. X            if ((istat=g_finish()) != 0) return(istat);
  587. X            if ((istat=g_init(IBM_PRINTER)) != 0) return(istat);
  588. X            break;
  589. X
  590. X        case LJ_PRINTER:
  591. X            if ((istat=g_finish()) != 0) return(istat);
  592. X            if ((istat=g_init(LJ_PRINTER)) != 0) return(istat);
  593. X            break;
  594. X
  595. X        default:
  596. X            return(1);
  597. X
  598. X    }
  599. X    return(0);
  600. X}
  601. XxX--EOF--XxX
  602. echo restoring n_box.c
  603. sed 's/^X//' > n_box.c <<XxX--EOF--XxX
  604. X#ifndef lint
  605. Xstatic char sccsid[] = "@(#) n_box.c 5.1 89/02/20";
  606. X#endif
  607. X
  608. X/*
  609. X *    Copyright (c) David T. Lewis 1987, 1988
  610. X *    All rights reserved.
  611. X *
  612. X *    Permission is granted to use this for any personal noncommercial use.
  613. X *    You may not distribute source or executable code for profit, nor
  614. X *    may you distribute it with a commercial product without the written
  615. X *    consent of the author.  Please send modifications to the author for
  616. X *    inclusion in updates to the program.  Thanks.
  617. X */
  618. X
  619. X/* Fri Jul  3 23:43:36 EDT 1987
  620. X * dtlewis
  621. X * Routine to draw a box.
  622. X */
  623. X
  624. Xextern int n_movepen(), n_draw();
  625. X
  626. Xint n_box(x1,y1,x2,y2)  
  627. X    int x1, y1, x2, y2;
  628. X{
  629. X    int n_movepen(), n_draw();
  630. X    if (n_movepen(x1,y1)) return(1);
  631. X    if (n_draw(x2,y1)) return(1);
  632. X    if (n_draw(x2,y2)) return(1);
  633. X    if (n_draw(x1,y2)) return(1);
  634. X    if (n_draw(x1,y1)) return(1);
  635. X    return(0);
  636. X}
  637. XxX--EOF--XxX
  638. echo restoring n_draw.c
  639. sed 's/^X//' > n_draw.c <<XxX--EOF--XxX
  640. X#ifndef lint
  641. Xstatic char sccsid[] = "@(#) n_draw.c 5.1 89/02/20";
  642. X#endif
  643. X
  644. X/*
  645. X *    Copyright (c) David T. Lewis 1987, 1988, 1989
  646. X *    All rights reserved.
  647. X *
  648. X *    Permission is granted to use this for any personal noncommercial use.
  649. X *    You may not distribute source or executable code for profit, nor
  650. X *    may you distribute it with a commercial product without the written
  651. X *    consent of the author.  Please send modifications to the author for
  652. X *    inclusion in updates to the program.  Thanks.
  653. X */
  654. X
  655. X/*  Sat Mar 21 22:59:10 EST 1987 */
  656. X/*  dtl 2-8-87
  657. X**
  658. X**    Write a line on the CGA or Hercules adapter.
  659. X**    This routine assumes that the current graphics cursor position is
  660. X**    set, and draws a line to the indicated point.
  661. X*/
  662. X
  663. X#include "config.h"
  664. X#include "bitmaps.h"
  665. X#include "graphics.h"
  666. X#include "gf_types.h"
  667. X
  668. X#define ROT_MASK (0x80000000L)
  669. X
  670. Xextern struct GL_graphics graphics;
  671. Xextern int (*p_do_pix)();
  672. X
  673. Xn_draw(new_x_cursor,new_y_cursor)  
  674. X    int new_x_cursor, new_y_cursor;
  675. X{
  676. X
  677. X        /* Draw line from current cursor to new position. */
  678. X        /* Parameters are in normalized 2-D coordinates. */
  679. X
  680. X        int x_dist;     /* Pixel coordinates */
  681. X        int y_dist;     /* Pixel coordinates */
  682. X        int x_start;    /* Pixel coordinates */
  683. X        int y_start;    /* Pixel coordinates */
  684. X        int x_final;     /* Pixel coordinates */
  685. X        int y_final;     /* Pixel coordinates */
  686. X        int x_current;  /* Pixel coordinates */
  687. X        int y_current;  /* Pixel coordinates */
  688. X    int x_pixels;    /* X distance in pixels */
  689. X    int y_pixels;    /* Y distance in pixels */
  690. X        long int slope;
  691. X        int offset;
  692. X        long int idx;
  693. X
  694. X    /* Check for out of range.  If either the start or end    */
  695. X    /* point would be off the screen, then we have a    */
  696. X    /* problem.                        */
  697. X
  698. X#if INT16
  699. X    /* 16 bit integers, use simple check.            */
  700. X    if (graphics.x_cursor < 0 || graphics.y_cursor < 0 || 
  701. X        new_x_cursor < 0 || new_y_cursor < 0)
  702. X#else
  703. X    /* Use explicit check.                    */
  704. X    if (    (graphics.x_cursor < 0) 
  705. X        || (graphics.x_cursor > NRM_X_RANGE) 
  706. X        || (graphics.y_cursor < 0) 
  707. X        || (graphics.y_cursor > NRM_Y_RANGE) 
  708. X        || (new_x_cursor < 0)
  709. X        || (new_x_cursor > NRM_X_RANGE)
  710. X        || (new_y_cursor < 0)
  711. X        || (new_y_cursor > NRM_Y_RANGE))
  712. X#endif /* INT16 */
  713. X    {
  714. X        /* Advance the cursor to the new position, even if    */
  715. X        /* it is not a valid location.  In the case where the    */
  716. X        /* current cursor is invalid but the new value is good,    */
  717. X        /* this will correct the problem.  In the case where    */
  718. X        /* the new value is bad, we will want to leave it that    */
  719. X        /* way for the next invocation of n_draw().        */
  720. X        graphics.x_cursor = new_x_cursor;
  721. X        graphics.y_cursor = new_y_cursor;
  722. X        return(1);
  723. X    }
  724. X
  725. X        /* Find the starting point in pixel coordinates. */
  726. X  
  727. X        x_current = x_start = n_to_p_x(graphics.x_cursor);
  728. X        y_current = y_start = n_to_p_y(graphics.y_cursor);
  729. X
  730. X        /* Find the end point in pixel coordinates. */
  731. X  
  732. X        x_final = n_to_p_x(new_x_cursor);
  733. X        y_final = n_to_p_y(new_y_cursor);
  734. X
  735. X    /* Find the distances in pixel coordinates. */
  736. X
  737. X        x_dist = x_final - x_start;
  738. X        y_dist = y_final - y_start;
  739. X
  740. X    /* Find the number of pixels to travel in the x any y directions. */
  741. X
  742. X    x_pixels = abs(x_dist);
  743. X    y_pixels = abs(y_dist);
  744. X
  745. X        /* Step across the screen pixel by pixel.  Do this in the x     */
  746. X        /* direction if x_dist is greater than y_dist; else, do it in    */
  747. X        /* the y direction.                        */
  748. X
  749. X        if (x_pixels > y_pixels) {
  750. X                /* Stepwise in x direction. */
  751. X
  752. X                /* Calculate the slope to use (rise over run). */
  753. X                /* Shift left 16 bits for precision. */
  754. X                if (x_dist != 0) slope = (long)y_dist * 0x010000L / 
  755. X                (long)x_dist;
  756. X                else slope = 0x7FFFFFFFL; /* Infinity */
  757. X
  758. X                /* Figure a fudge factor to be used in offsetting the */
  759. X                /* pixels by 1/2 pixel. */
  760. X                if (slope > 0) offset = 1;
  761. X                else if (slope < 0) offset = -1;
  762. X                else offset = 0;
  763. X
  764. X                /* Write the line on the screen. */
  765. X
  766. X                if (x_final - x_start >= 0)  {
  767. X                        if (slope==0)  {
  768. X                                while (x_current <= x_final)
  769. X                    if ((*p_do_pix)(x_current++, 
  770. X                        y_current)) return(1);
  771. X                        }
  772. X                        else for (idx=0; idx <= x_pixels; idx++, x_current++)  {
  773. X                                y_current = y_start + (idx*slope/0x08000L 
  774. X                                + offset)/2;
  775. X                                if ((*p_do_pix)(x_current, y_current))
  776. X                    return(1);
  777. X                        }
  778. X                }
  779. X                else  {
  780. X                        if (slope==0)  {
  781. X                while (x_current >= x_final)
  782. X                                        if ((*p_do_pix)(x_current--, 
  783. X                        y_current)) return(1);
  784. X                        }
  785. X                        else for (idx=0; idx <= x_pixels; idx++, x_current--)  {
  786. X                                y_current = y_start - (idx*slope/0x08000L 
  787. X                                + offset)/2;
  788. X                                if ((*p_do_pix)(x_current, y_current)) 
  789. X                    return(1);
  790. X                        }
  791. X                }
  792. X        }
  793. X        else  {
  794. X                /* Stepwise in y direction. */
  795. X
  796. X                /* Calculate the inverse slope to use (run over rise). */
  797. X                /* Shift left 16 bits for precision. */
  798. X                if (y_dist != 0) slope = (long)x_dist * 0x010000L / 
  799. X                (long)y_dist;
  800. X                else slope = 0x7FFFFFFF; /* Infinity */
  801. X
  802. X                /* Figure a fudge factor to be used in offsetting the */
  803. X                /* pixels by 1/2 pixel. */
  804. X                if (slope > 0) offset = 1;
  805. X                else if (slope < 0) offset = -1;
  806. X                else offset = 0;
  807. X
  808. X               /* Write the line on the screen. */
  809. X
  810. X                if (y_final - y_start >= 0)  {
  811. X                        if (slope==0)  {
  812. X                                while (y_current <= y_final)
  813. X                                        if ((*p_do_pix)(x_current, 
  814. X                        y_current++)) return(1);
  815. X                        }
  816. X                        else for (idx=0; idx <= y_pixels; idx++, y_current++)  {
  817. X                                x_current = x_start + (idx*slope/0x08000L 
  818. X                                + offset)/2;
  819. X                                if ((*p_do_pix)(x_current, y_current))
  820. X                    return(1);
  821. X                        }
  822. X                }
  823. X                else  {
  824. X                        if (slope==0)  {
  825. X                while (y_current >= y_final)
  826. X                                        if ((*p_do_pix)(x_current, 
  827. X                        y_current--)) return(1);
  828. X                        }
  829. X                        else for (idx=0; idx <= y_pixels; idx++, y_current--)  {
  830. X                                x_current = x_start - (idx*slope/0x08000L 
  831. X                                + offset)/2;
  832. X                                if ((*p_do_pix)(x_current, y_current))
  833. X                    return(1);
  834. X                        }
  835. X                }
  836. X        }
  837. X        /* Advance the cursor to the new position. */
  838. X        graphics.x_cursor = new_x_cursor;
  839. X        graphics.y_cursor = new_y_cursor;
  840. X    return(0);
  841. X}
  842. XxX--EOF--XxX
  843. echo restoring n_gfchar.c
  844. sed 's/^X//' > n_gfchar.c <<XxX--EOF--XxX
  845. X#ifndef lint
  846. Xstatic char sccsid[] = "@(#) n_gfchar.c 5.1 89/02/20";
  847. X#endif
  848. X
  849. X/*
  850. X *    Copyright (c) David T. Lewis 1987, 1988
  851. X *    All rights reserved.
  852. X *
  853. X *    Permission is granted to use this for any personal noncommercial use.
  854. X *    You may not distribute source or executable code for profit, nor
  855. X *    may you distribute it with a commercial product without the written
  856. X *    consent of the author.  Please send modifications to the author for
  857. X *    inclusion in updates to the program.  Thanks.
  858. X */
  859. X
  860. X/* Adapted from a routine in _Advanced_Graphics_in_C_, by Nelson    */
  861. X/* Johnson, McGraw-Hill, 1987.                        */
  862. X
  863. X/* Write a graphics character to the screen; advance cursor.        */
  864. X/* Sat Dec 12 12:51:27 EST 1987                        */
  865. X/* system5 dtlewis 2 2.2-U AT                        */
  866. X
  867. X#include "config.h"
  868. X#if MIX_C
  869. X#else
  870. X#include <math.h>
  871. X#endif /* MIX_C */
  872. X#include "font.h"
  873. X#include "bitmaps.h"
  874. X#include "graphics.h"
  875. X
  876. Xextern struct GL_graphics graphics;
  877. X
  878. Xextern int i_rot_2d_s();
  879. Xextern int n_line(), n_movepen();
  880. Xextern long longsin();
  881. X
  882. Xint n_grafchar(asc_char)
  883. Xunsigned char asc_char;
  884. X{
  885. X    int x, y, x_1, y_1, x_2, y_2, i;
  886. X    int istat = 0;
  887. X    double theta;
  888. X    float sin_slant;
  889. X    long l_sin_slant;
  890. X    int xscale, yscale, xinc, yinc;
  891. X    int tempval;
  892. X
  893. X    union  
  894. X        {
  895. X        struct  
  896. X            {
  897. X            unsigned xval_2 : 4;
  898. X            unsigned yval_2 : 4;
  899. X            unsigned xval_1 : 4;
  900. X            unsigned yval_1 : 4;
  901. X            }  nibble;
  902. X        struct
  903. X            {
  904. X            unsigned word;
  905. X            }  whole;
  906. X        }  fontline;
  907. X
  908. X    x = graphics.x_cursor;
  909. X    y = graphics.y_cursor;
  910. X
  911. X    xscale = graphics.strokefont.xsize;
  912. X    yscale = graphics.strokefont.ysize;
  913. X    xinc = graphics.strokefont.xtic;
  914. X    yinc = 0;
  915. X
  916. X    /* Calculate rotation angle for text and cursor motion.        */
  917. X
  918. X    if (graphics.strokefont.angle_flag)  {
  919. X
  920. X        theta = - (double)(graphics.strokefont.angle);
  921. X        i_rot_2d_s( &xinc, &yinc, theta);
  922. X    }
  923. X
  924. X    for (i=0; i<=35; i++)  {
  925. X        if ((fontline.whole.word = stroke[asc_char][i]) != 0xFFFF) {
  926. X
  927. X            /* Get the endpoints for this stroke line.    */
  928. X
  929. X            x_1 = fontline.nibble.xval_1 * xscale;
  930. X            y_1 = fontline.nibble.yval_1 * yscale;
  931. X            x_2 = fontline.nibble.xval_2 * xscale;
  932. X            y_2 = fontline.nibble.yval_2 * yscale;
  933. X
  934. X            /* Slant characters if necessary.        */
  935. X
  936. X            if (graphics.strokefont.slant_flag)  {
  937. X
  938. X                /* We want to slant the top of the     */
  939. X                /* character to the right, rather than    */
  940. X                /* slanting the bottom to the left.    */
  941. X                /* Use tempval as an offset.        */
  942. X
  943. X                tempval = yscale * FONTSIZE;
  944. X
  945. X#if NOFLOAT  /* Use integer math for speed.    */
  946. X
  947. X                l_sin_slant
  948. X                    = longsin(graphics.strokefont.slant);
  949. X
  950. X                x_1 += (int)((l_sin_slant * (tempval - y_1))
  951. X                    / TRIG_SCALE);
  952. X                x_2 += (int)((l_sin_slant * (tempval - y_2))
  953. X                    / TRIG_SCALE);
  954. X
  955. X#else  /* Use normal math library.    */
  956. X
  957. X                sin_slant
  958. X                    = (float)sin(graphics.strokefont.slant);
  959. X
  960. X                x_1 += (int)(sin_slant * (float)(tempval - y_1));
  961. X                x_2 += (int)(sin_slant * (float)(tempval - y_2));
  962. X
  963. X#endif /* NOFLOAT */
  964. X            }
  965. X
  966. X            /* If necessary, rotate vectors based on angle.    */
  967. X
  968. X            if (graphics.strokefont.angle_flag)  {
  969. X
  970. X                i_rot_2d_s( &x_1, &y_1, theta);
  971. X                i_rot_2d_s( &x_2, &y_2, theta);
  972. X            }
  973. X
  974. X            /* Translate to screen location.        */
  975. X
  976. X            x_1 += x;
  977. X            y_1 += y;
  978. X            x_2 += x;
  979. X            y_2 += y;
  980. X
  981. X            /* Draw the line.                */
  982. X
  983. X            if (n_line( x_1, y_1, x_2, y_2)) istat = 1;
  984. X        }
  985. X    }
  986. X
  987. X    /* Move the cursor.                        */
  988. X
  989. X    if (n_movepen(x + xinc, y + yinc)) istat = 1;
  990. X
  991. X    return(istat);
  992. X}
  993. X
  994. XxX--EOF--XxX
  995. echo restoring n_gfstr.c
  996. sed 's/^X//' > n_gfstr.c <<XxX--EOF--XxX
  997. X#ifndef lint
  998. Xstatic char sccsid[] = "@(#) n_gfstr.c 5.1 89/02/20";
  999. X#endif
  1000. X
  1001. X/*
  1002. X *    Copyright (c) David T. Lewis 1987, 1988
  1003. X *    All rights reserved.
  1004. X *
  1005. X *    Permission is granted to use this for any personal noncommercial use.
  1006. X *    You may not distribute source or executable code for profit, nor
  1007. X *    may you distribute it with a commercial product without the written
  1008. X *    consent of the author.  Please send modifications to the author for
  1009. X *    inclusion in updates to the program.  Thanks.
  1010. X */
  1011. X
  1012. X/* Write string of a graphics characters to the screen.            */
  1013. X/* Sat Dec 12 12:51:27 EST 1987                        */
  1014. X/* system5 dtlewis 2 2.2-U AT                        */
  1015. X
  1016. X#include <stdio.h>
  1017. X
  1018. Xextern int n_grafchar();
  1019. X
  1020. Xint n_grafstr(strng)  
  1021. Xchar strng[];
  1022. X{
  1023. X    int i;
  1024. X    for(i=0; strng[i] != 0; i++)  {
  1025. X        if (n_grafchar(strng[i])) return(1);
  1026. X    }
  1027. X    return(0);
  1028. X}
  1029. X
  1030. XxX--EOF--XxX
  1031.  
  1032.  
  1033.