[comp.sys.acorn] Drawing lines in C

ecwu61@castle.ed.ac.uk (R Renwick) (02/22/91)

	To those of you who are used to programming in C, this may seem
like a very silly question but I'm going to ask it anyway.
	I want to plot lines on the screen in C, not under the wimp. 
How can I do it???  I can't seem to find an example anywhere.
	Any hints, tips, examples or otherwise greatfully accepted.

Cheers,
	Rik

Oh if only everything was as simple as ML!!! [:-)

aighb@castle.ed.ac.uk (Geoffrey Ballinger) (02/22/91)

In article <8671@castle.ed.ac.uk> ecwu61@castle.ed.ac.uk (R Renwick) writes:
-	I want to plot lines on the screen in C, not under the wimp. 
-How can I do it???  I can't seem to find an example anywhere.

	I would guess you want some form of graphics library or are
there graphics calls in the riscos library?

-Oh if only everything was as simple as ML!!! [:-)

	OK, How does one do it in ML (;-)?

Geoff (who has been put through many hours of ML torture).
-- 
 Geoff Ballinger,                           EMAIL: Geoff@Ed.Ac.Uk
 Department of Artificial Intelligence,
 University of Edinburgh, 80 South Bridge,
 Edinburgh, Scotland.

andras@alzabo.ocunix.on.ca (Andras Kovacs) (02/25/91)

In article <8671@castle.ed.ac.uk> ecwu61@castle.ed.ac.uk (R Renwick) writes:
>	I want to plot lines on the screen in C, not under the wimp. 
>How can I do it???  I can't seem to find an example anywhere.

  Here is an implementation of Bresenham's algorithm for line drawing.
Please don't judge my programming from this example :-); it is just to pass
on some code to the needy. Anyway, this program will draw random lines on
the screen. It does not do clipping; if your x coordinates are out of screen,
then it will wrap around; if the y ones are out of bounds then BOMB!BOMB!
I put the screen pointer into a global 'cause I would hate to pass it
everytime on the stack. As you observe there is some code duplicated in the
Line routine; it is an attempt to optimize by trading size for speed.
The plot is inlined to speed things up a bit.
  This implementation draws around 1400 lines per second (including the loop
overhead and the - significant - time required to generate the random
coordinates); a carefully coded and little bit cheating assembly version does
approx. 2200 lines/sec (in the same test bed). (John Kortink will understand
this; Tiggr and some others will try to squeeze the same performance out of
their C compilers but they are doomed :-) ).
  There is lots of ways to do clipping on different levels; you have to
choose for yourself the best one for the particular problem - but it will
slow down the line drawing (obviously).

---- cut here ----
#include <Arthur.h>
#include <stdio.h>
#include <stdlib.h>

void Line(int x1, int y1, int x2, int y2, char col);

int InputBlock[] = {149, -1};
char *screen;

int main(int argc, char *argv[])
{
   int i, limit;
   reg_set regs;

   if (argc != 2)
   {
      printf("Usage: Lines <# of lines>\n");
      return -1;
   }

   mode(13);

   regs.r[0] = (int)InputBlock;
   regs.r[1] = (int)(&screen);

   swi(XOS_MASK | OS_ReadVduVariables, &regs);

   swi(XOS_MASK | OS_RemoveCursors, &regs);

   limit = atoi(argv[1]);

#define  r(n)  rand() % n

   for (i = 0; i < limit; ++i)
      Line(r(320), r(256), r(320), r(256), r(256));

   getchar();
   mode(0);

   return 0;
}

void Line(int x1, int y1, int x2, int y2, char col)
{
   int dx, dy, e, yincr, xincr, tmp;

   if (abs(x2 - x1) >= abs(y2 - y1))
   {
      if (x1 > x2)
      {
         tmp = x1;
         x1 = x2;
         x2 = tmp;
         tmp = y1;
         y1 = y2;
         y2 = tmp;
      }
      dx = x2 - x1;
      dy = y2 - y1;
      if (dy > 0)
         yincr = 1;
      else
         yincr = -1;
      dy = abs(dy);
      e = (dy << 1) - dx;
      for ( ; x1 <= x2; ++x1)
      {
         *(screen + x1 + y1 * 320) = col;
         if (e > 0)
         {
            y1 += yincr;
            e -= dx << 1;
         }
         e += dy << 1;
      }
   }
   else
   {
      if (y1 > y2)
      {
         tmp = x1;
         x1 = x2;
         x2 = tmp;
         tmp = y1;
         y1 = y2;
         y2 = tmp;
      }
      dx = x2 - x1;
      dy = y2 - y1;
      if (dx > 0)
         xincr = 1;
      else
         xincr = -1;
      dx = abs(dx);
      e = (dx << 1) - dy;
      for ( ; y1 <= y2; ++y1)
      {
         *(screen + x1 + y1 * 320) = col;
         if (e > 0)
         {
            x1 += xincr;
            e -= dy << 1;
         }
         e += dx << 1;
      }
   }
}
---- cut here ----

  Oh, I just realized that there is no comments in this source; I suppose
