[comp.sys.amiga] Graphical Monitor of CPU-Blitter-Memory Use. 1 of 3

jvkelley@watcgl.waterloo.edu (Jeff Kelley) (10/30/87)

Attempts to post via comp.{sources,binaries}.amiga were unsuccessful.

Briefly, this is somewhat like 'xload' for those familiar with the
X Window System, but with Amiga specific features.  The program is
divided into two components: a 'virtual' device that monitors the
use of the CPU (really the ready queue length), the Blitter, and
memory, and the 'amyload' program which graphically displays this
information.

While I'm here, I might as well ask a couple of questions:

   1) Why is there an 'added' state for tasks?  Why isn't a created
      task in the 'ready' state?  This burned me once
      when I was expecting a newly created task to preempt its
      lower priority creator.

   2) When a SIMPLE_REFRESH window is moved without exposing previously
      obscured areas of the window, why doesn't Intuition simply copy
      the rectangular area to the new location, instead of sending
      REFRESHWINDOW events to the application?

Thanks, and enjoy!

-Jeff Kelley
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
UUCP:     {ihnp4,watmath}!watcgl!jvkelley |  Postal Address:
BITNET:   jvkelley@cgl.waterloo.bitnet    |     Jeff Kelley
INTERNET: jvkelley@cgl.waterloo.edu       |     Dept. of Computer Science
EAN:      jvkelley@cgl.waterloo.cdn       |     University of Waterloo
                                          |     Waterloo, Ont., Canada
                                          |     N2L 3G1
					  |  	tel:   (519) 578-4514

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watcgl!jvkelley on Sat Oct 17 20:16:30 EDT 1987
# Contents:  README amyload.doc makefile execdef.h intuidef.h
#	loadrecord.h windowinfo.h windownode.h amyload.c cleanup.c
#	closeloadwindow.c drawdataline.c drawreflines.c findmxdatapoint.c
#	findwindownode.c init.c newdata.c newloadrecord.c newscale.c
#	newwindowsize.c openloadwindow.c printmessage.c printrecordtype.c
#	redrawwindow.c scrollwindow.c setwindowinfo.c cleanup.proto
#	closeloadwindow.proto drawdataline.proto drawscalereferencelines.proto
#	findmaxdatapoint.proto findwindownode.proto init.proto newdata.proto
#	newloadrecord.proto newscale.proto newwindowsize.proto
#	openloadwindow.proto printmessage.proto printrecordtypes.proto
#	redrawwindow.proto scrollwindow.proto setwindowinfo.proto
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
Read amyload.doc for documentation.
Remember that load.device must be in your DEVS: directory.
@//E*O*F README//
chmod u=rw,g=r,o=r README
 
echo x - amyload.doc
sed 's/^@//' > "amyload.doc" <<'@//E*O*F amyload.doc//'

    NAME
	Amyload - graphically monitor Amiga CPU, blitter, and memory usage

    SYNOPSIS
	amyload [options] [ '{' [window options] [ '[' [record options] ']' ] ... '}' ] ...

    DESCRIPTION
	Amyload is a program which graphically displays information about
	current CPU, blitter, and memory usage of the Amiga.  This
	information is displayed in one or more windows, each of which may
	display information about the usage of any or all of the following:

	    CPU usage - The average length of the ready queue over the last
			n seconds (a settable time interval).  When greater
			than 1, horizontal lines are drawn to reflect a
			change in the scale that CPU usage is being
			displayed in.

	    Blitter usage - The fraction of time during the last interval
			    that the blitter was in use.

	    Chip memory usage - The fraction of chip memory in use.

	    Fast memory usage - The fraction of fast memory in use.

	    Both chip and fast memory usage - The combination of both above.

	Options: (spaces are ignored except between an option requiring
		  an integer parameter, where there had better not be any)

	    i<n>    Set the time interval between updates to n seconds.
		    Default is the current setting of load.device, which
		    begins at 5 seconds, but may have been changed.

	    t<n>    Set the number of ticks per interval (at which samples
		    of CPU and blitter usage are taken) to n.  Default is
		    the current setting of the load.device, which begins
		    at 61.  The interval time divided by the number of
		    ticks should form an irregular number, so as to try
		    to avoid aliasing problems.  (e.g. 1 second / 10 ticks
		    is probably a bad idea, because the device might get
		    'in sync' with some other task, and that would distort
		    the results.)

	    p<n>    Set the priority of the measuring task to n.  It should
		    be higher than any tasks it is trying to measure.
		    Default is the current setting of the load.device, which
		    begins at 25.

	    Following the options selection, window specifications may be
	    given.  They are introduced by the '{' character, and terminated
	    by the '}' character.

	Window Options:

	    =[WIDTH][xHEIGHT][{+-}XOFF[{+-}YOFF]]
	      (similar to an X geometry specification)
		The '=' character introduces the specification.  WIDTH
		and HEIGHT specify the WIDTH and HEIGHT of the window.
		XOFF and YOFF specify the position of the window relative
		to the screen's borders, the '+' or '-' characters
		indicating a position relative to the left or right border
		respectively of the screen in the case of XOFF, or top or
		bottom in the case of YOFF.  Distances are measured between
		the screen's border and the nearest window edge, so the
		window can be placed in the lower right corner with
		specifications of -0-0 for XOFF and YOFF.  No spaces
		are allowed within the geometry specification.

	    d<n>    Set the window's detail pen color to n.

	    b<n>    Set the window's block pen number to n.

	    g<n>    Set the background pen number for the window to n.

	    After window options have been specified, one or more record
	    descriptions may be specified.  These are introduced with the
	    '[' character, and terminated by the ']' character.  The records
	    specified earlier will have their data lines drawn on top of
	    records specified later  (first to last == foreground to
	    background).

	Record Options:

	    C	    This record will display CPU usage (really ready queue
		    length).  This is the default record type.

	    b	    This record will display blitter usage.

	    c	    This record will display chip memory usage.

	    f	    This record will display fast memory usage.

	    m	    This record will display all memory usage.

	    d<n>    Data lines for this record will be drawn with pen n.

	    r<n>    References lines (drawn when scaling) will be drawn with
		    pen n.  This is irrelevant unless the record is
		    displaying CPU usage.  Note that reference lines will
		    be drawn behind all records, regardless of ordering,
		    except that they will be drawn on top of the scaled
		    record's data lines.

	Note that load.device MUST be in your DEVS: directory (or already
	loaded into the system).

    USER INTERFACE
	Standard system gadgets are present but invisible (except for the
	drag bar, see BUGS).  The menu button causes the types of the
	records in the windows to be printed in the color of their data
	lines.

    EXAMPLES
	amyload
	    - use the default setup

	amyload {[C]}
	    - open a single window monitoring CPU usage

	amyload {=200x200-0-0[C]}
	    - as above, but make the window 200 by 200 and put it in the
	      lower right hand corner of the screen.

	amyload {[bd2][Cd3]}{[cd3][fd2]}
	    - open one window displaying blitter usage in the foreground
	      using pen 2 for drawing data lines, and CPU usage in the
	      background using pen 3 for data lines and the default pen
	      for scale reference lines.  Open a second window with chip
	      memory usage in the foreground using pen 3 for data lines,
	      and fast memory usage in the background using pen 2 for
	      data lines.


    DIAGNOSTICS
	Error numbers are returned, rather than a messages,
	to avoid DOS.  Error numbers are:
	  1 -  "Can't open graphics library"
	  2 -  "Can't open intuition library"
	  3 -  "Can't create message port"
	  4 -  "Can't create IO request"
	  5 -  "Can't open load device"
	  6 -  "Can't open window"
	  7 -  "Can't create load record"
	  8 -  "Unexpected end of record description"
	  9 -  "Unexpected end of window description"
	 10 -  "Bad record flag"
	 11 -  "Bad window flag"
	 12 -  "Bad flag"

    BUGS
	When the window is activated/deactivated, the not so invisible drag
	bar is still drawn/masked.  Can't seem to figure out how to avoid
	this.

	Doesn't do enough checking of options.  May crash if bad ones
	are given, especially zeroes in the wrong places.

	Doesn't do a 3D representation, yet...

	There is a bug in the data line drawing procedure (I think it's in
	there, anyway) that causes scale lines to not be drawn over data lines
	that are just heigher than the scale line.

	Should use cback.o, so you don't have to 'run' it, but I haven't
	looked into that yet.

	Isn't Intuition friendly.  Application gadget and menu support
	should be added to allow configuration after startup.

    SEE ALSO
	devices/load.doc

    AUTHOR
	Jeff Kelley
	Dept. of Computer Science
	University of Waterloo
	Waterloo, Ontario, Canada
	N2L 3G1

	Voice:	  (519)-578-4514
	UUCP:	  {ihnp4,watmath}!watcgl!jvkelley
	BITNET:   jvkelley@cgl.waterloo.bitnet
	INTERNET: jvkelley@cgl.waterloo.edu
	EAN:	  jvkelley@cgl.waterloo.cdn

	Comments, suggestions, bug reports welcome.

    ACKNOWLEDGEMENTS
	Amyload was inspired by the 'xload' program for UN*X workstations
	running the X Window System, and, to a lesser extent, by 'pm' for
	the Amiga.

	Thanks to Matt Dillon for Dme, the Software Distillery for blink,
	Comspec for getting a 2M RAM expansion to me quickly (NACK to the
	<unnamed> company whose lies about delivery dates delayed this
	project by a couple months), everyone on USENET, and the
	visionaries who created the Amiga.
