home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d161
/
lgz
/
lgz.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-02
|
21KB
|
860 lines
/*Let's Get Ziviliced!
- a terrain generator & editor for the game LGZ.
by Malik Hyldtoft (who made the game)
& Lars R. Clausen (who is writing the program)
The terrain generator algoritm is from Chris Gray's Terrain, thanks, Chris.
Filerequester from Peter Da Silva, thanks. For further notes on
the requester, see STDFile.c */
/*Data.pre includes all*/
void *OpenLibrary();
void *OpenScreen();
int errno;
struct bufferstruct {
int heigth,growth;
};
/*
** It starts with OpenThings(), after that I initialize colors,
** draw etc.
** It closes with CloseThings() and exit(0).
** Thanks go to P.S.Kivolowitz for making a simple program we
** could learn and steal screen and window structures from.
*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct DOSBase *DOSBase;
int is_cli = 0;
struct Window *w; /* window structure returned by exec */
/*
** mask is a bit mask of things that I should close or deallocate
** when the program terminates for any reason. after opening or
** allocating some resource set the appropriate bit in mask.
*/
unsigned int mask = 0;
#define INTUITION 0x00000001
#define GRAPHICS 0x00000002
#define SCREEN 0x00000004
#define WINDOW 0x00000008
#define DOSBASE 0x00000010
OpenThings(argc) /* Open libraries, screen, window etc. */
{
if (argc) is_cli = 1;
if (!(GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library",0L)))
{
if (is_cli) printf("no graphics library!!!\n");
CloseThings();
exit(1);
}
mask |= GRAPHICS;
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0L)))
{
if (is_cli) printf("no intuition here!!\n");
CloseThings();
exit(1);
}
mask |= INTUITION;
if (!(DOSBase = (struct DOSBase *)
OpenLibrary("dos.library", 0L)))
{
if (is_cli) printf("DOS closed for now...\n");
CloseThings();
exit(2);
}
mask |= DOSBASE;
if (!(GfxBase->DisplayFlags & PAL)) ns.ViewModes |= LACE;
if ((stdscreen = (struct Screen *)
OpenScreen(&ns)) == (struct Screen *) NULL)
{
if (is_cli) printf("could not open the screen!\n");
CloseThings();
exit(3);
}
mask |= SCREEN;
nw.Screen = stdscreen;
if ((w = (struct Window *)
OpenWindow(&nw)) == (struct Window *) NULL)
{
if (is_cli) printf("could not open the window!\n");
CloseThings();
exit(4);
}
mask |= WINDOW;
SetMenuStrip(w,MyMenu);
ShowTitle(stdscreen,FALSE);
MySetDMRequester();
}
CloseThings() /* Closes all the stuff opened above */
{
if (w) ClearMenuStrip(w);
if (w) ClearDMRequest(w);
if (mask & WINDOW) CloseWindow(w);
if (mask & SCREEN) CloseScreen(stdscreen);
if (mask & DOSBASE) CloseLibrary(DOSBase);
if (mask & GRAPHICS) CloseLibrary(GfxBase);
/*OpenWorkBench();*/
if (mask & INTUITION) CloseLibrary(IntuitionBase);
}
Abort() /* Get the hell out of here */
{
CloseThings();
exit(100);
}
InitColorMap() /* Stolen from Kivolowitz */
{
static short map_values[NMAP] = {
/* 0-3 */ 0x000A , 0x0FFF , 0x0000 , 0x0EC1 ,
/* 4-7 */ 0x0F12 , 0x000C , 0x0050 , 0x0060 ,
/* 8-11 */ 0x0070 , 0x0080 , 0x0090 , 0x00A0 ,
/* 12-15 */ 0x00B0 , 0x00C0 , 0x00D0 , 0x0FB1 ,
/* 16-19 */ 0x0D80 , 0x0C80 , 0x0C70 , 0x0B70 ,
/* 20-23 */ 0x0A70 , 0x0A60 , 0x0960 , 0x0850 ,
/* 24-27 */ 0x0777 , 0x0888 , 0x0999 , 0x0AAA ,
/* 28-31 */ 0x0BBB , 0x0CCC , 0x0DDD , 0x0EEE
};
LoadRGB4(&stdscreen->ViewPort , map_values , (long)NMAP);
}
#define SIZE 6
#define COUNT 1 << SIZE
#define COLOURS 32
/* These values for reference only, the real thing in DMReq */
int GRange[6] = {64,32,16,6,3,1}; /* Parameters for growth */
int HRange[6] = {64,32,16,6,3,1}; /* Parameters for height */
short Cell[COUNT][COUNT][2];
int VegOnOff = 1;
set(l,c,size,height,nr) /* Set a single cell */
unsigned int l,c,size,nr;
int height;
{
unsigned int rang;
if (nr == 0) rang = HRange[size];
else rang = GRange[size];
height += rand()/(32767/rang) - (rang+1)/2;
Cell[l][c][nr] = height;
}
Grow(nr) /* Grow the terrain, either for height or for vegetation */
int nr;
{
unsigned int step,nextstep,l1,l2,c1 = 0;
register unsigned int l,c,i,c2 = 0;
/* User may have entered new HRange/GRange values from DMReq */
for (i=0; i<6; i++) {
HRange[i] = IntGadgetStuff[i].LongInt;
GRange[i] = IntGadgetStuff[i+6].LongInt;
}
Cell[0][0][nr] = 0;
step = COUNT;
for (i=0; i<SIZE; i++)
{
nextstep = step / 2;
for (l=0; l<COUNT; l+=step)
{
l1 = l+nextstep;
l2 = l+step;
if (l2 == COUNT) l2 = 0;
for (c=0; c<COUNT; c+=step)
{
c1 = c+nextstep;
c2 = c+step;
if (c2 == COUNT) c2 = 0;
set(l,c1,i,(Cell[l][c][nr]+Cell[l][c2][nr])/2,nr);
set(l1,c,i,(Cell[l][c][nr]+Cell[l2][c2][nr])/2,nr);
set(l1,c1,i,(Cell[l][c][nr]+Cell[l][c2][nr]+
Cell[l2][c][nr]+Cell[l2][c2][nr])/4,nr);
}
}
step = nextstep;
}
}
DrawMap() /* Draw it */
{
register long x,y,h,g = 0;
for (x=0; x<COUNT; x++)
for (y=0; y<COUNT; y++)
{
h = Cell[x][y][0];
g = Cell[x][y][1];
if (h<5)
h = 5;
else
if (h >= COLOURS)
h = COLOURS-1;
SetAPen(w->RPort,h);
RectFill(w->RPort,x*4,y*3+10,x*4+3,y*3+12);
if ((Cell[x][y][0]>5) && (Cell[x][y][0]<15) && (VegOnOff == TRUE))
{
SetAPen(w->RPort,15L);
if ((g>-10) && (g<13))
{
WritePixel(w->RPort,x*4+1,y*3+11);
WritePixel(w->RPort,x*4+2,y*3+11);
}
else
if (g<=-10)
RectFill(w->RPort,x*4+1,y*3+10,x*4+2,y*3+12);
}
}
}
LoadMap() /* Load formerly saved maps */
{
FILE *fp,*fopen();
char filename[MAXFILENAME];
int error=1;
if (stdfile("Load Map","df1:LGZ/LGZ.map",NULL,filename)==1)
{
if ((fp = fopen(filename,"r")) == NULL)
printf("Couldn't open %s\n",filename);
else
{
error=fread(&Cell[0][0][0],16384,1,fp);
if (error == 0)
{
printf("Error in reading map from file\n");
if feof(fp) printf("Unexpected end of file.\n");
else printf("Error number: %d\n",errno);
}
fclose(fp);
}
}
}
SaveMap() /* Save the map */
{
FILE *fp,*fopen();
char filename[30];
int error=1l;
if (stdfile("Save Map","df1:LGZ/",NULL,filename)==1)
{
if ((fp = fopen(filename,"w")) == NULL)
printf("Couldn't open %s\n",filename);
else
{
error=fwrite(&Cell[0][0][0],16384,1,fp);
if (error == 0)
{
printf("Error in writing map to file\n");
printf("Error number: %d\n",errno);
}
else
printf("File written!\n");
fclose(fp);
}
}
}
int ProjectHandler(n) /* Handle the Project menu */
USHORT n;
{
int x,y = 0;
switch(ITEMNUM(n))
{
case 0: { /* Clear */
if (AutoRequest(w,&ClearText,&YesText,&NoText,NULL,NULL,200L,60L)==TRUE)
{
ClearTerrain();
SetAPen(w->RPort,5L);
RectFill(w->RPort,0L,10L,256L,240L);
}
break;
}
case 1: { /* Open */
LoadMap();
DrawMap();
break;
}
case 2: { /* Save */
SaveMap();
break;
}
case 3: { /* Info */
break;
}
case 4: { /* Quit */
if (AutoRequest(w,&QuitText,&YesText,&NoText,NULL,NULL,200L,60L)==TRUE)
{
CloseThings();
exit(0);
}
}
}
}
ClearTerrain() /* Clear it all */
{
register int x,y;
for (x=0; x<COUNT; x++)
for (y=0; y<COUNT; y++)
Cell[x][y][0] = Cell[x][y][1] = 0;
}
EditHandler(n) /* Handle the Edit menu */
USHORT n;
{
switch (ITEMNUM(n))
{
case 0: /* Edit pixels */
{
Edit();
break;
}
case 1: /* Sink map */
{
Sink();
DrawMap();
break;
}
case 2: /* Lift map */
{
Lift();
DrawMap();
break;
}
case 3: /* Compress map ( divide by two, idea from Bjarne Fich) */
{
Compress();
DrawMap();
break;
}
case 4: /* Scroll Map */
{
ScrollHandler(n);
break;
}
}
}
Edit() /* Edit pixelwise */
{
long x=0,type=2,height=7,a=0,b=0,hg=0,ac,bc,h,g,outflag=0;
struct Gadget *numgad;
struct IntuiMessage *msg;
struct RastPort *rp;
rp = w->RPort;
SetAPen(rp,1L);
RectFill(rp,279L,29L,291L,166L);
for (x=5; x<COLOURS; x++)
{
SetAPen(rp,x);
RectFill(rp,280L,(36-x)*5+5,290L,(36-x)*5+10);
}
RemoveGadget(w,&ReadyGadget);
AddGadget(w,&ExitGadget,-1);
AddGadget(w,&WoodsGadget,-1);
AddGadget(w,&DesertGadget,-1);
AddGadget(w,&PlainsGadget,-1);
AddGadget(w,&MapGad,-1);
RefreshGadgets(&ExitGadget,w,NULL);
do
{
WaitPort(w->UserPort);
msg = (struct IntuiMessage *) GetMsg(w->UserPort);
if (((msg->Class == MOUSEBUTTONS) && (msg->Code == SELECTDOWN)) ||
(msg->Class == GADGETDOWN) || ((msg->Class == MOUSEMOVE) &&
(msg->MouseX<257)))
{
a = msg->MouseX; b = msg->MouseY;
if ((a > 279) && (a < 291) &&
(b > 30) && (b < 166))
{
DrawBorder(rp,&TypeOffBorder,70*type+17,208L);
SetAPen(rp,1L);
RectFill(rp,279L,29L,291L,166L);
for (x=5; x<COLOURS; x++)
{
SetAPen(rp,x);
RectFill(rp,280L,(36-x)*5+5,290L,(36-x)*5+10);
}
height = 37-((b-1)/5);
hg = 0L;
DrawBorder(rp,&ColBorder,279L,(36-height)*5+5);
}
if ((a < 256L) && (b>9L) && (b<201L))
{
ac = a/4; bc = (b-9)/3;
if (hg<1L)
Cell[ac][bc][0] = height;
else
Cell[ac][bc][1] = (2-type)*30;
g = Cell[ac][bc][1]; h = Cell[ac][bc][0];
if (h>31) h = 31;
if (h<5) h = 5;
SetAPen(rp,h);
RectFill(w->RPort,ac*4,bc*3+10,ac*4+3,bc*3+12);
if ((h>5L) && (h<15L) && (VegOnOff = TRUE))
{
SetAPen(rp,15L);
if ((g>-10) && (g<13))
{
WritePixel(rp,ac*4+1,bc*3+11);
WritePixel(rp,ac*4+2,bc*3+11);
}
else
if (g<=-10)
RectFill(rp,ac*4+1,bc*3+10,ac*4+2,bc*3+12);
}
}
if ((msg->Class == GADGETDOWN) && (a>256L))
{
numgad = msg->IAddress;
type = numgad->UserData;
if (type < 4)
{
if (type!=1) WoodsGadget.Flags&=0xFF7F;
else WoodsGadget.Flags|=0x0080;
if (type!=2) PlainsGadget.Flags&=0xFF7F;
else PlainsGadget.Flags|=0x0080;
if (type!=3) DesertGadget.Flags&=0xFF7F;
else DesertGadget.Flags|=0x0080;
RefreshGadgets(&ExitGadget,w,NULL);
SetAPen(rp,1L);
RectFill(rp,279L,29L,291L,166L);
for (x=5; x<COLOURS; x++)
{
SetAPen(rp,x);
RectFill(rp,280L,(36-x)*5+5,290L,(36-x)*5+10);
}
if (VegOnOff == 0)
{
VegOnOff = 1;
DrawMap();
}
hg = 1;
}
if (type == 4)
outflag = 1;
}
ReplyMsg(msg);
}
}
while (outflag == 0);
RemoveGadget(w,&ExitGadget);
RemoveGadget(w,&WoodsGadget);
RemoveGadget(w,&PlainsGadget);
RemoveGadget(w,&DesertGadget);
RemoveGadget(w,&MapGad);
SetAPen(rp,0L);
RectFill(rp,259L,29L,320L,226L);
AddGadget(w,&ReadyGadget,-1);
}
Sink() /* Sink Map */
{
register int x,y = 0;
for (x=0; x<COUNT; x++)
for (y=0; y<COUNT; y++)
Cell[x][y][0]--;
}
Lift() /* Lift Map */
{
register int x,y = 0;
for (x=0; x<COUNT; x++)
for (y=0; y<COUNT; y++)
Cell[x][y][0]++;
}
Compress() /* Compress map */
{
register int x,y =0;
for (x=0; x<COUNT; x++)
for (y=0; y<COUNT; y++)
Cell[x][y][0] = (Cell[x][y][0]-6)/2+6;
}
ScrollHandler(n) /* Handle scroll submenuitems */
USHORT n;
{
register int x,y,th,tg =0;
#define SCOUNT 64
switch (SUBNUM(n))
{
case 0:/*Up*/
{
for (x=0; x<SCOUNT; x++)
{
th = Cell[x][0][0];
tg = Cell[x][0][1];
for (y=0; y<SCOUNT-1; y++)
{
Cell[x][y][0] = Cell[x][y+1][0];
Cell[x][y][1] = Cell[x][y+1][1];
}
Cell[x][SCOUNT-1][0] = th;
Cell[x][SCOUNT-1][1] = tg;
}
ScrollRaster(w->RPort,0L,3L,0L,10L,255L,201L);
DrawMapLine(1,1);
break;
}
case 1:/*Down*/
{
for (x=0; x<SCOUNT; x++)
{
th = Cell[x][SCOUNT-1][0];
tg = Cell[x][SCOUNT-1][1];
for (y=SCOUNT-1; y>0; y--)
{
Cell[x][y][0] = Cell[x][y-1][0];
Cell[x][y][1] = Cell[x][y-1][1];
}
Cell[x][0][0] = th;
Cell[x][0][1] = tg;
}
ScrollRaster(w->RPort,0L,-3L,0L,10L,255L,201L);
DrawMapLine(1,0);
break;
}
case 2:/*Left*/
{
for (x=0; x<SCOUNT; x++)
{
th = Cell[0][x][0];
tg = Cell[0][x][1];
for (y=0; y<SCOUNT-1; y++)
{
Cell[y][x][0] = Cell[y+1][x][0];
Cell[y][x][1] = Cell[y+1][x][1];
}
Cell[SCOUNT-1][x][0] = th;
Cell[SCOUNT-1][x][1] = tg;
}
ScrollRaster(w->RPort,4L,0L,0L,10L,255L,201L);
DrawMapLine(0,1);
break;
}
case 3:/*Right*/
{
for (x=0; x<SCOUNT; x++)
{
th = Cell[SCOUNT-1][x][0];
tg = Cell[SCOUNT-1][x][1];
for (y=SCOUNT-1; y>0; y--)
{
Cell[y][x][0] = Cell[y-1][x][0];
Cell[y][x][1] = Cell[y-1][x][1];
}
Cell[0][x][0] = th;
Cell[0][x][1] = tg;
}
ScrollRaster(w->RPort,-4L,0L,0L,10L,255L,201L);
DrawMapLine(0,0);
break;
}
}
}
DrawMapLine(way,nr) /* Used by scroll */
int way,nr;
{
register long x,y,h,g = 0;
if (way==0)
{
x = 63*nr;
for (y=0; y<COUNT; y++)
{
h = Cell[x][y][0];
g = Cell[x][y][1];
if (h<5)
h = 5;
else
if (h >= COLOURS)
h = COLOURS-1;
SetAPen(w->RPort,h);
RectFill(w->RPort,x*4,y*3+10,x*4+3,y*3+12);
if ((Cell[x][y][0]>5) && (Cell[x][y][0]<15) && (VegOnOff = TRUE))
{
SetAPen(w->RPort,15L);
if ((g>-10) && (g<13))
{
WritePixel(w->RPort,x*4+1,y*3+11);
WritePixel(w->RPort,x*4+2,y*3+11);
}
else
if (g<=-10)
RectFill(w->RPort,x*4+1,y*3+10,x*4+2,y*3+12);
}
}
}
else
{
y = 63*nr;
for (x=0; x<COUNT; x++)
{
h = Cell[x][y][0];
g = Cell[x][y][1];
if (h<5)
h = 5;
else
if (h >= COLOURS)
h = COLOURS-1;
SetAPen(w->RPort,h);
RectFill(w->RPort,x*4,y*3+10,x*4+3,y*3+12);
if ((Cell[x][y][0]>5) && (Cell[x][y][0]<15) && (VegOnOff == TRUE))
{
SetAPen(w->RPort,15L);
if ((g>-10) && (g<13))
{
WritePixel(w->RPort,x*4+1,y*3+11);
WritePixel(w->RPort,x*4+2,y*3+11);
}
else
if (g<=-10)
RectFill(w->RPort,x*4+1,y*3+10,x*4+2,y*3+12);
}
}
}
}
NewMapHandler(n) /* Handle NewMap menu */
USHORT n;
{
switch (ITEMNUM(n))
{
case 0: /* Grow Height, Growth or both */
{
GrowHandler(n);
DrawMap();
break;
}
case 1: /* On/Off Vegetation */
{
VegOnOff = !(VegOnOff);
DrawMap();
break;
}
case 2: /* Change growth parameters - now with requester */
{
ChangePara();
break;
}
case 3: /* Make terrain more smooth - also from Bjarne Fich */
/* Doesn't work yet */
{
LevelItOut();
break;
}
case 4: /* 3-dimesional map - not implemented yet */
{
Draw3DMap();
DrawMap();
break;
}
}
}
GrowHandler(nr) /* Grow submenuitems */
int nr;
{
switch (SUBNUM(nr))
{
case 0: /* Both */
{
Grow(0);
Grow(1);
break;
}
case 1: /* Height */
{
Grow(0);
break;
}
case 2: /* Growth */
{
Grow(1);
VegOnOff = TRUE;
break;
}
}
}
MySetDMRequester()
{
InitRequester(&DMReq);
DMReq.LeftEdge = 50;
DMReq.TopEdge = 30;
DMReq.Width = 150;
DMReq.Height = 130;
DMReq.RelLeft = -50;
DMReq.RelTop = -50;
DMReq.ReqGadget = &DMIntGadget[11]; /* All done */
DMReq.ReqText = &DMReqText; /* Current Parameters */
DMReq.BackFill = 3; /* To be adjusted */
DMReq.ReqBorder = &DMReqBorder;
DMReq.Flags |= POINTREL;
SetDMRequest(w,&DMReq);
}
ChangePara()
{
int i;
Request(&DMReq,w);
WaitPort(w->UserPort);
/* Seems Intuition does not keep the LongInt variabla ?!?!? */
for (i=0; i<12; i++) IntGadgetStuff[i].LongInt = atoi(DMBuffer[i]);
/* Here needs to enter some code to distinguish
'USE' and 'Cancel!' Gadget in DMReq */
}
LevelItOut()
{
register long x,y,z;
long px,mx,py,my;
short TCell[COUNT][COUNT];
for (x=0;x<COUNT;x++)
{
for (y=0;y<COUNT;y++)
{
px=x+1;
if (px>=COUNT) px=0;
mx=x-1;
if (mx<0) mx=COUNT-1;
py=y+1;
if (py>=COUNT) py=0;
my=y-1;
if (my<0) my=COUNT-1;
z=Cell[mx][my][0];
z+=Cell[mx][py][0];
z+=Cell[px][my][0];
z+=Cell[px][py][0];
z+=Cell[mx][y][0]*2;
z+=Cell[x][my][0]*2;
z+=Cell[px][y][0]*2;
z+=Cell[x][py][0]*2;
z+=Cell[x][y][0]*8;
TCell[x][y]=(z+10)/20;
}
}
for (x=0;x<COUNT;x++)
{
for (y=0;y<COUNT;y++)
{
Cell[x][y][0]=TCell[x][y];
printf("%d,%d,%d,%d\n",x,y,Cell[x][y][0],TCell[x][y]);
}
}
DrawMap();
}
Draw3DMap() /* To be made - real soon now */
{
}
MenuHandler(number) /* Greater Menuhandler */
USHORT number;
{
if (number != MENUNULL){
switch(MENUNUM(number)){
case 0: {
ProjectHandler(number);
break;
}
case 1: {
EditHandler(number);
break;
}
case 2: {
NewMapHandler(number);
break;
}
default: printf("Error in menu selection. Please debug!\n");
}
}
}
main(argc)
{
ULONG seconds,micros;
struct IntuiMessage *msg;
int x,y;
OpenThings(argc);
InitColorMap();
SetAPen(w->RPort,0L);
RectFill(w->RPort,259L,9L,310L,20L);
CurrentTime(&seconds,µs);
srand(seconds);
Grow(0);
Grow(1);
DrawMap();
RefreshGadgets(&ReadyGadget,w,NULL);
for (;;)
{
WaitPort(w->UserPort);
msg = (struct IntuiMessage *) GetMsg(w->UserPort);
if (msg != NULL)
switch (msg->Class)
{
case MENUPICK :
{
SetAPen(w->RPort,0L);
RectFill(w->RPort,259L,9L,310L,20L);
MenuHandler(msg->Code);
RefreshGadgets(&ReadyGadget,w,NULL);
break;
}
case CLOSEWINDOW :
{
if (AutoRequest(w,&QuitText,&YesText,&NoText,
NULL,NULL,200L,60L)==TRUE) {
printf("We're closing now. Goodbye (wave hands)\n");
CloseThings();
exit(0); /* The way out */
}
else break;
}
case GADGETDOWN :
{ /* Only thing needed yet is to recognize the Cancel! gadget */
for (x=0; x<12; x++)
IntGadgetStuff[x].LongInt = atoi(DMBuffer[x]);
break;
}
case MOUSEBUTTONS :
{
break;
}
}
}
if (0 == 1) Abort(); /* Just to confuse - never gets here */
}