I'll never be a CS student... :-)

  Andras
-- 
Andras Kovacs 
andras@alzabo.ocunix.on.ca
Nepean, Ont.

x51@nikhefh.nikhef.nl (Excursiecommissie) (02/28/91)

In article <1991Feb25.081646.15077@alzabo.ocunix.on.ca> andras@alzabo.UUCP (Andras Kovacs) writes:
>In article <8671@castle.ed.ac.uk> ecwu61@castle.ed.ac.uk (R Renwick) writes:
>>	I want to plot lines on the screen in C, not under the wimp. 
>>How can I do it???  I can't seem to find an example anywhere.
>
>  Here is an implementation of Bresenham's algorithm for line drawing.
>Please don't judge my programming from this example :-); it is just to pass

Jezus! (sorry), why do you want to do this on an Archimedes??????
Ok, it is interesting to see the Bresenham algorithm. But since the 
operating system supports lines (and other graphics stuff), why should
you go wild and implement your own line routines in C?
for speed? The OS routines are in Arm code, if you want them to be faster,
rewrite them again in Arm code, not in C.

NO, I DON'T WANT A LANGUAGE DISCUSSION AGAIN!!!

Remember that Risc OS is an Operating System, which supports the programmer,
and not a Disc Filer (like DOS), which hinders the programmer.

Axel

rst@cs.hull.ac.uk (Rob Turner) (03/01/91)

Geoffrey Ballinger writes:

>OK, How does one do it in ML (;-)?

You call a C library routine from your ML program, I guess :-).

Rob

ecwu61@castle.ed.ac.uk (R Renwick) (03/01/91)

In article <29216.9102281711@olympus.cs.hull.ac.uk> rst@cs.hull.ac.uk (Rob Turner) writes:
>Geoffrey Ballinger writes:
>
>>OK, How does one do it in ML (;-)?
>
>You call a C library routine from your ML program, I guess :-).
>
	An ML programmer call a C lib routine :-( 
Arghhhhhhhhhhhhhhhhhhh!

If it can't be done in ML alone, it's not worth doing ;-)

	Geoff's original comment was about drawing lines in ML.  Here's
the standard CS4 approach at Edinburgh Uni:

	1) Get some overhead projector pens (water soluble)
	2) Run ML program and output co-ordinates of the object to be plotted
	3) Use a ruler and plot the co-ords on the screen using OHP pen
	4) Recalulate the object's co-ords
	5) Use damp cloth to remove drawing from the screen
	6) Goto (3)

	I really don't see the problem here, it's fast, efficient and
requires less room than the C equivilent which takes nearly 300 giga
bytes ;-)


Rik

===============================================================================

    ############	Richard Renwick		ecwu61@uk.ac.ed.castle
   #            #	Computer Science 4	OR rlr@uk.ac.ed.lfcs
  @   ~~~  ~~~   @	University of Edinburgh
|\@    **  **    @/|	Edinburgh
| @    **  **    @ |	
|/@      ||      @\|	
  @  \   ||   /  @ 	
   @  \______/  @	"Doesn't the grass look funny from underneath?"
    @          @				- Penfold
     @@@@@@@@@@		

===============================================================================

csuwr@warwick.ac.uk (Derek Hunter) (03/04/91)

In article <8810@castle.ed.ac.uk> ecwu61@castle.ed.ac.uk (R Renwick) writes:
[stuff gone]
>If it can't be done in ML alone, it's not worth doing ;-)

>	1) Get some overhead projector pens (water soluble)
>	2) Run ML program and output co-ordinates of the object to be plotted
>	3) Use a ruler and plot the co-ords on the screen using OHP pen
>	4) Recalulate the object's co-ords
>	5) Use damp cloth to remove drawing from the screen
>	6) Goto (3)

But this ^^^^^ isn't in ML. Is it worth doing? :-)

>Rik

 - Derek Hunter

PS. With reference to the using Basic's assembler as a 'real' code assembler,
    this is exactly what I'll be doing from my compiler once I've stopped
    modifying the main record types all over the place and have it written
    (in C, using itself) as a relocatable module. (Yes, there is a use for
    Basic -@chain).