@//E*O*F amyload.doc//
chmod u=rw,g=r,o=r amyload.doc
 
echo x - makefile
sed 's/^@//' > "makefile" <<'@//E*O*F makefile//'
CC   =	lc

CFLAGS = -b -r -v

PROG =	amyload

SRCS =	\
	amyload.c\
	init.c\
	cleanup.c\
	closeloadwindow.c\
	openloadwindow.c\
	newdata.c\
	scrollwindow.c\
	newloadrecord.c\
	newscale.c\
	findmxdatapoint.c\
	drawreflines.c\
	newwindowsize.c\
	setwindowinfo.c\
	drawdataline.c\
	redrawwindow.c\
	printmessage.c\
	printrecordtype.c\
	findwindownode.c

OBJS =	lib:c.o\
	amyload.o\
	init.o\
	cleanup.o\
	closeloadwindow.o\
	openloadwindow.o\
	newdata.o\
	scrollwindow.o\
	newloadrecord.o\
	newscale.o\
	findmxdatapoint.o\
	drawreflines.o\
	newwindowsize.o\
	setwindowinfo.o\
	drawdataline.o\
	redrawwindow.o\
	printmessage.o\
	printrecordtype.o\
	findwindownode.o

$(PROG): $(OBJS)
	blink FROM $(OBJS) TO $(PROG) LIB lib:lc.lib+lib:amiga.lib

amyload.o: amyload.c intuidef.h execdef.h\
	   cleanup.proto init.proto newdata.proto newwindowsize.proto\
	   redrawwindow.proto closeloadwindow.proto findwindownode.proto
	$(CC) $(CFLAGS) amyload.c

cleanup.o: cleanup.c cleanup.proto\
	   closeloadwindow.proto\
	   execdef.h intuidef.h windownode.h
	$(CC) $(CFLAGS) cleanup.c

closeloadwindow.o: closeloadwindow.c closeloadwindow.proto\
	   execdef.h intuidef.h windownode.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) closeloadwindow.c

drawdataline.o: drawdataline.c drawdataline.proto\
	   execdef.h intuidef.h loadrecord.h windowinfo.h
	$(CC) $(CFLAGS) drawdataline.c

drawreflines.o: drawreflines.c drawscalereferencelines.proto\
	   execdef.h intuidef.h loadrecord.h windowinfo.h
	$(CC) $(CFLAGS) drawreflines.c

findmxdatapoint.o: findmxdatapoint.c findmaxdatapoint.proto\
	   execdef.h loadrecord.h
	$(CC) $(CFLAGS) findmxdatapoint.c

findwindownode.o: findwindownode.c findwindownode.proto\
	   execdef.h intuidef.h windownode.h
	$(CC) $(CFLAGS) findwindownode.c

init.o: init.c init.proto\
	   openloadwindow.proto newloadrecord.proto\
	   execdef.h error.h windownode.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) init.c

newdata.o: newdata.c newdata.proto\
	   scrollwindow.proto newscale.proto redrawwindow.proto drawdataline.proto\
	   execdef.h intuidef.h loadrecord.h windownode.h windowinfo.h
	$(CC) $(CFLAGS) newdata.c

newloadrecord.o: newloadrecord.c newloadrecord.proto\
	   execdef.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) newloadrecord.c

newscale.o: newscale.c newscale.proto\
	   execdef.h loadrecord.h windowinfo.h
	$(CC) $(CFLAGS) newscale.c

newwindowsize.o: newwindowsize.c newwindowsize.proto\
	   setwindowinfo.proto findmaxdatapoint.proto redrawwindow.proto\
	   execdef.h intuidef.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) newwindowsize.c

openloadwindow.o: openloadwindow.c openloadwindow.proto\
	   setwindowinfo.proto\
	   execdef.h intuidef.h windownode.h windowinfo.h
	$(CC) $(CFLAGS) openloadwindow.c

printmessage.o: printmessage.c printmessage.proto\
	   execdef.h intuidef.h windowinfo.h

printrecordtype.o: printrecordtype.c printrecordtypes.proto\
	   printmessage.proto\
	   execdef.h intuidef.h windowinfo.h loadrecord.h

redrawwindow.o: redrawwindow.c redrawwindow.proto\
	   drawscalereferencelines.proto drawdataline.proto\
	   execdef.h intuidef.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) redrawwindow.c

scrollwindow.o: scrollwindow.c scrollwindow.proto\
	   findmaxdatapoint.proto newscale.proto drawscalereferencelines.proto redrawwindow.proto\
	   execdef.h intuidef.h windowinfo.h loadrecord.h
	$(CC) $(CFLAGS) scrollwindow.c

