home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
634.lha
/
SunClock_1.0
/
Main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-11
|
19KB
|
711 lines
/*-------------------------------------------------------------------------
SunClock
Amiga version by Mark Waggoner,
waggoner@ichips.intel.com or wagnell@PDaXcess.techbook.com
December 1991
This program was developed using Aztec C V5.0a and V5.2
This program was derived from the X11 Sun clock program, which was
in turn derived from a suntools Sun clock program. The author's notices
for those programs appear below.
Since the previous versions of the program were made public domain,
I am also making this program public domain. Sorry, no clever quote
from me.
main.c
-------------------------------------------------------------------------*/
/*
* Sun clock. X11 version by John Mackin.
*
* This program was derived from, and is still in part identical with, the
* Suntools Sun clock program whose author's comment appears immediately
* below. Please preserve both notices.
*
* The X11R3/4 version of this program was written by John Mackin, at the
* Basser Department of Computer Science, University of Sydney, Sydney,
* New South Wales, Australia; <john@cs.su.oz.AU>. This program, like
* the one it was derived from, is in the public domain: `Love is the
* law, love under will.'
*/
/*
Sun clock
Designed and implemented by John Walker in November of 1988.
Version for the Sun Workstation.
The algorithm used to calculate the position of the Sun is given in
Chapter 18 of:
"Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
Richmond: Willmann-Bell, 1985. This book can be obtained from:
Willmann-Bell
P.O. Box 35025
Richmond, VA 23235
USA
Phone: (804) 320-7016
This program was written by:
John Walker
Autodesk, Inc.
2320 Marinship Way
Sausalito, CA 94965
USA
Fax: (415) 389-9418
Voice: (415) 332-2344 Ext. 2829
Usenet: {sun,well,uunet}!acad!kelvin
or: kelvin@acad.uu.net
This program is in the public domain: "Do what thou wilt shall be the
whole of the law". I'd appreciate receiving any bug fixes and/or
enhancements, which I'll incorporate in future versions of the
program. Please leave the original attribution information intact so
that credit and blame may be properly apportioned.
Revision history:
1.0 12/21/89 Initial version.
8/24/89 Finally got around to submitting.
*/
#include <stdio.h>
#include <stdlib.h>
#include <functions.h>
#include <string.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include "images.h"
extern void UpdateImages(int force);
extern int OpenTimer(ULONG sec,ULONG micro);
extern void CloseTimer(void);
extern void ResetTimeReq(ULONG sec,ULONG micro);
extern void AbortTimer(void);
/*-------------------------------------------------------------------------
Gobs of global data
-------------------------------------------------------------------------*/
struct Library *IntuitionBase = NULL;
struct Library *GfxBase = NULL;
/*--- Information about the About window ---*/
struct Window *AboutWin = NULL;
ULONG AboutMask = 0;
/*--- Information about the "icon" window on the workbench ---*/
int AdjustIcon = 1; /* Flag */
int FullScreen = 0; /* Flag */
int AdjustedIconHeight,AdjustedIconWidth;
int IconTop,IconLeft;
static WORD IconIllum[IconHeight];
struct Window *IconWin = NULL;
int whitepen,blackpen;
struct NewWindow NewIconWindow = {
0,0,10,10, /* x,y,w,h */
-1,-1, /* gadget pen,border pen */
CLOSEWINDOW|MOUSEBUTTONS|REFRESHWINDOW|MENUPICK,
/* IDCMP Flags */
WINDOWDEPTH|WINDOWCLOSE|WINDOWDRAG|SIMPLE_REFRESH,
/* System Flags */
NULL,NULL, /* Gadget and Check Image */
(UBYTE *)"Sunclock",/* Title */
NULL, /* Screen to put it in (if TYPE is custom) */
NULL, /* Pointer to Bitmap for SUPER BIT MAP windows */
-1, -1, /* minimum width,height */
-1, -1, /* maximum width,height */
WBENCHSCREEN /* screen TYPE */
};
/*--- Information about the main window on its own screen ---*/
int AdjustedMainHeight,AdjustedMainWidth;
int MainTop,MainLeft;
static WORD MainIllum[MainHeight];
struct Screen *MainScreen = NULL;
struct Window *MainWin = NULL;
char loctimestr[50];
char gmtimestr[50];
struct NewScreen NewMainScreen = {
0,0,640,STDSCREENHEIGHT,1,0,1,
HIRES|LACE,
CUSTOMSCREEN,NULL,(UBYTE *) "Sunclock",
NULL,NULL
};
struct NewWindow NewMainWindow = {
0,0,10,10, /* x,y,w,h */
-1,-1, /* gadget pen,border pen */
MOUSEBUTTONS|REFRESHWINDOW|MENUPICK,
/* IDCMP Flags */
BORDERLESS|BACKDROP|SIMPLE_REFRESH,
/* System Flags */
NULL,NULL, /* Gadget and Check Image */
NULL, /* Title */
NULL, /* Screen to put it in (if TYPE is custom) */
NULL, /* Pointer to Bitmap for SUPER BIT MAP windows */
-1, -1, /* minimum width,height */
-1, -1, /* maximum width,height */
CUSTOMSCREEN /* screen TYPE */
};
/*--- These are set according to whether the window is in its ---*/
/*--- iconized form or its full form. ---*/
struct Window *Win;
struct MsgPort *SigPort;
ULONG WinMask;
UWORD *Data;
WORD *Illum;
UWORD DataWidth,DataHeight;
void (*MapRefresh)(void);
void (*TextRefresh)(void);
struct BitMap MapBitMap;
struct BitMap IllumBitMap;
/*--- Used to get a copy of the workbench screen information ---*/
struct Screen WBScreen;
/*--- Timer data ---*/
struct MsgPort *Timer_Port = NULL;
struct timerequest Time_Request;
ULONG TimerMask = 0;
ULONG DelaySec,DelayMicro;
/*--- TimerMask | WinMask ---*/
ULONG SigMask;
/*--- Menu data ---*/
extern struct Menu ProjectMenu;
extern struct MenuItem ProjectItems[];
/*--- Text for the about window ---*/
char *AllAboutMe[] = {
"SunClock, Amiga version 1.0 by Mark Waggoner, derived from:",
" X11 version by John Mackin, derived from:",
" Suntools version by John Walker.",
"Double click on the world image or use the Iconize menu to switch",
"between the workbench window and a full screen image.",
"",
"To get a correct display of the illuminated portion of the globe,",
"set the environment variable TZ to ZZZnDDD",
"where ZZZ = Time zone name.",
" n = Number of hours you are away from GMT.",
" DDD = Time zone name during daylight savings time.",
"For example, setenv TZ=PST8PDT for pacific time",
"",
"Tooltypes and options:",
"LEFT=x TOP=y FULLSCREEN DONOTADJUST",
"See the documentation for more information",
NULL
};
/*-------------------------------------------------------------------------
Open and close the libraries we need
-------------------------------------------------------------------------*/
void
OpenLibs(void) {
if (!(IntuitionBase = OpenLibrary((UBYTE *)"intuition.library",0L))) {
exit(100);
}
if (!(GfxBase = OpenLibrary((UBYTE *)"graphics.library",0L))) {
CloseLibrary(IntuitionBase);
exit(100);
}
}
void
CloseLibs(void) {
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}
/*-------------------------------------------------------------------------
Get info about the workbench screen and adapt to it
-------------------------------------------------------------------------*/
void
AdjustToScreen(void)
{
int i,pen,minpen=15*3,maxpen=0;
ULONG RGB;
GetScreenData((char *)&WBScreen,sizeof(WBScreen),WBENCHSCREEN,NULL);
/* Figure out how wide to make the window */
NewIconWindow.Width = IconWidth +
WBScreen.WBorLeft + WBScreen.WBorRight;
/* If operating on a non-interlaced screen, use alternate lines of the
icon image */
AdjustedIconWidth = IconWidth;
AdjustedIconHeight = IconHeight;
AdjustedMainWidth = MainWidth;
AdjustedMainHeight = MainHeight;
if (!(WBScreen.ViewPort.Modes & LACE) && AdjustIcon) {
AdjustedIconWidth *= 2;
AdjustedIconHeight /= 2;
AdjustedMainWidth *= 2;
AdjustedMainHeight /= 2;
}
NewIconWindow.Height = AdjustedIconHeight + WBScreen.BarHeight +
WBScreen.WBorTop + WBScreen.WBorBottom;
/* The position of the bitmap within the window */
IconTop = WBScreen.BarHeight + WBScreen.WBorTop;
IconLeft = WBScreen.WBorLeft;
/* Now figure out which pens are "whitest" and "blackest" */
whitepen = 1;
blackpen = 0;
for(i = 0;i < 1<<WBScreen.BitMap.Depth; i++) {
RGB = GetRGB4(WBScreen.ViewPort.ColorMap,i);
pen = (RGB & 0x00f) + ((RGB & 0x0f0) >> 4) + ((RGB & 0xf00) >> 8);
if (pen < minpen) {
minpen = pen;
blackpen = i;
}
if (pen > maxpen) {
maxpen = pen;
whitepen = i;
}
}
}
/*-------------------------------------------------------------------------
Draw the main image
-------------------------------------------------------------------------*/
void
TextMain(void)
{
int sl,l;
SetAPen(MainWin->RPort,1);
SetBPen(MainWin->RPort,0);
SetDrMd(MainWin->RPort,JAM2);
l = TextLength(MainWin->RPort,loctimestr,sl = strlen(loctimestr));
Move(MainWin->RPort,(MainWidth+MainLeft-l)/2,
MainTop+MainHeight+MainWin->RPort->Font->tf_YSize+1);
Text(MainWin->RPort,loctimestr,sl);
l = TextLength(MainWin->RPort,gmtimestr,sl = strlen(gmtimestr));
Move(MainWin->RPort,(MainWidth+MainLeft-l)/2,
MainTop+MainHeight+2*MainWin->RPort->Font->tf_YSize+2);
Text(MainWin->RPort,gmtimestr,sl);
}
void
DrawMain(void)
{
SetAPen(MainWin->RPort,0);
SetBPen(MainWin->RPort,1);
SetDrMd(MainWin->RPort,JAM2);
BltTemplate((PLANEPTR)IllumBitMap.Planes[0],0,((MainWidth+15)/16)*2,
MainWin->RPort,
MainLeft,MainTop,MainWidth,MainHeight);
}
/*-------------------------------------------------------------------------
Start the main window (full sized map)
-------------------------------------------------------------------------*/
int
StartMainWindow(void)
{
/* Get rid of the raster used for the icon map */
if (IllumBitMap.Planes[0])
FreeRaster(IllumBitMap.Planes[0],DataWidth,DataHeight);
/* Open our own screen */
NewMainScreen.Width = MainWidth;
if (!(MainScreen = OpenScreen(&NewMainScreen))) return 0;
/* Set colors for black and white */
SetRGB4(&MainScreen->ViewPort,0, 0, 0, 0); /* Outline */
SetRGB4(&MainScreen->ViewPort,1,15,15,15); /* Background */
/* Open our window */
NewMainWindow.Width = MainWidth;
NewMainWindow.Height = MainScreen->Height - MainScreen->BarHeight;
NewMainWindow.Screen = MainScreen;
NewMainWindow.TopEdge = MainScreen->BarHeight;
MainTop = 0;
MainLeft = 0;
if (!(MainWin = OpenWindow(&NewMainWindow))) {
CloseScreen(MainScreen);
return 0;
}
/* Set up global pointers to the window, etc */
Win = MainWin;
SigPort = Win->UserPort;
WinMask = 1L<<SigPort->mp_SigBit;
SigMask = WinMask | TimerMask | AboutMask;
MapRefresh = DrawMain;
TextRefresh = TextMain;
DataWidth = MainWidth;
DataHeight = MainHeight;
Data = MainData;
Illum = MainIllum;
/* Set up the bitmap structure for the full sized map */
InitBitMap(&MapBitMap,2,MainWidth,MainHeight);
MapBitMap.Planes[0] = (PLANEPTR) MainData;
/* Allocate and set up a bitmap for the illumination mask */
InitBitMap(&IllumBitMap,1,MainWidth,MainHeight);
if (!(IllumBitMap.Planes[0] = AllocRaster(MainWidth,MainHeight))) {
CloseWindow(MainWin);
CloseScreen(MainScreen);
return 0;
}
ProjectItems[1].Flags &= ~CHECKED;
SetMenuStrip(MainWin,&ProjectMenu);
DelaySec = 1;
DelayMicro = 0;
AbortTimer();
UpdateImages(1);
return 1;
}
/*-------------------------------------------------------------------------
Switch to the Main Window
-------------------------------------------------------------------------*/
int
SwitchToMain(void)
{
if (MainWin)
return 0;
if (IconWin) {
NewIconWindow.LeftEdge = IconWin->LeftEdge;
NewIconWindow.TopEdge = IconWin->TopEdge;
ClearMenuStrip(IconWin);
CloseWindow(IconWin);
IconWin = NULL;
}
if (!StartMainWindow()) return 1;
(*MapRefresh)();
(*TextRefresh)();
return 0;
}
/*-------------------------------------------------------------------------
Start and End the About Window
-------------------------------------------------------------------------*/
void
StartAbout(void)
{
char *s;
int i;
struct NewWindow NW;
if (AboutWin) return;
NW.TopEdge =
NW.LeftEdge = 0;
NW.Width = 600;
NW.Height = 200;
NW.DetailPen = NW.BlockPen = -1;
NW.IDCMPFlags = CLOSEWINDOW;
NW.Flags = WINDOWDEPTH|WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|
SMART_REFRESH|NOCAREREFRESH;
NW.FirstGadget = NULL;
NW.CheckMark = NULL;
NW.Title = (UBYTE *) "About SunClock";
NW.Screen = NULL;
NW.BitMap = NULL;
NW.MinWidth = NW.MinHeight =
NW.MaxWidth = NW.MaxHeight = -1;
NW.Type = WBENCHSCREEN;
if (!(AboutWin = OpenWindow(&NW)))
return;
SetAPen(AboutWin->RPort,whitepen);
SetDrMd(AboutWin->RPort,JAM1);
RectFill(AboutWin->RPort,AboutWin->BorderLeft,AboutWin->BorderTop,
AboutWin->Width-AboutWin->BorderLeft-AboutWin->BorderRight,
AboutWin->Height-AboutWin->BorderTop-AboutWin->BorderBottom);
SetAPen(AboutWin->RPort,blackpen);
for(i=0;AllAboutMe[i];i++) {
Move(AboutWin->RPort,10,
AboutWin->BorderTop+(i+1)*AboutWin->RPort->Font->tf_YSize+5);
Text(AboutWin->RPort,AllAboutMe[i],strlen(AllAboutMe[i]));
}
AboutMask = 1L<<AboutWin->UserPort->mp_SigBit;
SigMask = WinMask | TimerMask | AboutMask;
WBenchToFront();
return;
}
void
EndAbout(void)
{
if (AboutWin)
CloseWindow(AboutWin);
AboutWin = NULL;
AboutMask = 0;
SigMask = WinMask | TimerMask | AboutMask;
if (MainScreen)
ScreenToFront(MainScreen);
return;
}
/*-------------------------------------------------------------------------
Draw the iconized image
-------------------------------------------------------------------------*/
void
TextIcon(void)
{
}
void
DrawIcon(void)
{
SetAPen(IconWin->RPort,blackpen);
SetBPen(IconWin->RPort,whitepen);
SetDrMd(IconWin->RPort,JAM2);
BltTemplate((PLANEPTR)IllumBitMap.Planes[0],0,((AdjustedIconWidth+15)/16)*2,
IconWin->RPort,
IconLeft,IconTop,IconWidth,AdjustedIconHeight);
}
/*-------------------------------------------------------------------------
Start the icon window
-------------------------------------------------------------------------*/
int
StartIconWindow(void)
{
if (IllumBitMap.Planes[0])
FreeRaster(IllumBitMap.Planes[0],DataWidth,DataHeight);
if (!(IconWin = OpenWindow(&NewIconWindow)))
return 0;
Win = IconWin;
SigPort = Win->UserPort;
WinMask = 1L<<SigPort->mp_SigBit;
SigMask = WinMask | TimerMask | AboutMask;
MapRefresh = DrawIcon;
TextRefresh = TextIcon;
Data = IconData;
DataWidth = IconWidth;
DataHeight = IconHeight;
Illum = IconIllum;
InitBitMap(&MapBitMap,1,IconWidth,IconHeight);
MapBitMap.Planes[0] = (PLANEPTR) IconData;
InitBitMap(&IllumBitMap,1,IconWidth,IconHeight);
if (!(IllumBitMap.Planes[0] = AllocRaster(IconWidth,IconHeight))) {
CloseWindow(IconWin);
return 0;
}
ProjectItems[1].Flags |= CHECKED;
SetMenuStrip(IconWin,&ProjectMenu);
DelaySec = 60;
DelayMicro = 0;
AbortTimer();
UpdateImages(1);
return 1;
}
/*-------------------------------------------------------------------------
Switch to the Icon Window
-------------------------------------------------------------------------*/
int
SwitchToIcon(void)
{
if (IconWin)
return 0;
if (MainWin) {
ClearMenuStrip(MainWin);
CloseWindow(MainWin);
}
if (MainScreen) CloseScreen(MainScreen);
MainWin = NULL;
MainScreen = NULL;
if (!StartIconWindow()) return 1;
(*MapRefresh)();
(*TextRefresh)();
return 0;
}
/*-------------------------------------------------------------------------
Handle all events from the windows
-------------------------------------------------------------------------*/
int
HandleWindowMsgs(void)
{
struct IntuiMessage *M;
struct Window *win;
struct MenuItem *item;
ULONG sec,mic;
static ULONG sec0 = 0,mic0 = 0;
ULONG class;
USHORT code;
while(M = (struct IntuiMessage *) GetMsg(SigPort)) {
class = M->Class;
code = M->Code;
sec = M->Seconds;
mic = M->Micros;
win = M->IDCMPWindow;
ReplyMsg((struct Message *) M);
switch(class) {
case CLOSEWINDOW:
return 1;
break;
case REFRESHWINDOW:
BeginRefresh(Win);
(*MapRefresh)();
(*TextRefresh)();
EndRefresh(Win,1);
break;
case MOUSEBUTTONS:
if (code == SELECTDOWN) {
if (DoubleClick(sec0,mic0,sec,mic)) {
if (IconWin) {
if (SwitchToMain()) return 1;
}
else {
if (SwitchToIcon()) return 1;
}
}
sec0 = sec;
mic0 = mic;
}
break;
case MENUPICK:
while (code != MENUNULL) {
item = ItemAddress(&ProjectMenu,code);
switch(ITEMNUM(code)) {
case 0: /* About */
StartAbout();
break;
case 1: /* Iconize */
if (item->Flags & CHECKED) {
if (SwitchToIcon()) return 1;
}
else {
if (SwitchToMain()) return 1;
}
break;
case 2: /* Quit */
return 1;
break;
default:
break;
}
code = item->NextSelect;
}
break;
default:
break;
}
}
return 0;
}
/*-------------------------------------------------------------------------
The main Event loop
-------------------------------------------------------------------------*/
void
MainLoop(void)
{
ULONG MsgMask;
if (FullScreen) {
if (!StartMainWindow()) return;
}
else {
if (!StartIconWindow()) return;
}
(*MapRefresh)();
(*TextRefresh)();
while (1) {
MsgMask = Wait(SigMask);
if (MsgMask & TimerMask) {
UpdateImages(0);
ResetTimeReq(DelaySec,DelayMicro);
}
if (MsgMask & WinMask) {
if (HandleWindowMsgs()) return;
}
if (MsgMask & AboutMask) {
EndAbout();
}
}
}
/*-------------------------------------------------------------------------
Clean up all of our resources
-------------------------------------------------------------------------*/
void
clean_up(void) {
if (AboutWin)
CloseWindow(AboutWin);
CloseTimer();
if (IllumBitMap.Planes[0])
FreeRaster(IllumBitMap.Planes[0],DataWidth,DataHeight);
if (IconWin) {
ClearMenuStrip(IconWin);
CloseWindow(IconWin);
}
if (MainWin) {
ClearMenuStrip(MainWin);
CloseWindow(MainWin);
}
if (MainScreen) CloseScreen(MainScreen);
CloseLibs();
}
main(int argc,char *argv[])
{
/* Add the cleanup routine to the actions to take at exit time */
if (atexit(clean_up))
exit(20);
OpenLibs();
DelaySec = 5;
DelayMicro = 0;
if (!OpenTimer(DelaySec,DelayMicro)) exit(20);
AdjustToScreen();
MainLoop();
exit(0);
}