[net.micro.amiga] dadc.c - program source

perry@atux01.UUCP (P. Kivolowitz) (01/10/86)

The following was the first program I wrote on the amiga. It is
a digital simulation of an analog clock simulating a digital clock.
I just got round to installing the timer code (I originally kept time
with Delays). 

enjoy,

Perry S. Kivolowitz
ihnp4!ptsfa!well!perry

----------------------------------------------------------------------

/*
**	d a d c
**
**	a digital computer impersonating an analog clock impersonating
**	a digital clock.
**			Copyright 1986
**			By Perry S. Kivolowitz
**
**	Placed in the public domain with two restrictions:
**
**	(1) This header and the variable ``author'' not be modified
**	(2) This program may not be used as part of ANY commercial
**	    product nor can any part of this code be used in any
**	    commercial product IN ANY WAY.
**
**	Timer code lifted from GfxMem by Lou M.
*/

static char *author = "perry s. kivolowitz";

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <hardware/blit.h>
#include <graphics/copper.h>
#include <graphics/regions.h>
#include <graphics/rastport.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/gels.h>
#include <intuition/intuition.h>

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *DiskfontBase;

struct Window *w;

struct MsgPort *timerport = NULL, *CreatePort();
struct timerequest timereq;
struct RastPort rps[10];
struct BitMap bms[10];

long date[3];
long *s = &date[1];
#define	S 	*s

struct TextFont *font;
struct TextAttr sapphire = {
	"sapphire.font" ,
	19 ,
	FS_NORMAL ,
	FPF_DISKFONT | FPF_PROPORTIONAL | FPF_DESIGNED | FPF_ROMFONT
};

#define	XMAX	100
#define	YMAX	33

int is_cli;
int close_flag = 0;
int rast_count = 0;

#define	TIMER_DEVICE	0x0000001
#define	TIMER_PORT	0x0000002
#define	INTUITION	0x0000004
#define	GFXLIB		0x0000008
#define	THE_FONT	0x0000010
#define	THE_WINDOW	0x0000020
#define	FONTLIB		0x0000040

starttimer()
{
	timereq.tr_time.tv_secs = 59;
	timereq.tr_time.tv_micro = 0;
	timereq.tr_node.io_Command = TR_ADDREQUEST;
	timereq.tr_node.io_Flags = 0;
	timereq.tr_node.io_Error = 0;
	timereq.tr_node.io_Message.mn_ReplyPort = timerport;
	SendIO((char *) &timereq.tr_node);
}