setwindowinfo.o: setwindowinfo.c setwindowinfo.proto\
	   execdef.h intuidef.h windowinfo.h
	$(CC) $(CFLAGS) setwindowinfo.c
@//E*O*F makefile//
chmod u=rw,g=r,o=r makefile
 
echo x - execdef.h
sed 's/^@//' > "execdef.h" <<'@//E*O*F execdef.h//'
#undef TRUE
#undef FALSE
typedef char Bool;
#define TRUE  (Bool)1
#define FALSE (Bool)0
typedef struct MinNode MinNode;
typedef struct MinList MinList;
typedef struct MsgPort MsgPort;
typedef struct IORequest IORequest;
typedef struct Library Library;



@//E*O*F execdef.h//
chmod u=rw,g=r,o=r execdef.h
 
echo x - intuidef.h
sed 's/^@//' > "intuidef.h" <<'@//E*O*F intuidef.h//'
typedef struct Window Window;
typedef struct NewWindow NewWindow;
typedef struct IntuiMessage IntuiMessage;
typedef struct RastPort RastPort;
typedef struct Gadget Gadget;

@//E*O*F intuidef.h//
chmod u=rw,g=r,o=r intuidef.h
 
echo x - loadrecord.h
sed 's/^@//' > "loadrecord.h" <<'@//E*O*F loadrecord.h//'
#define CPU	0
#define BLITTER 1
#define CHIPMEM 2
#define FASTMEM 3
#define ALLMEM	4

typedef long LoadDataValue;

typedef struct {
    MinNode node;
    LoadDataValue  *start_data;   /* (fixed) Beginning of data array. */
    LoadDataValue  *end_data;	  /* (fixed) End of data array. */
    LoadDataValue  *next_data;	  /* Where next data will go. */
    LoadDataValue  *max_data;	  /* Where the max data value is. */
    short scale;
    long  scaled_ticks;
    short deltay;
    short moduloy;
    unsigned char type; 	  /* CPU, Blitter, Memory, Chip, Fast */
    unsigned char data_pen_num;
    unsigned char ref_pen_num;
} LoadRecord;
@//E*O*F loadrecord.h//
chmod u=rw,g=r,o=r loadrecord.h
 
echo x - windowinfo.h
sed 's/^@//' > "windowinfo.h" <<'@//E*O*F windowinfo.h//'
#define BORDERWIDTH  2
#define BORDERHEIGHT 1

#define WINDOWINFO(window) ((WindowInfo *)window->UserData)

typedef struct {
    MinList loadrecords;
    short   leftedge;
    short   rightedge;
    short   width;
    short   topedge;
    short   bottomedge;
    short   height;
    unsigned char back_pen_num;
} WindowInfo;
@//E*O*F windowinfo.h//
chmod u=rw,g=r,o=r windowinfo.h
 
echo x - windownode.h
sed 's/^@//' > "windownode.h" <<'@//E*O*F windownode.h//'
#define REFPENNUM   1
#define LOADPENNUM  3
#define BACKPENNUM  0

typedef struct {
    MinNode node;
    Window  *window;
} WindowNode;
@//E*O*F windownode.h//
chmod u=rw,g=r,o=r windownode.h
 
echo x - amyload.c
sed 's/^@//' > "amyload.c" <<'@//E*O*F amyload.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "intuidef.h"
#include    "execdef.h"
#include    "windownode.h"

#include    <exec/proto.h>
#include    <intuition/proto.h>

#include    "Cleanup.proto"
#include    "Init.proto"
#include    "NewData.proto"
#include    "NewWindowSize.proto"
#include    "RedrawWindow.proto"
#include    "CloseLoadWindow.proto"
#include    "FindWindowNode.proto"
#include    "PrintRecordTypes.proto"

#define SIGQUIT 12

struct Library		  *GfxBase;
struct IntuitionBase	  *IntuitionBase;

loadrequest *loadRequest;
MsgPort     *loadPort;
MsgPort     *windowPort;

MinList windowList;

void
_main(argp)
    char *argp;
{
    IntuiMessage *msg;
    Window *message_window;
    unsigned long message_class;
    unsigned short message_code;
    long    signals, window_signal_mask, load_signal_mask, combined_signal_mask;
    long    quit_signal_mask;
    long    errno;

    if (errno = Init(argp))
    {
	Cleanup();
	exit(errno);
    }
    quit_signal_mask = 1 << SIGQUIT;
    window_signal_mask = 1 << windowPort->mp_SigBit;
    load_signal_mask = 1 << loadPort->mp_SigBit;
    combined_signal_mask = quit_signal_mask | window_signal_mask | load_signal_mask;

    loadRequest->lr_node.io_Command = CMD_READ;
    SendIO(&loadRequest->lr_node);
    while(windowList.mlh_TailPred != (MinNode *)&windowList)
    {
	signals = Wait(combined_signal_mask);
	if (signals & window_signal_mask)
	{
	    while (msg = (struct IntuiMessage *)GetMsg(windowPort))
	    {
		message_window = msg->IDCMPWindow;
		message_class = msg->Class;
		message_code = msg->Code;
		ReplyMsg(msg);
		switch(message_class)
		{
		case MOUSEBUTTONS:
		    if (msg->Code == MENUDOWN)
			PrintRecordTypes(message_window);
		    break;
		case CLOSEWINDOW:
		    CloseLoadWindow(FindWindowNode(message_window));
		    break;
		case NEWSIZE:
		    if (!NewWindowSize(message_window))
			goto bug_out;
		    break;
		case REFRESHWINDOW:
		    BeginRefresh(message_window);
		    RedrawWindow(message_window);
		    EndRefresh(message_window, TRUE);
		    break;
		}
	    }
	}
	if (signals & load_signal_mask)
	{
	    (void)GetMsg(loadPort);
	    NewData(&loadRequest->lr_load);
	    SendIO(&loadRequest->lr_node);
	}
	if (signals & quit_signal_mask)
	    break;
    }
bug_out:
    AbortIO(&loadRequest->lr_node);
    Cleanup();
}
@//E*O*F amyload.c//
chmod u=rw,g=r,o=r amyload.c
 
echo x - cleanup.c
sed 's/^@//' > "cleanup.c" <<'@//E*O*F cleanup.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windownode.h"

#include    "Cleanup.proto"

#include    <exec/proto.h>

#include    "CloseLoadWindow.proto"

extern Library *GfxBase;
extern struct IntuitionBase *IntuitionBase;
extern MinList windowList;
extern MsgPort *windowPort;
extern MsgPort *loadPort;
extern loadrequest *loadRequest;

