[comp.sys.amiga] sc.draco translated to c

grwalter@orchid.UUCP (05/04/87)

[line eater, what line eate...

Below is a translation of the sc.draco (written in draco of course) into c.
It compiles under Lattice 3.10. I didn't do the translation, a friend did,
but I thought others might be interested in this, so I'm posting it for
him.

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

While I'm here, I'll say a few things about the *local* state of the freely
redistributable C compiler originally found on Fish Disk 53.

1) It generates correct Amiga 68k assembler source (that can be assembled
by any assembler that follows the AmigaDOS manual assembler format). There
is also an option to produce assembler source that the Lattice 3.10
assembler will handle.

2) It has been used to successfully compile several small C programs.
ie. It is use-able on small stuff.

3) It's executible is about 70k. (as compared to the reports of 400k to 1.2
meg for GNU C).

4) It ***almost*** compiles itself. By almost I mean that the program that
results from the compiler compiling itself runs, but doesn't produce
correct output.

I've been hunting down the problem, but I am now entering a school term,
and my time will drop to about zip to work on this. Is there someone out
there that :
	a) has a compiler (becuase this compiler won't compile itself yet)
	b) has the desire to see a PD-type C compiler working ?
	c) has the time to help finish porting this to the Amiga ?

If so, send me some email, and I'll see about getting you a copy of the
compiler source.

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

On a related note, what is happening with the port of GNU C to the Amiga ? It
was mentioned a while ago that several people were attempting this feat.
How is it coming ? (ie. if it is almost done ... it doesn't make sense to
have several PD-type C compilers ...)

	fred

 CSNet: grwalter@watmath.waterloo.edu
  UUCP: {ihnp4,decvax,allegra,utzoo}!watmath!grwalter
CDNnet: grwalter@watmath.waterloo.cdn
  ARPA: grwalter%watmath.waterloo.edu@csnet-relay.arpa

-----sc.c----------------------this-is-a-cut-line-virginia---------------
#include "intuition/intuition.h"
#include "libraries/dos.h"

#define FREEPEN (-1)

struct Screen *OpenScreen();
struct Window *OpenWindow();

/*
 * sc.c - fractalish terrain generator.
 *
 *   Date:     March 5, 1987 (original version sometime in 1985)
 *   Author:   Chris Gray
 *   Language: C
 *   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.)
 */

#define SIZE 8
#define COUNT (1 << SIZE)
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
#define SCREEN_DEPTH 5
#define COLOURS (1 << SCREEN_DEPTH)
#define WINDOW_WIDTH (COUNT < SCREEN_WIDTH ? COUNT : SCREEN_WIDTH)
#define WINDOW_HEIGHT (COUNT < SCREEN_HEIGHT ? COUNT : SCREEN_HEIGHT)

unsigned short Range[SIZE] = {32, 32, 32, 22, 14, 8, 4, 2};

unsigned short ColourMap[COLOURS] = {
    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
};

struct Screen *Screen;
struct Window *Window;

unsigned short Seed;

short Cell[COUNT][COUNT];

/*
 * random - return a random number 0 - passed range.
 */

unsigned short random(rang)
unsigned short rang;
{
    if (rang == 0)
        return 0;
    Seed = Seed * 17137 + 4287;
    Seed = (Seed >> 8) ^ (Seed << 8);
    return Seed % rang;
}

/*
 * set - set a given spot in Cell.
 */

void set(l, c, size, height)
unsigned short l, c, size;
short height;
{
    unsigned short rang;

    rang = Range[size];
    height = height + random(rang) - (rang + 1) / 2;
    Cell[l][c] = height;
}

/*
 * grow - grow the basic scenery heights.
 */

void grow()
{
    unsigned short l, c, i, step, nextStep, l1, l2, c1, c2;

    Cell[0][0] = 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] + 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);
                }
            }
        step = nextStep;
        }
}

/*
 * display - display the resulting scenery.
 */

void display()
{
    unsigned short l, c;
    short height;

    for (l=0; l<WINDOW_HEIGHT; l++)
        {
        for (c=0; c<WINDOW_WIDTH; c++)
            {
            height = Cell[l][c];
            SetAPen(Window->RPort,
                    height<0 ?
                        0
                    : (height>=COLOURS ?
                        COLOURS-1
                    : height));
            WritePixel(Window->RPort, c, l);
            }
        }
}

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
/*
 * main program.
 */

void main()
{
    static struct NewWindow newWindow =
            {
            0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
            FREEPEN, FREEPEN,
            0x0, BORDERLESS | ACTIVATE | NOCAREREFRESH,
            NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
            CUSTOMSCREEN
            };

    static struct NewScreen newScreen =
          {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0, 1,
          0x0, CUSTOMSCREEN, NULL, NULL, NULL, NULL};
    struct DateStamp ds;
    static struct IntuiText bodyText =
        {COLOURS - 1, 0, 0, 51, 5, NULL, NULL, NULL};
    static struct IntuiText positiveText =
        {COLOURS - 1, 0, 0, 7, 3, NULL, NULL, NULL};
    static struct IntuiText negativeText =
        {COLOURS - 1, 0, 0, 7, 3, NULL, NULL, NULL};

    bodyText.IText = "Done";
    positiveText.IText = "Next";
    negativeText.IText = "Quit";
    IntuitionBase = (struct IntuitionBase *)
                    OpenLibrary("intuition.library", 0);
    if (IntuitionBase != NULL)
        {
        GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
        if (GfxBase != NULL)
            {
                Screen = OpenScreen(&newScreen);
                if (Screen != NULL)
                    {
                    LoadRGB4(&Screen->ViewPort, ColourMap, COLOURS);
                    newWindow.Screen = Screen;
                    Window = OpenWindow(&newWindow);
                    if (Window != NULL)
                        {
                        DateStamp(&ds);
                        Seed = (ds.ds_Minute ^ ds.ds_Tick) | 1;
                        do
                            {
                            grow();
                            display();
                            }
                        while (AutoRequest(Window, &bodyText, &positiveText,
                               &negativeText, 0x0, 0x0, 150, 50));
                        CloseWindow(Window);
                        }
                    CloseScreen(Screen);
                    }
            CloseLibrary(IntuitionBase);
            }
        CloseLibrary(GfxBase);
        }
}