main(argc , argv)
char *argv[];
{
	int i , flag = 0;
	struct NewWindow nw;
	struct IntuiMessage *msg , *GetMsg();
	int waitmask;

	if (argc) is_cli = 1;

	IntuitionBase  = (struct IntuitionBase *) OpenLibrary("intuition.library" , 1);
	if (!IntuitionBase) {
		if (is_cli) printf("%s: could not open intuition library\n" , argv[0]);
	        exit(FALSE);
	}
	close_flag |= INTUITION;
	GfxBase = (struct GfxBase *) OpenLibrary("graphics.library" ,  1);
	if (!GfxBase) {
        	if (is_cli) printf("%s: could not open graphics library\n" , argv[0]);
		close_stuff();
		exit(FALSE);
	}
	close_flag |= GFXLIB;
	DiskfontBase = (struct Library *) OpenLibrary("diskfont.library" , 0);
	if (!DiskfontBase) {
        	if (is_cli) printf("%s: could not open disk font library\n" ,argv[0]);
		close_stuff();
		exit(FALSE);
	}
	close_flag |= FONTLIB;
	if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
		close_stuff();
		exit(1);
	}
	close_flag |= TIMER_PORT;
	if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
		close_stuff();
		exit(1);
	}
	close_flag |= TIMER_DEVICE;
	font = OpenDiskFont(&sapphire);
	if (!font) {
		if (is_cli) printf("%s: cannot open disk font\n" , argv[0]);
		close_stuff();
		exit(1);
	}
	close_flag |= THE_FONT;

	nw.LeftEdge = nw.TopEdge = 20;
	nw.Width = XMAX;
	nw.Height = YMAX;
	nw.DetailPen = 0;
	nw.BlockPen = 1;
	nw.Title = "DADC";
	nw.Flags = NOCAREREFRESH | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH;
	nw.FirstGadget = NULL;
	nw.CheckMark = NULL;
	nw.IDCMPFlags = CLOSEWINDOW;
	nw.Type = WBENCHSCREEN;
	nw.Screen = NULL;
	nw.BitMap = NULL;
	nw.MinWidth = nw.MinHeight = nw.MaxWidth = nw.MaxHeight = 0;

	if (!(w = (struct Window *) OpenWindow(&nw))) {
		if (is_cli) printf("%s: could not open window\n" , argv[0]);
		close_stuff();
		exit(1);
	}
	close_flag |= THE_WINDOW;
	i = SetFont(w->RPort , font);
	initialize_digits(font);
	DateStamp(date);
	scrollin(S % 10 , w->RPort , w->BorderLeft + 10 + (3 * (XMAX-20) / 4) , w->BorderTop , font->tf_YSize , font->tf_XSize);
	scrollin((S / 10) % 6 , w->RPort , w->BorderLeft + 10 + (XMAX-20) / 2 , w->BorderTop , font->tf_YSize , font->tf_XSize);
	scrollin((S / 60) % 10 , w->RPort , w->BorderLeft + 10 + (XMAX-20) / 4 , w->BorderTop , font->tf_YSize , font->tf_XSize);
	S = (S / 60) > 9 ? 1 : 0;
	scrollin(S , w->RPort , w->BorderLeft + 10 , w->BorderTop , font->tf_YSize , font->tf_XSize);
	waitmask = (1 << w->UserPort->mp_SigBit) | (1 << timerport->mp_SigBit);
	while (!flag) {
		starttimer();
		Wait(waitmask);
		while (msg = GetMsg(w->UserPort)) {
			switch (msg->Class) {

			case CLOSEWINDOW:
					flag = 1;
					break;
			}
			ReplyMsg(msg);
		}
		(void) GetMsg(timerport);
		if (flag) continue;
		DateStamp(date);
		scrollin(S % 10 , w->RPort , w->BorderLeft + 10 + (3 * (XMAX-20) / 4) , w->BorderTop , font->tf_YSize , font->tf_XSize);
		if (S % 10 == 0) scrollin((S / 10) % 6 , w->RPort , w->BorderLeft + 10 + (XMAX-20) / 2 , w->BorderTop , font->tf_YSize , font->tf_XSize);
		if (S % 60 == 0) scrollin((S / 60) % 10 , w->RPort , w->BorderLeft + 10 + (XMAX-20) / 4 , w->BorderTop , font->tf_YSize , font->tf_XSize);
		if (S % 60 != 0) continue;
		S = S / 60;
		if (S == 10) S = 1;
		else if (S != 0) continue;
		scrollin(S , w->RPort , w->BorderLeft + 10 , w->BorderTop , font->tf_YSize , font->tf_XSize);
	}
	close_stuff();
	exit(1);
}

close_stuff()
{
	if (close_flag & TIMER_DEVICE) {
		AbortIO(&timereq);
		CloseDevice(&timereq);
	}
	if (close_flag & TIMER_PORT) DeletePort(timerport);
	if (close_flag & THE_WINDOW) CloseWindow(w);
	if (close_flag & THE_FONT)   CloseFont(font);
	deallocate_rasters();
	if (close_flag & GFXLIB) CloseLibrary(GfxBase);
	if (close_flag & FONTLIB) CloseLibrary(DiskfontBase);
	if (close_flag & INTUITION) CloseLibrary(IntuitionBase);
	(void) OpenWorkBench();
	exit(TRUE);
}

initialize_digits(font)
struct TextFont *font;
{
	int i;
	char *digits = "0123456789";

	for (i = 0; i < 10; i++) {
		InitRastPort(&rps[i]);
		InitBitMap(&bms[i] , 2 , 30 , 30);
		bms[i].Planes[0] = AllocRaster(30 , 30);
		if (bms[i].Planes[0] == NULL) {
			close_stuff();
			exit(1);
		}
		rast_count++;
		bms[i].Planes[1] = AllocRaster(30 , 30);
		if (bms[i].Planes[1] == NULL) {
			close_stuff();
			exit(1);
		}
		rast_count++;
		rps[i].BitMap = &bms[i];
		SetFont(&rps[i] , font);
		SetRast(&rps[i] , 0);
		Move(&rps[i] , 0 , font->tf_Baseline);
		Text(&rps[i] , digits + i , 1);
	}
}

deallocate_rasters()
{
	register int i;

	for (i = 0; i < 10; i++) {
		if (rast_count-- > 0) FreeRaster(bms[i].Planes[0] , 30 , 30);
		if (rast_count-- > 0) FreeRaster(bms[i].Planes[1] , 30 , 30);
	}
}

scrollin(i , rp , begx , begy , dy , dx)
struct RastPort *rp;
{
	int counter;

	for (counter = 0; counter < dy; counter++) {
		ScrollRaster(rp,0,1,begx,begy,begx+dx,begy+dy);
		ClipBlit(&rps[i],0,counter,rp,begx,begy+dy,dx,1,0xC0);
		Delay(4);
	}
}