void
Cleanup()
{
    WindowNode *windownode, *oldwindownode;

    for (windownode = (WindowNode *)windowList.mlh_Head;
	 windownode->node.mln_Succ; )
    {
	oldwindownode = windownode;
	windownode = (WindowNode *)windownode->node.mln_Succ;
	CloseLoadWindow(oldwindownode);
    }
    if (loadRequest)
    {
	if (loadRequest->lr_node.io_Device)
	    CloseDevice((IORequest *)loadRequest);
	DeleteExtIO((IORequest *)loadRequest, sizeof(loadrequest));
    }
    if (loadPort)
	DeletePort(loadPort);
    if (windowPort)
	DeletePort(windowPort);
    if (IntuitionBase)
	CloseLibrary((Library *)IntuitionBase);
    if (GfxBase)
	CloseLibrary(GfxBase);
}
@//E*O*F cleanup.c//
chmod u=rw,g=r,o=r cleanup.c
 
echo x - closeloadwindow.c
sed 's/^@//' > "closeloadwindow.c" <<'@//E*O*F closeloadwindow.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windownode.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "CloseLoadWindow.proto"

#include    <exec/proto.h>
#include    <intuition/proto.h>

void
CloseLoadWindow(windownode)
    WindowNode *windownode;
{
    LoadRecord *record, *oldrecord;

    Remove(&windownode->node);
    for (record = (LoadRecord *)WINDOWINFO(windownode->window)->loadrecords.mlh_Head;
	 record->node.mln_Succ;  )
    {
	FreeMem((char *)record->start_data, (record->end_data - record->start_data) * sizeof(LoadDataValue));
	oldrecord = record;
	record = (LoadRecord *)record->node.mln_Succ;
	FreeMem((char *)oldrecord, sizeof(LoadRecord));
    }
    FreeMem((char *)WINDOWINFO(windownode->window), sizeof(WindowInfo));
    windownode->window->UserPort = NULL;
    CloseWindow(windownode->window);
    FreeMem((char *)windownode, sizeof(WindowNode));
}
@//E*O*F closeloadwindow.c//
chmod u=rw,g=r,o=r closeloadwindow.c
 
echo x - drawdataline.c
sed 's/^@//' > "drawdataline.c" <<'@//E*O*F drawdataline.c//'
#include    <intuition/intuition.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "loadrecord.h"
#include    "windowinfo.h"

#include    "DrawDataLine.proto"

#include    <graphics/proto.h>

void
DrawDataLine(window, record, x, value)
    Window *window;
    LoadRecord *record;
    short x;
    LoadDataValue value;
{
    WindowInfo *window_info;
    register short deltay, moduloy, y, miny;
    unsigned char data_pen_num, ref_pen_num;
    register RastPort *rport;

    window_info = WINDOWINFO(window);
    data_pen_num = record->data_pen_num;
    ref_pen_num = record->ref_pen_num;
    x += window_info->leftedge;
    rport = window->RPort;
    y = window_info->bottomedge;
    miny = y - (value * window_info->height) / record->scaled_ticks;
    Move(rport, x, y);
    if (record->scale <= 1)
    {
	SetAPen(rport, record->data_pen_num);
	Draw(rport, x, miny);
    }
    else
    {
	deltay = record->deltay;
	moduloy = record->moduloy;
	do
	{
	    y -= deltay;
	    if (moduloy-- > 0)
		y--;
	    SetAPen(rport, data_pen_num);
	    if ( y < miny)
	    {
		Draw(rport, x, miny);
		break;
	    }
	    Draw(rport, x, y);
	    SetAPen(rport, ref_pen_num);
	    WritePixel(rport, x, y);
	    Move(rport, x, (short)(y-1));
	} while (y >= miny);
    }
}
@//E*O*F drawdataline.c//
chmod u=rw,g=r,o=r drawdataline.c
 
echo x - drawreflines.c
sed 's/^@//' > "drawreflines.c" <<'@//E*O*F drawreflines.c//'
#include    <intuition/intuition.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "loadrecord.h"
#include    "windowinfo.h"

#include    "DrawScaleReferenceLines.proto"

#include    <graphics/proto.h>

void
DrawScaleReferenceLines(window, record, xleft)
    Window *window;
    LoadRecord *record;
    short   xleft;
{
    WindowInfo *window_info;
    register short y, deltay, moduloy;

    /* Draw scale reference lines from xleft to rightedge. */

    window_info = WINDOWINFO(window);
    SetAPen(window->RPort, record->ref_pen_num);
    xleft += window_info->leftedge;
    deltay = record->deltay;
    moduloy = record->moduloy;
    for (y = window_info->height; (y -= deltay) > 0;)
    {
	if (moduloy-- > 0)
	    y--;
	Move(window->RPort, xleft, y);
	Draw(window->RPort, window_info->rightedge, y);
    }
}
@//E*O*F drawreflines.c//
chmod u=rw,g=r,o=r drawreflines.c
 
echo x - findmxdatapoint.c
sed 's/^@//' > "findmxdatapoint.c" <<'@//E*O*F findmxdatapoint.c//'
#include    <exec/types.h>
#include    <exec/nodes.h>
#include    "execdef.h"
#include    "loadrecord.h"

#include    "FindMaxDataPoint.proto"

void
FindMaxDataPoint(record)
    register LoadRecord *record;
{
    register LoadDataValue *cur_data;

    record->max_data = record->start_data;
    for (cur_data = record->start_data; cur_data < record->next_data; cur_data++)
	 if (*cur_data > *(record->max_data))
	    record->max_data = cur_data;
}
@//E*O*F findmxdatapoint.c//
chmod u=rw,g=r,o=r findmxdatapoint.c
 
echo x - findwindownode.c
sed 's/^@//' > "findwindownode.c" <<'@//E*O*F findwindownode.c//'
#include    <intuition/intuition.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windownode.h"

#include    "FindWindowNode.proto"

extern MinList windowList;

WindowNode *
FindWindowNode(window)
    Window *window;
{
    WindowNode *node;

    for (node = (WindowNode *)windowList.mlh_Head;
	 node->node.mln_Succ;
	 node = (WindowNode *)node->node.mln_Succ)
    {
	if (node->window == window)
	    return node;
    }
    return NULL;
}

@//E*O*F findwindownode.c//
chmod u=rw,g=r,o=r findwindownode.c
 
echo x - init.c
sed 's/^@//' > "init.c" <<'@//E*O*F init.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "error.h"
#include    "windownode.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "Init.proto"

#include    <exec/proto.h>

#include    "OpenLoadWindow.proto"
#include    "NewLoadRecord.proto"

#define LINEWIDTH   1
#define DEFAULT_LEFTEDGE    screenWidth-DEFAULT_WIDTH
#define DEFAULT_TOPEDGE     10
#define DEFAULT_WIDTH	    100
#define DEFAULT_HEIGHT	    100
#define MINWIDTH    BORDERWIDTH * 2 + LINEWIDTH
#define MINHEIGHT   BORDERHEIGHT * 2 + LINEWIDTH
#define MAXWIDTH    -1
#define MAXHEIGHT   -1
#define DEFAULT_DETAIL_PEN   -1
#define DEFAULT_BLOCK_PEN    -1
#define DEFAULT_DATA_PEN 1
#define DEFAULT_REF_PEN  1
#define DEFAULT_BACK_PEN 0

