home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d566
/
apfelkiste.lha
/
Apfelkiste
/
Apfelkiste2.0
/
Source
/
Apfelkiste2.0src.lzh
/
Apfelkiste.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-23
|
28KB
|
1,041 lines
/************************************************************************/
/* Apfel.c --- Generates an image of the Mandelbrot-set */
/* */
/* Author: M. Böhnisch (BillySoft) */
/* Löher Str. 2 */
/* D-4790 Paderborn */
/* */
/* billy@uni-paderborn.de.pbinfo */
/*======================================================================*/
/* 06.11.89 iterative version with fixed box sizes (10 by 10), */
/* adapted a GFA-BASIC program from a german magazine */
/* */
/* 08.11.89 complete own version with recursive algorithm */
/* (divide & conquer) */
/* */
/* 10.11.89 added user input of picture size and borders */
/* */
/* 11.11.89 minor bug fixing */
/* */
/* 20.11.89 added fix-point arithmetik written in assembler */
/* format: */
/* */
/* [sgn|xxx xxxx xxxx xxxx.xxxx xxxx xxxx xxxx] */
/* */
/* not accurate enough. */
/* */
/* 21.11.89 rewrote fix-point format to: */
/* */
/* [sgn|xxx xxxx.xxxx xxxx xxxx xxxx xxxx xxxx] */
/* */
/* nice! (I'll try to use 26 bit after the point sometime) */
/* */
/* 28.11.89 found IFF-Library on Fish #173. save picture option */
/* added. */
/* */
/* 04.12.89 improved assembly program */
/* */
/* 07.12.89 slight optimization in recursion scheme */
/* */
/* 09.12.89 added input requester */
/* */
/* 21.07.90 review for Aztek-C5.0a */
/* */
/* 23.09.90 print option added (color printers) */
/* */
/* 25.09.90 added color requester */
/* */
/* 27.09.90 optimization of assembly program */
/* */
/* 15.11.90 review for SAS C5.10 */
/* */
/* 19.11.90 added a little retrying in case of an error by closing */
/* screens. Might recover some problems with Amigas short */
/* on memory or when really *BIG* screens are requested. */
/* */
/* 25.11.90 added s'more source code comments and translated all */
/* strings from german to english */
/* */
/* 30.01.91 removed a bug causing to save no colormap along with a */
/* picture */
/* */
/* 01.02.91 removed a bug doing strange things while colorcycling */
/* pictures with more than 5 BitPlanes */
/* */
/* 01.02.91 added configuration facilities */
/* */
/* 17.04.91 removed a bug preventing the "Multitasking OFF" to work */
/* */
/* 18.04.91 some cast - operators added in "printersupport.h" to */
/* compile without warnings. */
/* */
/* 08.06.91 added 68030/68881 support */
/* */
/* 09.06.91 replaced lattice fp by fast floating point functions */
/* (faster only if FLOAT is used. shorter object, though) */
/************************************************************************/
/* W A R N I N G ! ! ! */
/* */
/* From now on ALL versions of Apfelkiste will need KS 2.0 and the new */
/* set of include files. This applies to version 28 and above. */
/************************************************************************/
/* */
/* 12.06.91 switched to 2.0 at last. removed ARP routines, not */
/* because they're bad (THEY AREN'T!), but because of */
/* naming conflicts of arp.h to 2.0 include files. */
/* */
/* 12.06.91 added some all *new* facilities: */
/* o automatic overscan adaption */
/* o autoscrolling screen */
/* */
/* 22.07.91 2.0 style gadgets provided */
/* */
/* 23.07.91 located a bug in SAS's fscanf() (!!!), %hx does NOT */
/* read 16 Bit integers but 32 Bit longs. Thus lead into */
/* a strange error that occurred with pictures >3 */
/* bitplanes only: all colors above #8 are set to 0(black) */
/* Fixed by scanning into a temporary long first. */
/* */
/* 23.10.91 changed names of OpenIFF() and CloseIFF() to xOpenIFF() */
/* and xCloseIFF() for KS 2.0 include file compatibility */
/* */
/* updated docs for inclusion in AmigaLibDisk pool */
/* */
/* last-minute review for SAS C5.10b */
/************************************************************************/
/* -------------------------------------------------------------------- */
/* Some defininitions to take advantage of Lattice's LSR-code: */
/* -------------------------------------------------------------------- */
long _stack = 20000; /* Stack space for this task */
char *_procname = "Apfelkiste"; /* Name of process created */
long _priority = 0; /* Process priority */
long _BackgroundIO = 0; /* No stdio required */
/* -------------------------------------------------------------------- */
#define APFEL_VERSION "30"
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <libraries/iff.h>
#include <libraries/asl.h>
#include <libraries/color.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/asl.h>
#include <proto/gadtools.h>
#include <printersupport.h>
#include <clib/macros.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mffp.h>
#include <math.h>
#include "Apf0.h"
#include "Apf2.h"
/* -------------------------------------------------------------------- */
/* Prototypes for the functions in the other modules */
/* -------------------------------------------------------------------- */
void FixPoint( double rmin, double rmax, double imin, double imax,
double dx, double dy,
int maxiter, double divergenz, int gx, int gy, int depth);
void __regargs Apfel_Alert(long number);
void __regargs Activate_Gadget(struct Window *w, USHORT ID);
void __regargs Apfel_FLOAT(int x1, int y1, int x2, int y2);
long Iter_FLOAT(double r, double i);
void FreeGads(void);
struct Gadget *InitGads(struct Screen *scr);
/* --------------------------------------------------------------------- */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct IFFBase *IFFBase;
struct Library *AslBase;
struct ColorBase *ColorBase;
struct Library *GadToolsBase;
struct Screen *s;
struct Window *w, *u;
struct RastPort *rp, *up;
struct ViewPort *vp;
struct Gadget *glist;
char DefBuf_REAL0[40];
char DefBuf_REAL1[40];
char DefBuf_IMAG0[40];
char DefBuf_IMAG1[40];
char DefBuf_MAXITER[40];
char DefBuf_DIV[40];
char DefBuf_XSIZE[40];
char DefBuf_YSIZE[40];
char DefBuf_DEPTH[40];
extern long SelNo_TASK;
extern long SelNo_CYCLE;
extern char *Buf_REAL0;
extern char *Buf_REAL1;
extern char *Buf_IMAG0;
extern char *Buf_IMAG1;
extern char *Buf_MAXITER;
extern char *Buf_DIV;
extern char *Buf_XSIZE;
extern char *Buf_YSIZE;
extern char *Buf_DEPTH;
extern char *DefText_REAL0;
extern char *DefText_REAL1;
extern char *DefText_IMAG0;
extern char *DefText_IMAG1;
extern char *DefText_MAXITER;
extern char *DefText_DIV;
extern char *DefText_XSIZE;
extern char *DefText_YSIZE;
extern char *DefText_DEPTH;
int cycle, task = TRUE;
APTR IFFfile = NULL;
struct FileRequester *FReq;
union printerIO *request;
struct MsgPort *printerPort;
int gx, gy, xsize, ysize, depth, hide;
short maxcol;
int maxiter;
double divergenz, rmin, rmax, imin, imax, dx, dy;
/* -------------------------------------------------------------------- */
/* All the stuff needed to comfortably get IntuitionMessages */
/* -------------------------------------------------------------------- */
ULONG CLASS, CODE, GAD_ID;
APTR ADDR;
struct IntuiMessage *Message = NULL;
ULONG GetMessage(struct Window *MW)
{
CLASS = CODE = 0;
ADDR = NULL;
if ( Message = (struct IntuiMessage *) GetMsg(MW->UserPort) ) {
CLASS = Message->Class;
CODE = Message->Code;
ADDR = Message->IAddress;
ReplyMsg((struct Message *) Message);
}
return CLASS;
}
ULONG GT_GetMessage(struct Window *MW)
{
CLASS = CODE = GAD_ID = 0;
ADDR = NULL;
if ( Message = GT_GetIMsg(MW->UserPort) ) {
CLASS = Message->Class;
CODE = Message->Code;
ADDR = Message->IAddress;
if ( CLASS == IDCMP_GADGETUP ) {
GAD_ID = ((struct Gadget *) ADDR)->GadgetID;
}
GT_ReplyIMsg(Message);
}
return CLASS;
}
/* -------------------------------------------------------------------- */
/* Simple routine to draw a rectangular shape. Used for the Mouse Opt */
/* -------------------------------------------------------------------- */
void DrawRect(struct RastPort *rp, short x1, short y1, short x2, short y2)
{
Move(rp, x1, y1);
Draw(rp, x2, y1);
Draw(rp, x2, y2);
Draw(rp, x1, y2);
Draw(rp, x1, y1);
}
/* -------------------------------------------------------------------- */
/* Pre-initialized structures for main screen and window */
/* -------------------------------------------------------------------- */
UWORD PenSpec[] = { ~0 }; /* Minimal pen specifikation array */
struct TextAttr TOPAZ80 = { (STRPTR) "topaz.font", TOPAZ_EIGHTY, 0, 0 };
struct NewScreen NS = {
0, 0, /* screen XY origin relative to View */
0, 0, /* screen width and height */
0, /* screen depth (number of bitplanes) */
0, 1, /* detail and block pens */
NULL, /* display modes for this screen */
CUSTOMSCREEN | SCREENQUIET, /* screen type */
&TOPAZ80, /* pointer to default screen font */
NULL, /* screen title */
NULL, /* first in list of custom screen gadgets */
NULL /* pointer to custom BitMap structure */
};
struct NewWindow NW = {
0, 0, /* window XY origin relative to TopLeft of screen */
0, 0, /* window width and height */
0, 1, /* detail and block pens */
NULL, /* IDCMP flags */
SMART_REFRESH |
ACTIVATE |
BORDERLESS, /* other window flags */
NULL, /* first gadget in gadget list */
NULL, /* custom CHECKMARK imagery */
NULL, /* window title */
NULL, /* custom screen pointer */
NULL, /* custom bitmap */
5, 5, /* minimum width and height */
-1, -1, /* maximum width and height */
CUSTOMSCREEN /* destination screen type */
};
struct NewWindow NW2 = {
0, 0, /* window XY origin relative to TopLeft of screen */
320, 196, /* window width and height */
0, 1, /* detail and block pens */
GADGETUP, /* IDCMP flags */
WINDOWDRAG |
ACTIVATE |
NOCAREREFRESH, /* other window flags */
NULL, /* first gadget in gadget list */
NULL, /* custom CHECKMARK imagery */
NULL, /* window title */
NULL, /* custom screen pointer */
NULL, /* custom bitmap */
5, 5, /* minimum width and height */
-1, -1, /* maximum width and height */
CUSTOMSCREEN /* destination screen type */
};
/* -------------------------------------------------------------------- */
/* Default palette. Change this if you don't like the colors provided */
/* by me. Versions 25 and higher are supporting a custom default file. */
/* -------------------------------------------------------------------- */
USHORT Palette[128] = {
0x0000, /* color #0 */
0x0F90, /* color #1 */
0x0F20, /* color #2 */
0x0840, /* color #3 */
0x0580, /* color #4 */
0x0589, /* color #5 */
0x055F, /* color #6 */
0x0A0F, /* color #7 */
0x0F08, /* color #8 */
0x0777, /* color #9 */
0x0080, /* color #10 */
0x00A0, /* color #11 */
0x00C0, /* color #12 */
0x00E0, /* color #13 */
0x08E0, /* color #14 */
0x0FF0, /* color #15 */
0x0000, /* color #16 */
0x0F90, /* color #17 */
0x0F20, /* color #18 */
0x0840, /* color #19 */
0x0580, /* color #20 */
0x0589, /* color #21 */
0x055F, /* color #22 */
0x0A0F, /* color #23 */
0x0F08, /* color #24 */
0x0777, /* color #25 */
0x0080, /* color #26 */
0x00A0, /* color #27 */
0x00C0, /* color #28 */
0x00E0, /* color #29 */
0x08E0, /* color #30 */
0x0FF0 /* color #31 */
#define PaletteColorCount 32
};
/* -------------------------------------------------------------------- */
/* Close everything opened at runtime */
/* -------------------------------------------------------------------- */
void CleanUp(void)
{
if ( FReq ) FreeAslRequest(FReq);
if ( request ) DeleteExtIO((struct IORequest *) request);
if ( printerPort ) DeletePort(printerPort);
if ( IFFfile ) xCloseIFF(IFFfile);
if ( w ) CloseWindow(w);
if ( u ) CloseWindow(u);
if ( glist ) FreeGads();
if ( s ) CloseScreen(s);
if ( GadToolsBase ) CloseLibrary(GadToolsBase);
if ( ColorBase ) CloseLibrary(ColorBase);
if ( AslBase ) CloseLibrary(AslBase);
if ( IFFBase ) CloseLibrary(IFFBase);
if ( GfxBase ) CloseLibrary(GfxBase);
if ( IntuitionBase ) CloseLibrary(IntuitionBase);
exit(0);
}
/* -------------------------------------------------------------------- */
/* Open all used libraries, ports, etc. If this routine fails you are */
/* probably not up-to-date with one or several of the shared libraries */
/* used by me. Copy the provided libraries to your LIBS: directory, */
/* reboot (!) and try again. */
/* -------------------------------------------------------------------- */
void OpenLibs(void)
{
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 36);
if ( ! IntuitionBase ) {
Apfel_Alert(1);
CleanUp();
}
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 36);
if ( ! GfxBase ) {
Apfel_Alert(2);
CleanUp();
}
IFFBase = (struct IFFBase *) OpenLibrary(IFFNAME, IFFVERSION);
if ( ! IFFBase ) {
Apfel_Alert(3);
CleanUp();
}
AslBase = OpenLibrary(AslName, 0);
if ( ! AslBase ) {
Apfel_Alert(4);
CleanUp();
}
ColorBase = (struct ColorBase *) OpenLibrary(COLORNAME, COLORVERSION);
if ( ! ColorBase ) {
Apfel_Alert(5);
CleanUp();
}
GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 0);
if ( ! GadToolsBase ) {
Apfel_Alert(15);
CleanUp();
}
FReq = AllocFileRequest();
if ( ! FReq ) {
Apfel_Alert(6);
CleanUp();
}
printerPort = CreatePort("Apfel-01.port",0L);
if ( ! printerPort ) {
Apfel_Alert(7);
CleanUp();
}
request = (union printerIO *) CreateExtIO(printerPort, sizeof(union printerIO));
if ( ! request ) {
Apfel_Alert(8);
CleanUp();
}
}
/* -------------------------------------------------------------------- */
/* Open the control window and set gadget texts to appropriate values */
/* -------------------------------------------------------------------- */
void OpenRW(void)
{
int wbflag = FALSE;
NW2.Screen = s;
if ( ! s ) {
NW2.Type = WBENCHSCREEN;
}
else {
NW2.Type = CUSTOMSCREEN;
}
if ( task ) {
SelNo_TASK = 1;
}
else {
SelNo_TASK = 0;
}
if ( cycle ) {
SelNo_CYCLE = 1;
}
else {
SelNo_CYCLE = 0;
}
if ( ! s ) {
s = LockPubScreen("Workbench");
wbflag = TRUE;
}
glist = InitGads(s);
if ( ! glist ) CleanUp();
u = OpenWindowTags(&NW2, WA_Gadgets, glist, TAG_END);
if ( wbflag ) {
UnlockPubScreen(NULL, s);
s = NULL;
}
/* open control window */
if ( ! u ) { /* if something goes wrong... */
Apfel_Alert(9); /* give message. */
if ( s ) { /* is the screen open, then ? */
CloseScreen(s); /* close it... */
s = NULL;
OpenRW(); /* and retry on WB Screen... */
}
else { /* No screen, no hope... */
CleanUp(); /* exiting... */
}
}
up = u->RPort;
GT_RefreshWindow(u, NULL);
}
void CloseRW(void)
{
if ( u ) {
strcpy(DefBuf_REAL0 ,Buf_REAL0);
strcpy(DefBuf_REAL1 ,Buf_REAL1);
strcpy(DefBuf_IMAG0 ,Buf_IMAG0);
strcpy(DefBuf_IMAG1 ,Buf_IMAG1);
strcpy(DefBuf_MAXITER,Buf_MAXITER);
strcpy(DefBuf_DIV ,Buf_DIV);
strcpy(DefBuf_XSIZE ,Buf_XSIZE);
strcpy(DefBuf_YSIZE ,Buf_YSIZE);
strcpy(DefBuf_DEPTH ,Buf_DEPTH);
DefText_REAL0 = DefBuf_REAL0;
DefText_REAL1 = DefBuf_REAL1;
DefText_IMAG0 = DefBuf_IMAG0;
DefText_IMAG1 = DefBuf_IMAG1;
DefText_MAXITER = DefBuf_MAXITER;
DefText_DIV = DefBuf_DIV;
DefText_XSIZE = DefBuf_XSIZE;
DefText_YSIZE = DefBuf_YSIZE;
DefText_DEPTH = DefBuf_DEPTH;
CloseWindow(u);
FreeGads();
u = NULL;
glist = NULL;
}
}
/* -------------------------------------------------------------------- */
/* Open screen & window for graphics rendition trying to evaluate a */
/* "best match" for the view modes for both PAL and NTSC. Maybe this */
/* needs a little work for optimal results on NTSC machines. */
/* I plan to rework this completely after CBM pops out Kick 2.0 for */
/* the A2000 in an official version. */
/* -------------------------------------------------------------------- */
void OpenAll(void)
{
USHORT Modes = 0;
int cnt;
NS.Width = xsize;
NS.Height = ysize;
NS.Depth = depth;
maxcol = cnt = 1 << depth;
if ( xsize > 350 ) Modes = HIRES;
if ( ! Modes && depth == 6 ) {
Modes = EXTRA_HALFBRITE;
cnt = 32;
}
if ( ysize > 262 ) Modes |= LACE;
NS.ViewModes = Modes;
s = OpenScreenTags(&NS,
SA_Overscan, OSCAN_STANDARD,
SA_AutoScroll, TRUE,
SA_FullPalette, TRUE,
SA_SysFont, 0,
SA_Pens, PenSpec,
TAG_DONE);
if ( ! s ) {
Apfel_Alert(10);
}
else {
NW.Screen = s;
NW.Width = gx;
NW.Height = gy;
NW.LeftEdge = (xsize - gx) / 2;
NW.TopEdge = (ysize - gy) / 2;
w = OpenWindow(&NW);
if ( ! w ) {
Apfel_Alert(9);
}
else {
rp = w->RPort;
vp = &(s->ViewPort);
LoadRGB4(vp, Palette, cnt);
}
}
}
/* -------------------------------------------------------------------- */
/* Load an IFF ILBM file and get it displayed on the graphics screen. */
/* I have not put too much work into this, e.g. there is no chunk for */
/* the data needed to re-calculate the loaded Mandelbrot image. */
/* Comments and help are welcome, just send me a message to my E-Mail */
/* adress. */
/* -------------------------------------------------------------------- */
BOOL LoadFile(char *Name)
{
struct BitMapHeader *bmhd;
ULONG cnt;
IFFfile = xOpenIFF(Name);
if ( ! IFFfile ) {
Apfel_Alert(12);
}
else {
bmhd = GetBMHD(IFFfile);
if ( ! bmhd ) {
Apfel_Alert(13);
}
else {
NS.Width = gx = xsize = bmhd->w;
NS.Height = gy = ysize = bmhd->h;
NS.Depth = depth = bmhd->nPlanes;
maxcol = 1 << depth;
NS.ViewModes = GetViewModes(IFFfile);
s =
OpenScreenTags(&NS,
SA_Overscan, OSCAN_STANDARD,
SA_AutoScroll, TRUE,
SA_SysFont, 1,
TAG_DONE);
if ( ! s ) {
Apfel_Alert(10);
}
else {
vp = &(s->ViewPort);
cnt = GetColorTab(IFFfile, (WORD *) Palette);
NW.Screen = s;
NW.Width = gx;
NW.Height = gy;
w = OpenWindow(&NW);
if ( ! w ) {
Apfel_Alert(9);
CloseScreen(s);
s = NULL;
}
else {
rp = w->RPort;
LoadRGB4(vp, Palette, cnt);
if ( ! DecodePic(IFFfile, rp->BitMap) ) {
Apfel_Alert(14);
CloseWindow(w);
w = NULL;
CloseScreen(s);
s = NULL;
}
}
}
}
xCloseIFF(IFFfile);
IFFfile = NULL;
}
return ( w != NULL ); /* All OK if window still open */
}
/* -------------------------------------------------------------------- */
/* Set default values for the control window. Load the default image to */
/* comfortably get zoomed into this wonderful world of chaos. */
/* -------------------------------------------------------------------- */
void SetDefault(void)
{
FILE *fp;
char defpic[FMSIZE];
int i;
int omt;
long tmp;
omt = task;
fp = fopen("Apfelkiste.config", "r");
if ( ! fp ) fopen("DEVS:Apfelkiste.config", "r");
if ( ! fp ) fopen("S:Apfelkiste.config", "r");
if ( ! fp ) {
Apfel_Alert(11);
strcpy(defpic, "Apfel0.IFF");
rmin = -2.3;
imin = -1.25;
rmax = 0.825;
imax = 1.25;
maxiter = 30;
divergenz = 6.0;
cycle = FALSE;
task = TRUE;
}
else {
fscanf(fp, "FNAME=%s", defpic);
fscanf(fp, "RMIN=%lf", &rmin);
fscanf(fp, "RMAX=%lf", &rmax);
fscanf(fp, "IMIN=%lf", &imin);
fscanf(fp, "IMAX=%lf", &imax);
fscanf(fp, "MAXITER=%d", &maxiter);
fscanf(fp, "DIVERGENZ=%lf", &divergenz);
fscanf(fp, "TASK=%d", &task);
fscanf(fp, "CYCLE=%d", &cycle);
for ( i = 0; i < PaletteColorCount; i++ ) {
fscanf(fp, "COLOR=%x", &tmp);
Palette[i] = (UWORD) tmp;
}
fclose(fp);
}
if ( ! LoadFile("Apfel0.IFF") ) {
xsize = gx = 320;
ysize = gy = 200;
depth = 2;
maxcol = 1 << depth;
}
dx = (rmax - rmin) / (double) gx;
dy = (imax - imin) / (double) gy;
sprintf(DefBuf_REAL0 , "%lf", rmin);
sprintf(DefBuf_REAL1 , "%lf", rmax);
sprintf(DefBuf_IMAG0 , "%lf", imin);
sprintf(DefBuf_IMAG1 , "%lf", imax);
sprintf(DefBuf_MAXITER, "%d" , maxiter);
sprintf(DefBuf_DIV , "%lf", divergenz);
sprintf(DefBuf_XSIZE , "%d" , gx);
sprintf(DefBuf_YSIZE , "%d" , gy);
sprintf(DefBuf_DEPTH , "%d" , depth);
DefText_REAL0 = DefBuf_REAL0;
DefText_REAL1 = DefBuf_REAL1;
DefText_IMAG0 = DefBuf_IMAG0;
DefText_IMAG1 = DefBuf_IMAG1;
DefText_MAXITER = DefBuf_MAXITER;
DefText_DIV = DefBuf_DIV;
DefText_XSIZE = DefBuf_XSIZE;
DefText_YSIZE = DefBuf_YSIZE;
DefText_DEPTH = DefBuf_DEPTH;
if ( omt != task ) {
if ( task ) {
Permit();
}
else {
Forbid();
}
}
}
/* -------------------------------------------------------------------- */
/* Used by load/save routines to get filenames. */
/* -------------------------------------------------------------------- */
BOOL GetFileName(char *Name, char *Hail)
{
if ( AslRequestTags(FReq,
ASL_Hail, Hail,
ASL_Window, w,
TAG_DONE) ) {
strmfp(Name, FReq->rf_Dir, FReq->rf_File);
return TRUE;
}
else {
return FALSE;
}
}
/************************************************************************/
/* The main() function, at last... */
/* Contains the handling to react on gadget activation and manage the */
/* call of the diverse subroutines. */
/* Not commented at all, but shouldn't be too difficult to read anyway. */
/************************************************************************/
void main(int argc, char *argv[])
{
char fname[80];
int i, x, y;
double help;
int mx1, my1, mx2, my2;
UWORD c_palette[128];
OpenLibs();
SetDefault();
OpenRW();
do {
WaitPort(u -> UserPort);
GT_GetMessage(u);
switch ( CLASS ) {
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(u);
GT_EndRefresh(u, TRUE);
break;
case IDCMP_GADGETUP:
switch ( GAD_ID ) {
case GAD_FLOAT:
case GAD_FXP:
sscanf(Buf_REAL0 , "%lf", &rmin);
sscanf(Buf_REAL1 , "%lf", &rmax);
sscanf(Buf_IMAG0 , "%lf", &imin);
sscanf(Buf_IMAG1 , "%lf", &imax);
sscanf(Buf_MAXITER, "%d" , &maxiter);
sscanf(Buf_DIV , "%lf", &divergenz);
sscanf(Buf_XSIZE , "%d" , &gx);
sscanf(Buf_YSIZE , "%d" , &gy);
sscanf(Buf_DEPTH , "%d" , &depth);
xsize = gx;
if ( gx <= 736 ) xsize = 736; /* Max. Overscan Hires */
if ( gx <= 640 ) xsize = 640; /* Nor. Size Hires */
if ( gx <= 368 ) xsize = 368; /* Max. Overscan Lores */
if ( gx <= 320 ) xsize = 320; /* Nor. Size Lores */
ysize = gy;
if ( gy <= 564 ) ysize = 564; /* Max. Overscan Lace PAL */
if ( gy <= 512 ) ysize = 512; /* Nor. Size Lace PAL */
if ( gy <= 400 ) ysize = 400; /* Nor. Size Lace NTSC */
if ( gy <= 282 ) ysize = 282; /* Max. Overscan NoLace PAL */
if ( gy <= 256 ) ysize = 256; /* Nor. Size NoLace PAL */
if ( gy <= 200 ) ysize = 200; /* Nor. Size NoLace NTSC */
if ( w ) CloseWindow(w);
w = NULL;
CloseRW();
if ( s ) CloseScreen(s);
s = NULL;
OpenAll();
if ( w && s ) {
dx = (rmax - rmin) / (double) gx;
dy = (imax - imin) / (double) gy;
switch ( GAD_ID ) {
case GAD_FLOAT:
help = rmin;
for ( x = 0; x < gx; x++ ) {
SetAPen(rp, Iter_FLOAT(help, imin));
WritePixel(rp, x, 0);
SetAPen(rp, Iter_FLOAT(help, imax));
WritePixel(rp, x, gy-1);
help += dx;
}
help = imin;
for ( y = 0; y < gy; y++ ) {
SetAPen(rp, Iter_FLOAT(rmin, help));
WritePixel(rp, 0, y);
SetAPen(rp, Iter_FLOAT(rmax, help));
WritePixel(rp, gx-1, y);
help += dy;
}
Apfel_FLOAT(0, 0, gx - 1, gy - 1);
break;
case GAD_FXP:
FixPoint(rmin, rmax, imin, imax, dx, dy,
maxiter, divergenz,
gx, gy, depth);
break;
}
}
else {
if ( s ) {
CloseScreen(s);
s = NULL;
}
}
OpenRW();
break;
case GAD_QUIT:
CleanUp();
break;
case GAD_SAVE:
CloseRW();
if ( GetFileName(fname, "Save Picture") ) {
SaveBitMap(fname, &(s->BitMap), Palette, 0x1L);
}
OpenRW();
break;
case GAD_LOAD:
CloseRW();
if ( GetFileName(fname, "Load Picture") ) {
if ( w ) CloseWindow(w);
w = NULL;
if ( s ) CloseScreen(s);
s = NULL;
if ( ! LoadFile(fname) ) {;}
}
OpenRW();
break;
case GAD_REAL0:
Activate_Gadget(u, GAD_REAL1);
break;
case GAD_REAL1:
Activate_Gadget(u, GAD_IMAG0);
break;
case GAD_IMAG0:
Activate_Gadget(u, GAD_IMAG1);
break;
case GAD_IMAG1:
Activate_Gadget(u, GAD_MAXITER);
break;
case GAD_MAXITER:
Activate_Gadget(u, GAD_DIV);
break;
case GAD_DIV:
Activate_Gadget(u, GAD_XSIZE);
break;
case GAD_XSIZE:
Activate_Gadget(u, GAD_YSIZE);
break;
case GAD_YSIZE:
Activate_Gadget(u, GAD_DEPTH);
break;
case GAD_DEPTH:
Activate_Gadget(u, GAD_REAL0);
break;
case GAD_MOUSE:
if ( s && w ) {
CloseRW();
ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
do {
WaitPort(w->UserPort);
GetMessage(w);
} while ( CLASS != MOUSEBUTTONS || CODE != SELECTDOWN );
mx2 = mx1 = w->MouseX;
my2 = my1 = w->MouseY;
SetDrMd(rp, JAM2 | COMPLEMENT);
SetAPen(rp, 1L);
DrawRect(rp, mx1, my1, mx2, my2);
do {
if ( mx2 != w->MouseX || my2 != w->MouseY ) {
DrawRect(rp, mx1, my1, mx2, my2);
mx2 = w->MouseX;
my2 = w->MouseY;
DrawRect(rp, mx1, my1, mx2, my2);
}
Wait(1L << w->UserPort->mp_SigBit);
GetMessage(w);
} while ( CLASS != MOUSEBUTTONS || CODE != SELECTUP );
DrawRect(rp, mx1, my1, mx2, my2);
if ( mx1 > mx2 ) {
i = mx1;
mx1 = mx2;
mx2 = i;
}
if ( my1 > my2 ) {
i = my1;
my1 = my2;
my2 = i;
}
ModifyIDCMP(w, NULL);
sprintf(DefBuf_REAL0, "%lf", mx1*dx+rmin);
sprintf(DefBuf_REAL1, "%lf", mx2*dx+rmin);
sprintf(DefBuf_IMAG0, "%lf", my1*dy+imin);
sprintf(DefBuf_IMAG1, "%lf", my2*dy+imin);
DefText_REAL0 = DefBuf_REAL0;
DefText_REAL1 = DefBuf_REAL1;
DefText_IMAG0 = DefBuf_IMAG0;
DefText_IMAG1 = DefBuf_IMAG1;
OpenRW();
}
break;
case GAD_VIEW:
if ( s && w ) {
CloseRW();
memcpy(c_palette, Palette, sizeof(UWORD) * MIN(32, maxcol));
ModifyIDCMP(w, MOUSEBUTTONS | INTUITICKS);
while ( GetMessage(w) != MOUSEBUTTONS ) {
if ( cycle ) {
i = c_palette[MIN(31, maxcol-1)];
movmem(c_palette+1, c_palette+2, sizeof(UWORD) * MIN(30, maxcol-2 ));
c_palette[1] = i;
LoadRGB4(vp, c_palette, MIN(32, maxcol));
Delay(10L);
}
WaitPort(w->UserPort);
}
ModifyIDCMP(w, NULL);
LoadRGB4(vp, Palette, MIN(32,maxcol));
OpenRW();
}
break;
case GAD_PRINT:
if ( s && w ) {
if ( ! OpenPrinter(request) ) {
DumpRPort(request, rp, vp->ColorMap,
vp->Modes, 0, 0, s->Width, s->Height, 0, 0,
SPECIAL_FULLCOLS | SPECIAL_ASPECT);
ClosePrinter(request);
}
}
break;
case GAD_CYCLE:
cycle = CODE;
break;
case GAD_DEFAULT:
if ( w ) CloseWindow(w);
w = NULL;
CloseRW();
if ( s ) CloseScreen(s);
s = NULL;
SetDefault();
OpenRW();
break;
case GAD_TASK:
task = CODE;
if ( task ) {
Permit();
}
else {
Forbid();
}
break;
case GAD_ABOUT:
CloseRW();
EasyRequest(w, &ES1, NULL, NULL);
OpenRW();
break;
case GAD_COLOR:
if ( s ) {
CloseRW();
if ( ! DoColor(Palette, s) ) {
for ( i = 0; i < MIN(32, maxcol); i++ ) {
Palette[i] = GetRGB4(vp->ColorMap, i);
}
}
OpenRW();
}
break;
}
}
} while ( TRUE );
}