home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
038.lha
/
sc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-05-16
|
5KB
|
198 lines
#include:intuition/miscellaneous.g
#include:intuition/screen.g
#include:intuition/window.g
#include:intuition/intuitext.g
#include:intuition/requester.g
#include:graphics/gfx.g
#include:graphics/view.g
#include:graphics/rastport.g
#include:libraries/dos.g
/*
* sc.d - fractalish terrain generator.
*
* Date: March 5, 1987 (original version sometime in 1985)
* Author: Chris Gray
* Language: Draco
* System: Amiga
*/
/*
* The nature of the terrain can be changed by playing with the numbers
* in 'Range'. If you change SIZE, you must also change the number of
* values given for 'Range'. The created terrain with SIZE = 8 is 256 pixels
* by 256 pixels, which doesn't fit on a non-interlaced screen, so only the
* top 200 pixels are displayed. The terrain is a torus, i.e. wraps around
* both vertically and horizontally.
*/
/*
* Feel free to use this algorithm in any games you write, so long as you
* give me credit for it. (I THINK I invented it, since I've never heard of
* anything similar, and other programs I've seen use much slower methods.)
*/
uint
SIZE = 8,
COUNT = 1 << SIZE,
SCREEN_WIDTH = 320,
SCREEN_HEIGHT = 200,
SCREEN_DEPTH = 5,
COLOURS = 1 << SCREEN_DEPTH,
WINDOW_WIDTH = if COUNT < SCREEN_WIDTH then COUNT else SCREEN_WIDTH fi,
WINDOW_HEIGHT = if COUNT < SCREEN_HEIGHT then COUNT else SCREEN_HEIGHT fi;
[SIZE] uint Range = (32, 32, 32, 22, 14, 8, 4, 2);
[COLOURS] uint ColourMap = (
0x00f, 0x050, 0x070, 0x0a0, 0x0c0, 0x0e0, 0x4f4, 0x8f8,
0xdf0, 0xff0, 0xfd0, 0xfb0, 0xf90, 0xf70, 0xe50, 0xe33,
0xe11, 0xf01, 0xf03, 0xf05, 0xf07, 0xf09, 0xf0b, 0xf0d,
0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff
);
*Screen_t Screen;
*Window_t Window;
uint Seed;
[COUNT, COUNT] int Cell;
/*
* random - return a random number 0 - passed range.
*/
proc random(uint rang)uint:
if rang = 0 then
0
else
Seed := Seed * 17137 + 4287;
Seed := (Seed >> 8) >< (Seed << 8);
Seed % rang
fi
corp;
/*
* set - set a given spot in Cell.
*/
proc set(uint l, c, size; int height)void:
uint rang;
rang := Range[size];
height := height + random(rang) - (rang + 1) / 2;
Cell[l, c] := height;
corp;
/*
* grow - grow the basic scenery heights.
*/
proc grow()void:
uint l, c, i, step, nextStep, l1, l2, c1, c2;
Cell[0, 0] := 0;
step := COUNT;
for i from 0 upto SIZE - 1 do
nextStep := step / 2;
for l from 0 by step upto COUNT - 1 do
l1 := l + nextStep;
l2 := l + step;
if l2 = COUNT then
l2 := 0;
fi;
for c from 0 by step upto COUNT - 1 do
c1 := c + nextStep;
c2 := c + step;
if c2 = COUNT then
c2 := 0;
fi;
set(l, c1, i, (Cell[l, c] + Cell[l, c2] + 1) / 2);
set(l1, c, i, (Cell[l, c] + Cell[l2, c] + 1) / 2);
set(l1, c1, i, (Cell[l, c] + Cell[l, c2] +
Cell[l2, c] + Cell[l2, c2] + 2) / 4);
od;
od;
step := nextStep;
od;
corp;
/*
* display - display the resulting scenery.
*/
proc display()void:
uint l, c;
int height;
for l from 0 upto WINDOW_HEIGHT - 1 do
for c from 0 upto WINDOW_WIDTH - 1 do
height := Cell[l, c];
SetAPen(Window*.w_RPort,
if height < 0 then
0
elif height >= COLOURS then
COLOURS - 1
else
height
fi);
pretend(WritePixel(Window*.w_RPort, c, l), void);
od;
od;
corp;
/*
* main program.
*/
proc main()void:
NewWindow_t newWindow;
DateStamp_t ds;
IntuiText_t bodyText, positiveText, negativeText;
bodyText := IntuiText_t(COLOURS - 1, 0, 0, 51, 5, nil, nil, nil);
bodyText.it_IText := "Done";
positiveText := IntuiText_t(COLOURS - 1, 0, 0, 7, 3, nil, nil, nil);
positiveText.it_IText := "Next";
negativeText := IntuiText_t(COLOURS - 1, 0, 0, 7, 3, nil, nil, nil);
negativeText.it_IText := "Quit";
if OpenIntuitionLibrary(0) ~= nil then
if OpenGraphicsLibrary(0) ~= nil then
if OpenDosLibrary(0) ~= nil then
Screen := OpenScreen(&NewScreen_t(
0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0, 1,
0x0, CUSTOMSCREEN, nil, nil, nil, nil));
if Screen ~= nil then
LoadRGB4(&Screen*.sc_ViewPort, &ColourMap[0], COLOURS);
newWindow := NewWindow_t(
0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
FREEPEN, FREEPEN,
0x0, BORDERLESS | ACTIVATE | NOCAREREFRESH,
nil, nil, nil, nil, nil, 0, 0, 0, 0,
CUSTOMSCREEN);
newWindow.nw_Screen := Screen;
Window := OpenWindow(&newWindow);
if Window ~= nil then
DateStamp(&ds);
Seed := (ds.ds_Minute >< ds.ds_Tick) | 1;
while
grow();
display();
AutoRequest(Window, &bodyText, &positiveText,
&negativeText, 0x0, 0x0, 150, 50)
do
od;
CloseWindow(Window);
fi;
CloseScreen(Screen);
fi;
CloseDosLibrary();
fi;
CloseGraphicsLibrary();
fi;
CloseIntuitionLibrary();
fi;
corp;