static NewWindow newWindow =
{ 0, 0, 0, 0,
  0, 0,
  0,
  WINDOWSIZING | WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SIMPLE_REFRESH | RMBTRAP,
  0, 0, 0, 0, 0,
  MINWIDTH, MINHEIGHT, MAXWIDTH, MAXHEIGHT,
  WBENCHSCREEN
};

extern Library *GfxBase;
extern struct IntuitionBase *IntuitionBase;
extern MinList windowList;
extern MsgPort *loadPort;
extern MsgPort *windowPort;
extern loadrequest *loadRequest;

static short atoi(char **);
static void GetScreenDimensions();
static void ParseGeometry(char **);

long   maxTicks;
long   maxChip;
long   maxFast;
long   maxMem;

static char *default_argstr = "{[d3]}";
static short screenWidth, screenHeight;

long
Init(argstr)
    char *argstr;
{
    WindowNode *node;
    struct LoadBase *load_base;
    Bool getting_record, getting_window;
    short try_again;
    unsigned char data_pen_num, ref_pen_num, back_pen_num, record_type;
    char c;
    struct Screen screen;

    if (!(GfxBase = OpenLibrary("graphics.library", 0)))
	return ENOGFX;
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
	return ENOINTUITION;
    if (!(windowPort = CreatePort(0,0)))
	return ENOPORT;
    NewList(&windowList);
    if (!(loadPort = CreatePort(0,0)))
	return ENOPORT;
    if (!(loadRequest = (loadrequest *)CreateExtIO(loadPort, sizeof(loadrequest))))
	return ENOIOREQUEST;
    if (OpenDevice("load.device",0,(IORequest *)loadRequest,0))
	return ENODEVICE;
    load_base = (struct LoadBase *)loadRequest->lr_node.io_Device;
    maxTicks = load_base->ld_ticks;
    maxChip  = load_base->ld_max_chip;
    maxFast  = load_base->ld_max_fast;
    maxMem   = maxChip + maxFast;
    GetScreenDimensions();
    while ((c = *argstr) && (c != ' '))
	argstr++;
    node = NULL;
    for (try_again = 2; try_again--;)
    {
	while ((c = *argstr++) && (c != '\n'))
	{
	    switch(c)
	    {
	    case 'i':
		loadRequest->lr_interval = atoi(&argstr);
		break;
	    case 't':
		loadRequest->lr_ticks = atoi(&argstr);
		break;
	    case 'p':
		loadRequest->lr_pri = atoi(&argstr);
		break;
	    case '{':
		node = NULL;
		newWindow.LeftEdge = DEFAULT_LEFTEDGE;
		newWindow.TopEdge = DEFAULT_TOPEDGE;
		newWindow.Width = DEFAULT_WIDTH;
		newWindow.Height = DEFAULT_HEIGHT;
		newWindow.DetailPen = DEFAULT_DETAIL_PEN;
		newWindow.BlockPen = DEFAULT_BLOCK_PEN;
		back_pen_num = DEFAULT_BACK_PEN;
		for (getting_window = TRUE; getting_window;)
		{
		    c = *argstr++;
		    switch(c)
		    {
		    case '=':
			ParseGeometry(&argstr);
			break;
		    case 'd':
			newWindow.DetailPen = atoi(&argstr);
			break;
		    case 'b':
			newWindow.BlockPen = atoi(&argstr);
			break;
		    case 'g':
			back_pen_num = atoi(&argstr);
			break;
		    case '[':
			if (!node && !(node = OpenLoadWindow(&newWindow, back_pen_num)))
			    return ENOWINDOW;
			record_type = CPU;
			ref_pen_num = DEFAULT_REF_PEN;
			data_pen_num = DEFAULT_DATA_PEN;
			for (getting_record = TRUE; getting_record; )
			{
			    c = *argstr++;
			    switch(c)
			    {
			    case 'C':
				record_type = CPU;
				break;
			    case 'b':
				record_type = BLITTER;
				break;
			    case 'm':
				record_type = ALLMEM;
				break;
			    case 'c':
				record_type = CHIPMEM;
				break;
			    case 'f':
				record_type = FASTMEM;
				break;
			    case 'd':
				data_pen_num = atoi(&argstr);
				break;
			    case 'r':
				ref_pen_num = atoi(&argstr);
				break;
			    case ' ':
				break;
			    case ']':
				getting_record = FALSE;
				break;
			    case '\n':
			    case '\0':
				/* Error: Unexpected end of record. */
				return EUNXEOR;
			    default:
				/* Error: Unknown record flag. */
				return EBADRFLAG;
			    }
			}
			if (!(NewLoadRecord(WINDOWINFO(node->window), record_type, data_pen_num, ref_pen_num)))
			    return ENORECORD;
			break;
		    case ' ':
			break;
		    case '}':
			getting_window = FALSE;
			break;
		    case '\n':
		    case '\0':
			/* Error: Unexpected end of window. */
			return EUNXEOW;
		    default:
			/* Error: Unknown window flag. */
			return EBADWFLAG;
		    }
		}
		break;
	    case ' ':
		break;
	    default:
		/* Error: Unknown global flag. */
		return EBADGFLAG;
	    }
	}
	if (!node)
	    argstr = default_argstr;
	else
	    break;
    }
    loadRequest->lr_node.io_Command = LD_SET;
    DoIO(loadRequest);
    return 0;
}

static
short atoi(s)
    register char **s;
{
    register short num;

    for (num = 0; isdigit(**s); (*s)++)
	num = num * (short)10 + **s - '0';
    return num;
}

static
void
GetScreenDimensions()
{
    struct Screen screen;

    GetScreenData(&screen,  sizeof(struct Screen), WBENCHSCREEN, NULL);
    screenWidth = screen.Width;
    screenHeight = screen.Height;
}

static
void
ParseGeometry(string)
    register char **string;
{
    register char c;

    c = **string;
    if (c != 'x' && c != '+' && c != '-')
	newWindow.Width = atoi(string);
    c = *((*string)++);
    if (c == 'x')
    {
	newWindow.Height = atoi(string);
	c = *((*string)++);
    }
    if (c == '+')
    {
	newWindow.LeftEdge = atoi(string);
	c = *((*string)++);
    }
    else if (c == '-')
    {
	newWindow.LeftEdge = screenWidth - atoi(string) - newWindow.Width;
	c = *((*string)++);
    }
    else
	return;
    if (c == '+')
	newWindow.TopEdge = atoi(string);
    else if (c == '-')
	newWindow.TopEdge = screenHeight - atoi(string) - newWindow.Height;
}
@//E*O*F init.c//
chmod u=rw,g=r,o=r init.c
 
echo x - newdata.c
sed 's/^@//' > "newdata.c" <<'@//E*O*F newdata.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "loadrecord.h"
#include    "windownode.h"
#include    "windowinfo.h"

#include    "NewData.proto"

#include    "ScrollWindow.proto"
#include    "NewScale.proto"
#include    "RedrawWindow.proto"
#include    "DrawDataLine.proto"

extern MinList windowList;

void
NewData(newloadvalue)
    loadval *newloadvalue;
{
    WindowNode *node;
    Bool    new_scale;
    LoadRecord *record;
    LoadDataValue newvalue;

    for (node = (WindowNode *)windowList.mlh_Head;
	 node->node.mln_Succ;
	 node = (WindowNode *)node->node.mln_Succ)
    {
	new_scale = FALSE;
	for (record = (LoadRecord *)WINDOWINFO(node->window)->loadrecords.mlh_Head;
	     record->node.mln_Succ;
	     record = (LoadRecord *)record->node.mln_Succ)
	{
	    if (record->next_data == record->end_data)
		ScrollWindow(node->window);
	    switch (record->type)
	    {
	    case CPU:
		newvalue = newloadvalue->lv_cpu;
		break;
	    case BLITTER:
		newvalue = newloadvalue->lv_blitter;
		break;
	    case CHIPMEM:
		newvalue = newloadvalue->lv_chip;
		break;
	    case FASTMEM:
		newvalue = newloadvalue->lv_fast;
		break;
	    case ALLMEM:
		newvalue = newloadvalue->lv_chip + newloadvalue->lv_fast;
		break;
	    }
	    *(record->next_data++) = newvalue;
	    if (record->scale && newvalue > *record->max_data)
	    {
		record->max_data = record->next_data - 1;
		new_scale = NewScale(WINDOWINFO(node->window), record, newvalue) || new_scale;
	    }
	    if (!new_scale)
		DrawDataLine(node->window, record, (short)(record->next_data - 1 - record->start_data), newvalue);
	}
	if (new_scale)
	    RedrawWindow(node->window);
    }
}
@//E*O*F newdata.c//
chmod u=rw,g=r,o=r newdata.c
 
echo x - newloadrecord.c
sed 's/^@//' > "newloadrecord.c" <<'@//E*O*F newloadrecord.c//'
#include    <exec/types.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "NewLoadRecord.proto"

#include    <exec/proto.h>

extern loadrequest *loadRequest;
extern long maxTicks;
extern long maxChip;
extern long maxFast;
extern long maxMem;

LoadRecord *
NewLoadRecord(window_info, type, data_pen_num, ref_pen_num)
    register WindowInfo *window_info;
    unsigned char type;
    unsigned char data_pen_num, ref_pen_num;
{
    LoadRecord *record;

    if (!(record = (LoadRecord *)AllocMem(sizeof(LoadRecord), 0)))
	return NULL;
    if (!(record->start_data = (LoadDataValue *)AllocMem(window_info->width * sizeof(LoadDataValue), 0)))
    {
	FreeMem((char *)record, sizeof(LoadRecord));
	return NULL;
    }
    record->end_data = record->start_data + window_info->width;
    record->next_data = record->start_data;
    record->max_data = record->start_data;
    switch(type)
    {
    case CPU:
	record->scale = 1;
	record->scaled_ticks = maxTicks;
	break;
    case BLITTER:
	record->scale = 0;
	record->scaled_ticks = maxTicks;
	break;
    case CHIPMEM:
	record->scale = 0;
	record->scaled_ticks = maxChip;
	break;
    case FASTMEM:
	record->scale = 0;
	record->scaled_ticks = maxFast;
	break;
    case ALLMEM:
	record->scale = 0;
	record->scaled_ticks = maxMem;
	break;
    }
    record->deltay = window_info->height;
    record->moduloy = 0;
    record->type = type;
    record->data_pen_num = data_pen_num;
    record->ref_pen_num = ref_pen_num;
    AddHead(&window_info->loadrecords, &record->node);
    return record;
}
@//E*O*F newloadrecord.c//
chmod u=rw,g=r,o=r newloadrecord.c
 
echo x - newscale.c
sed 's/^@//' > "newscale.c" <<'@//E*O*F newscale.c//'
#include    <exec/types.h>
#include    <exec/lists.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "loadrecord.h"
#include    "windowinfo.h"

#include    "NewScale.proto"

extern loadrequest *loadRequest;
extern long maxTicks;
extern long maxChip;
extern long maxFast;
extern long maxMem;

Bool
NewScale(window_info, record, data_value)
    WindowInfo *window_info;
    LoadRecord *record;
    LoadDataValue data_value;
{
    short new_scale;
    long  max_value;

    switch(record->type)
    {
    case CPU:
    case BLITTER:
	max_value = maxTicks;
	break;
    case CHIPMEM:
	max_value = maxChip;
	break;
    case FASTMEM:
	max_value = maxFast;
	break;
    case ALLMEM:
	max_value = maxMem;
	break;
    }
    new_scale = data_value / max_value + 1;
    if (new_scale != record->scale)
    {
	record->scale = new_scale;
	record->scaled_ticks = new_scale * max_value;
	record->deltay = window_info->height / new_scale;
	record->moduloy = window_info->height % new_scale;
	return TRUE;
    }
    return FALSE;
}
@//E*O*F newscale.c//
chmod u=rw,g=r,o=r newscale.c
 
echo x - newwindowsize.c
sed 's/^@//' > "newwindowsize.c" <<'@//E*O*F newwindowsize.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    <clib/macros.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "NewWindowSize.proto"

#include    <exec/proto.h>

#include    "SetWindowInfo.proto"
#include    "FindMaxDataPoint.proto"
#include    "RedrawWindow.proto"

Bool
NewWindowSize(window)
    Window *window;
{
    LoadDataValue *new_start_data;
    short number_data_points_to_copy;
    LoadRecord old_record, *record;

    SetWindowInfo(window);
    for (record = (LoadRecord *)WINDOWINFO(window)->loadrecords.mlh_Head;
	 record->node.mln_Succ;
	 record = (LoadRecord *)record->node.mln_Succ)
    {
	old_record = *record;
	if (!(new_start_data = (LoadDataValue *)AllocMem(WINDOWINFO(window)->width * sizeof(LoadDataValue), 0)))
	    return FALSE;
	record->start_data = new_start_data;
	record->end_data = record->start_data + WINDOWINFO(window)->width;
	number_data_points_to_copy = MIN(old_record.next_data - old_record.start_data, WINDOWINFO(window)->width);
	record->next_data = record->start_data + number_data_points_to_copy;
	record->max_data = record->start_data + (old_record.max_data - old_record.start_data);
	CopyMemQuick(old_record.next_data - number_data_points_to_copy, record->start_data, number_data_points_to_copy * sizeof(LoadDataValue));
	if (record->max_data >= record->next_data)
	    FindMaxDataPoint(record);

	FreeMem((char *)old_record.start_data, (old_record.end_data - old_record.start_data) * sizeof(LoadDataValue));
	if (record->scale)
	{
	    record->deltay = WINDOWINFO(window)->height / record->scale;
	    record->moduloy = WINDOWINFO(window)->height / record->scale;
	}
    }
    return TRUE;
}
@//E*O*F newwindowsize.c//
chmod u=rw,g=r,o=r newwindowsize.c
 
echo x - openloadwindow.c
sed 's/^@//' > "openloadwindow.c" <<'@//E*O*F openloadwindow.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windownode.h"
#include    "windowinfo.h"

#include    "OpenLoadWindow.proto"

#include    <intuition/proto.h>
#include    <exec/proto.h>
#include    <graphics/proto.h>

#include    "SetWindowInfo.proto"
#include    "PrintMessage.proto"

extern MsgPort *windowPort;
extern MinList windowList;

static ULONG IDCMPFlags = MOUSEBUTTONS | CLOSEWINDOW | NEWSIZE | REFRESHWINDOW;
static char  *myname =	 "Amyload by";
static char  *myauthor = "Jeff Kelley";

WindowNode *
OpenLoadWindow(new_window, back_pen_num)
    NewWindow *new_window;
    unsigned char back_pen_num;
{
    WindowNode *windownode;
    Window *window;
    WindowInfo *window_info;
    Gadget *gadget;

    if (!(windownode = (WindowNode *)AllocMem(sizeof(WindowNode), 0)))
	return NULL;
    if (!(window = OpenWindow(new_window)))
    {
	FreeMem((char *)windownode, sizeof(WindowNode));
	return NULL;
    }
    windownode->window = window;
    if (!(window_info = (WindowInfo *)AllocMem(sizeof(WindowInfo), 0)))
    {
	FreeMem((char *)windownode, sizeof(WindowNode));
	CloseWindow(window);
	return NULL;
    }
    window->UserData = (char *)window_info;
    NewList(&window_info->loadrecords);
    SetWindowInfo(window);
    window_info->back_pen_num = back_pen_num;
    for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget)
    {
	gadget->GadgetRender = NULL;
	gadget->SelectRender = NULL;
    }
    RefreshWindowFrame(window);
    SetAPen(window->RPort, back_pen_num);
    RectFill(window->RPort, window_info->leftedge,
			    window_info->topedge,
			    window_info->rightedge,
			    window_info->bottomedge);
    PrintMessage(window, myname, (short)1, (unsigned char)1);
    PrintMessage(window, myauthor, (short)2, (unsigned char)3);
    window->UserPort = windowPort;
    ModifyIDCMP(window, IDCMPFlags);
    AddTail(&windowList, &windownode->node);
    return windownode;
}
@//E*O*F openloadwindow.c//
chmod u=rw,g=r,o=r openloadwindow.c
 
echo x - printmessage.c
sed 's/^@//' > "printmessage.c" <<'@//E*O*F printmessage.c//'
/*
static char *messages[] = {
    "Blitter Overheating!",
    "Blitter Temperature Critical!",
    "CPU Load Critical!",
    "System Overloaded - Please Log Out.",
    "Use Me."
};
*/
#include    <intuition/intuition.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windowinfo.h"

#include    "PrintMessage.proto"

#include    <graphics/proto.h>

void
PrintMessage(window, message, line_num, pen)
    Window *window;
    char *message;
    short line_num;
    unsigned char pen;
{
    RastPort *rport;

    rport = window->RPort;
    SetAPen(rport, pen);
    Move(rport, (short)(WINDOWINFO(window)->leftedge + 2), (short)((rport->TxHeight+2) * line_num + WINDOWINFO(window)->topedge + 2));
    Text(rport, message, strlen(message));
}
@//E*O*F printmessage.c//
chmod u=rw,g=r,o=r printmessage.c
 
echo x - printrecordtype.c
sed 's/^@//' > "printrecordtype.c" <<'@//E*O*F printrecordtype.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "intuidef.h"
#include    "execdef.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "PrintRecordTypes.proto"

#include    "PrintMessage.proto"

static char *recordTypeNames[] = {
		    "CPU",
		    "Blitter",
		    "Chip",
		    "Fast",
		    "Memory"
};

void
PrintRecordTypes(window)
    Window *window;
{
    LoadRecord *record;
    short line_num;

    line_num = 1;
    for (record = (LoadRecord *)WINDOWINFO(window)->loadrecords.mlh_TailPred;
	 record->node.mln_Pred;
	 record = (LoadRecord *)record->node.mln_Pred)
    {
	PrintMessage(window, recordTypeNames[record->type], line_num, record->data_pen_num);
	line_num++;
    }
}
@//E*O*F printrecordtype.c//
chmod u=rw,g=r,o=r printrecordtype.c
 
echo x - redrawwindow.c
sed 's/^@//' > "redrawwindow.c" <<'@//E*O*F redrawwindow.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "RedrawWindow.proto"

#include    <graphics/proto.h>

#include    "DrawScaleReferenceLines.proto"
#include    "DrawDataLine.proto"

void
RedrawWindow(window)
    Window *window;
{
    WindowInfo *window_info;
    register short x;
    register LoadDataValue *current_data, *last_data;
    LoadRecord *record;

    window_info = WINDOWINFO(window);
    SetAPen(window->RPort, window_info->back_pen_num);
    /* Clear the window. */
    RectFill(window->RPort,
	     window_info->leftedge,
	     window_info->topedge,
	     window_info->rightedge,
	     window_info->bottomedge);

    for (record = (LoadRecord *)window_info->loadrecords.mlh_Head;
	 record->node.mln_Succ;
	 record = (LoadRecord *)record->node.mln_Succ)
    {
	if (record->scale)
	    DrawScaleReferenceLines(window, record, (short)0);

	/* Draw data point lines. */
	last_data = record->next_data;
	x = 0;
	for (current_data = record->start_data;
	     current_data < last_data;
	     current_data++)
	{
	    DrawDataLine(window, record, x, *current_data);
	    x++;
	}
    }
}
@//E*O*F redrawwindow.c//
chmod u=rw,g=r,o=r redrawwindow.c
 
echo x - scrollwindow.c
sed 's/^@//' > "scrollwindow.c" <<'@//E*O*F scrollwindow.c//'
#include    <intuition/intuition.h>
#include    <devices/load.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windowinfo.h"
#include    "loadrecord.h"

#include    "ScrollWindow.proto"

#include    <exec/proto.h>
#include    <graphics/proto.h>

#include    "NewScale.proto"
#include    "FindMaxDataPoint.proto"
#include    "DrawScaleReferenceLines.proto"
#include    "RedrawWindow.proto"

void
ScrollWindow(window)
    Window *window;
{
    WindowInfo *window_info;
    short scroll_distance;
    Bool  new_scale;
    LoadRecord *record;

    window_info = WINDOWINFO(window);
    new_scale = FALSE;
    scroll_distance = (window_info->width + 1) >> 1;

    for (record = (LoadRecord *)window_info->loadrecords.mlh_Head;
	 record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ)
    {
	/* Scroll the data. */
	CopyMemQuick(record->start_data + scroll_distance,
		     record->start_data,
		     (window_info->width - scroll_distance) * sizeof(LoadDataValue));
	record->next_data -= scroll_distance;
	record->max_data -= scroll_distance;
	if (record->max_data < record->start_data)
	    FindMaxDataPoint(record);
	if (record->scale)
	    new_scale = NewScale(window_info, record, *record->max_data) || new_scale;
    }

    /* Scroll the window. */
    if (new_scale)
	RedrawWindow(window);
    else
    {
	ScrollRaster(window->RPort,
		     (short)((window_info->width + 1) >> 1),
		     (short)0,
		     window_info->leftedge,
		     window_info->topedge,
		     window_info->rightedge,
		     window_info->bottomedge);

	for (record = (LoadRecord *)window_info->loadrecords.mlh_Head;
	     record->node.mln_Succ; record = (LoadRecord *)record->node.mln_Succ)
	    if (record->scale)
		DrawScaleReferenceLines(window, record, (short)(window_info->width - scroll_distance));
    }
}
@//E*O*F scrollwindow.c//
chmod u=rw,g=r,o=r scrollwindow.c
 
echo x - setwindowinfo.c
sed 's/^@//' > "setwindowinfo.c" <<'@//E*O*F setwindowinfo.c//'
#include    <intuition/intuition.h>
#include    "execdef.h"
#include    "intuidef.h"
#include    "windowinfo.h"

#include    "SetWindowInfo.proto"

void
SetWindowInfo(window)
    register Window  *window;
{
    register WindowInfo *info;

    info = WINDOWINFO(window);

    info->leftedge = BORDERWIDTH;
    info->rightedge = window->Width - BORDERWIDTH - 1;
    info->width = window->Width - BORDERWIDTH * 2;
    info->topedge = BORDERHEIGHT;
    info->bottomedge = window->Height - BORDERHEIGHT - 1;
    info->height = window->Height - BORDERHEIGHT * 2;
}
@//E*O*F setwindowinfo.c//
chmod u=rw,g=r,o=r setwindowinfo.c
 
echo x - cleanup.proto
sed 's/^@//' > "cleanup.proto" <<'@//E*O*F cleanup.proto//'
extern void Cleanup();
@//E*O*F cleanup.proto//
chmod u=rw,g=r,o=r cleanup.proto
 
echo x - closeloadwindow.proto
sed 's/^@//' > "closeloadwindow.proto" <<'@//E*O*F closeloadwindow.proto//'
extern void CloseLoadWindow(WindowNode *);
@//E*O*F closeloadwindow.proto//
chmod u=rw,g=r,o=r closeloadwindow.proto
 
echo x - drawdataline.proto
sed 's/^@//' > "drawdataline.proto" <<'@//E*O*F drawdataline.proto//'
extern void DrawDataLine(Window *, LoadRecord *, short, LoadDataValue);
@//E*O*F drawdataline.proto//
chmod u=rw,g=r,o=r drawdataline.proto
 
echo x - drawscalereferencelines.proto
sed 's/^@//' > "drawscalereferencelines.proto" <<'@//E*O*F drawscalereferencelines.proto//'
extern void DrawScaleReferenceLines(Window *, LoadRecord *, short);
@//E*O*F drawscalereferencelines.proto//
chmod u=rw,g=r,o=r drawscalereferencelines.proto
 
echo x - findmaxdatapoint.proto
sed 's/^@//' > "findmaxdatapoint.proto" <<'@//E*O*F findmaxdatapoint.proto//'
extern void FindMaxDataPoint(LoadRecord *);
@//E*O*F findmaxdatapoint.proto//
chmod u=rw,g=r,o=r findmaxdatapoint.proto
 
echo x - findwindownode.proto
sed 's/^@//' > "findwindownode.proto" <<'@//E*O*F findwindownode.proto//'
extern WindowNode *FindWindowNode(Window *);
@//E*O*F findwindownode.proto//
chmod u=rw,g=r,o=r findwindownode.proto
 
echo x - init.proto
sed 's/^@//' > "init.proto" <<'@//E*O*F init.proto//'
extern long Init(char *);
@//E*O*F init.proto//
chmod u=rw,g=r,o=r init.proto
 
echo x - newdata.proto
sed 's/^@//' > "newdata.proto" <<'@//E*O*F newdata.proto//'
extern void NewData(loadval *);
@//E*O*F newdata.proto//
chmod u=rw,g=r,o=r newdata.proto
 
echo x - newloadrecord.proto
sed 's/^@//' > "newloadrecord.proto" <<'@//E*O*F newloadrecord.proto//'
extern LoadRecord *NewLoadRecord(WindowInfo *, unsigned char, unsigned char, unsigned char);
@//E*O*F newloadrecord.proto//
chmod u=rw,g=r,o=r newloadrecord.proto
 
echo x - newscale.proto
sed 's/^@//' > "newscale.proto" <<'@//E*O*F newscale.proto//'
extern Bool NewScale(WindowInfo *, LoadRecord *, LoadDataValue);
@//E*O*F newscale.proto//
chmod u=rw,g=r,o=r newscale.proto
 
echo x - newwindowsize.proto
sed 's/^@//' > "newwindowsize.proto" <<'@//E*O*F newwindowsize.proto//'
extern Bool NewWindowSize(Window *);
@//E*O*F newwindowsize.proto//
chmod u=rw,g=r,o=r newwindowsize.proto
 
echo x - openloadwindow.proto
sed 's/^@//' > "openloadwindow.proto" <<'@//E*O*F openloadwindow.proto//'
extern WindowNode *OpenLoadWindow(NewWindow *, unsigned char);
@//E*O*F openloadwindow.proto//
chmod u=rw,g=r,o=r openloadwindow.proto
 
echo x - printmessage.proto
sed 's/^@//' > "printmessage.proto" <<'@//E*O*F printmessage.proto//'
extern void PrintMessage(Window *, char *, short, unsigned char);
@//E*O*F printmessage.proto//
chmod u=rw,g=r,o=r printmessage.proto
 
echo x - printrecordtypes.proto
sed 's/^@//' > "printrecordtypes.proto" <<'@//E*O*F printrecordtypes.proto//'
extern void PrintRecordTypes(Window *);
@//E*O*F printrecordtypes.proto//
chmod u=rw,g=r,o=r printrecordtypes.proto
 
echo x - redrawwindow.proto
sed 's/^@//' > "redrawwindow.proto" <<'@//E*O*F redrawwindow.proto//'
extern void RedrawWindow(Window *);
@//E*O*F redrawwindow.proto//
chmod u=rw,g=r,o=r redrawwindow.proto
 
echo x - scrollwindow.proto
sed 's/^@//' > "scrollwindow.proto" <<'@//E*O*F scrollwindow.proto//'
extern void ScrollWindow(Window *);
@//E*O*F scrollwindow.proto//
chmod u=rw,g=r,o=r scrollwindow.proto
 
echo x - setwindowinfo.proto
sed 's/^@//' > "setwindowinfo.proto" <<'@//E*O*F setwindowinfo.proto//'
extern void SetWindowInfo(Window *);
@//E*O*F setwindowinfo.proto//
chmod u=rw,g=r,o=r setwindowinfo.pro Whi 2;cho x