home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
274.lha
/
SimGen_Src
/
simgen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-26
|
13KB
|
578 lines
/****************************************************************************
* These include files define many system equates, structures, and data types
****************************************************************************/
#include <exec/types.h> /* Data Type like UBYTE, ULONG, ... */
#include <exec/memory.h> /* Memory Types like MEMF_CHIP, ... */
#include <exec/libraries.h> /* Base Amiga Library Structures */
#include <graphics/gfxmacros.h> /* Graphics Macros (IE. ON_DISPLAY) */
#include <graphics/sprite.h> /* Sprite Stuctures */
#include <graphics/gfxbase.h> /* Graphics Library Stuctures */
#include <libraries/dos.h> /* AmigaDOS structures */
#include <libraries/dosextens.h> /* more AmigaDOS structures */
#include <intuition/intuition.h> /* Intuition Stuctures (Windows...) */
#include <intuition/intuitionbase.h> /* Intuition Library Stuctures */
#include <workbench/startup.h> /* WorkBench "Startup" structures */
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <iff/readpict.h>
#include <functions.h> /* All function return types */
#include <stdio.h> /* Standard 'C' I/O data types */
#include <ctype.h>
/****************************************************************************
* These includes are for this program and also "packages" I have written
****************************************************************************/
#include "picture.h" /* my IFF shape structures */
#include "rectcopy.h" /* my Pic/Shape drawing routines */
char *PreFix = ""; /* Pointer to path string for all
data files for program */
struct IntuitionBase *IntuitionBase = 0; /* Pntr to Intuition Routines */
struct GfxBase *GfxBase = 0; /* Pntr to Graphics Routines */
extern struct WBStartup *WBenchMsg;
extern struct Library *IconBase;
extern char *index ();
/* Global graphics variables
************************************************************************
*/
struct Window *MainWindow = NULL;
struct Screen *WScreen = NULL;
struct BitMap *WBitMap = NULL;
struct BitMap MyBitMap;
struct FileLock *oldlock = NULL;
struct MsgPort *SPort = NULL;
struct MsgPort *SRPort = NULL;
Picture *BackPic = NULL;
UWORD OldColors[16];
int FromCLI = FALSE;
int Tile = FALSE;
int WorkBench = FALSE;
int KeepColors = FALSE;
int TileXOff = 0;
int TileYOff = 0;
extern struct NewWindow NewWindow;
extern int Message();
/*
** AboutToLoadBody ************************************************************
**
** Tells IFF routines where to load Picture.
*/
AboutToLoadBody (ilbmframe)
ILBMFrame *ilbmframe;
{
NewImage *ni = ilbmframe->ni;
int pos;
if (!Tile) {
/*
** Load Picture in center of screen
*/
ni->Left = (ni->Width >> 1) - (ilbmframe->bmHdr.w >> 1);
if (ni->Left < 0) {
ni->FLeft = -ni->Left;
ni->Left = 0;
}
ni->Top = (ni->Height >> 1) - (ilbmframe->bmHdr.h >> 1);
if (ni->Top < 0) {
ni->FTop = -ni->Top;
ni->Top = 0;
}
} else {
/*
** Tile Picture at users offset.
*/
ni->Left = TileXOff;
ni->Top = TileYOff;
}
}
/*
** ShutDownOld ******************************************************
**
** Checks for and shuts down other instances of SimGen.
*/
char portname[] = "SimGen_Close_Port";
ShutDownOld ()
{
struct MsgPort *port;
struct Message *msg;
while (port = FindPort (portname)) {
msg = GetMsg (port);
if (msg) {
ReplyMsg (msg);
}
Delay (30);
}
}
/*
** Initialize *****************************************************************
**
** This Routine intializes most of the stuff needed for the game
*/
void Initialize (name)
char *name;
{
UWORD *wcolors;
int i, j;
int x, y, ox;
if (!( SPort = CreatePort (portname, 0)))
Quit ("Couldn't create message port");
if (!( SRPort = CreatePort (NULL, 0)))
Quit ("Couldn't create reply port");
if (!( GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L)))
Quit ("Couldn't open graphics library");
if (!( MainWindow = OpenWindow (&NewWindow)))
Quit ("Couldn't open MainWindow");
WScreen = MainWindow->WScreen;
WBitMap = WScreen->ViewPort.RasInfo->BitMap;
if (!( BackPic = CreatePic (name, WScreen->Width, WScreen->Height)))
Quit2 ("Couldn't open ", name);
/*
** If tiling was requested then tile it.
*/
if (Tile) {
/*
** Set Cliping Area for Drawing Routines.
*/
ClipLeft = 0;
ClipTop = 0;
ClipWidth = WScreen->Width;
ClipHeight = WScreen->Height;
/* Find First "Grid" XPos before left edge */
ox = PicHotX(BackPic);
while (ox > 0) {
ox -= PicWidth (BackPic);
}
/* Find First "Grid" YPos before right edge */
y = PicHotY(BackPic);
while (y > 0) {
y -= PicHeight (BackPic);
}
/*
** Now copy image in grid until entire screen is covered.
*/
do {
x = ox;
do {
RectCopy (&BackPic->RastPort,
PicHotX (BackPic),
PicHotY (BackPic),
&BackPic->RastPort,
x, y,
PicWidth (BackPic),
PicHeight (BackPic));
x += PicWidth (BackPic);
} while (x < WScreen->Width);
y += PicHeight (BackPic);
} while (y < WScreen->Height);
}
MyBitMap = *WBitMap;
MyBitMap.Depth = 2 + PicDepth(BackPic);
MyBitMap.Planes[2] = BackPic->BitMap.Planes[0];
MyBitMap.Planes[3] = BackPic->BitMap.Planes[1];
WScreen->ViewPort.RasInfo->BitMap = &MyBitMap;
wcolors = (UWORD *)WScreen->ViewPort.ColorMap->ColorTable;
for (j = 0; j < 15; j++) {
OldColors[j] = wcolors[j];
}
for (j = 1; j < 4; j++) {
for (i = 1; i < 4; i++) {
wcolors[j * 4 + i] = wcolors[i];
}
}
for (j = 0; j < 4; j++) {
wcolors[j * 4] = PicColorMap(BackPic)[j];
}
LoadRGB4 (&WScreen->ViewPort, wcolors, 16);
RemakeDisplay ();
CloseWindow (MainWindow);
MainWindow = NULL;
}
MyClosePort (mp)
struct MsgPort *mp;
{
struct Message *msg;
Forbid ();
while (msg = GetMsg (mp));
DeletePort (mp);
Permit ();
}
/*
** Quit2 *********************************************************************
*/
Quit2 (mess1, mess2)
char *mess1, *mess2;
{
char mess[250];
strcpy (mess, mess1);
strcat (mess, mess2);
Quit (mess);
}
/*
** Quit *********************************************************************
**
** This routine deallocates all used resources and then exits the program
*/
Quit (message)
char *message;
{
int i;
if (BackPic) {
WScreen->ViewPort.RasInfo->BitMap = WBitMap;
RemakeDisplay ();
LoadRGB4 (&WScreen->ViewPort, OldColors, 16);
DeletePic (BackPic);
}
if (MainWindow) CloseWindow (MainWindow);
if (IntuitionBase) CloseLibrary (IntuitionBase);
if (GfxBase) CloseLibrary (GfxBase);
if (!FromCLI) CurrentDir(oldlock);
Forbid ();
if (SRPort) MyClosePort (SRPort);
if (SPort) MyClosePort (SPort);
Permit ();
if (message) {
ReportError (message);
}
exit (0);
}
/*
** GetOffset ***************************************************************
**
** Sets Tile offsets from string of format xxx,yyy
**
**/
char *GetOffset (s)
char *s;
{
if (isdigit(*s)) {
TileXOff = atoi (s);
s = index (s, ',');
if (s == NULL || !isdigit(s[1])) {
Quit ("Bad Tile Offset specification");
}
s++;
TileYOff = atoi (s);
while (isdigit (*s)) {
s++;
}
--s;
} else {
--s;
}
return (s);
}
/*
** UsePickFile ************************************************************
**
** Picks one of X Pictures from file.
*/
char fname[257];
char perr[] = "I/O Error Reading PickFile.";
char *UsePickFile (filename)
char *filename;
{
FILE *fp;
char line[257];
int c;
int i;
char *s;
if (!(fp = fopen (filename, "r")))
Quit2 ("Could open pickfile ", filename);
if (!fgets(line, 256, fp))
Quit (perr);
c = atoi (line);
c = Random (c);
for (i = 0; i <= c; i++) {
fgets(line, 256, fp);
}
fclose (fp);
s = index (line + 1, '"');
if (!s)
Quit ("Syntax Error in PickFile");
*s = '\0';
strcpy (fname, line + 1);
if (tolower(s[1]) == 't') {
Tile = TRUE;
GetOffset (s + 2);
}
return (fname);
}
/**************************************************************************/
char wbhelp[] = "\
From the Workbench you may use extened-selection to choose \
a picture to use with SimGen. Select a Picture, Hold Shift, \
and double-click on SimGen.\n\nYou may also set the default \
tool of a picture to SimGen.\
";
char wbhelp1[] = "\
Valid ToolTypes for SimGen are \n\
KEEPCOLORS\n\
\n\
Keeps correct colors even when changed by other \
programs.\n\
\n\
WORKBENCH\n\
\n\
Restores SimGen after WorkBench has been closed.\n\
\n\
";
char wbhelp2[] = "\
TILE\n\
\n\
'Tiles' Picture. By default the picture is centered. \
This option 'tiles' the picture. An optional offset may be \
specified as in 'TILE=10,20'.\
";
char help[] = "\
Usage: %s [-option ...] picture [picture]...\n\
\tt = Tile Picture. Normally the Picture is centered but\n\
\t with this option the picture will be used as a pattern.\n\
\t Use with brushes. An offset may also be specified.\n\
\t Example: -t10,20\n\
\tw = WorkBench Restore. Restores SimGen after WorkBench\n\
\t is closed and re-opened.\n\
\tk = Keep Colors. Keeps the colors correct even when they\n\
\t are changed by other programs like preferneces.\n\
\tp = PickFile. This option must be followed by a filename\n\
\t as in '-pPicList' where PicList is a text file which\n\
\t on the first line contains the number of choices and\n\
\t the following lines contain Path/filename (surrounded\n\
\t by quotes) to valid IFF pictures to randomly choose from.\n\
\tr = Remove. Removes any previous SimGen\n\
\n\
\t\Type CTRL-C to Exit, use the 'Break' command or\n\
\t\Type 'SimGen -r' to remove SimGen.\n\
";
main (argc, argv)
int argc;
char **argv;
{
char **line;
char *name = NULL;
char *s;
int firstname = 1;
int c;
struct WBArg *wbarg;
struct FileLock *newlock;
struct DiskObject *dobj;
struct Message msg;
/*
** Open Intuition Library (needed here it seed random number).
*/
if (!( IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L)))
Quit ("Couldn't open intuition library");
/*
** Seed Random Number Generator.
*/
SeedRandom ();
/*
** Startup for CLI or WorkBench.
*/
if (argc) {
/*
** Set FromCLI Flag
*/
FromCLI = TRUE;
/*
** Did we get enough arguments?
*/
if (argc < 2 || argv[1][0] == '?') {
printf (help, argv[0]);
Quit (NULL);
}
/*
** Parse Options.
*/
while (argv[firstname][0] == '-') {
s = argv[firstname] + 1;
firstname++;
while (*s) {
switch (tolower(*s)) {
case 'r' :
ShutDownOld ();
Quit (NULL);
break;
case 'k' :
KeepColors = TRUE;
break;
case 'w' :
WorkBench = TRUE;
break;
case 't' :
Tile = TRUE;
s = GetOffset (s+1);
break;
case 'p' :
name = UsePickFile (s+1);
s[1] = '\0';
break;
default :
printf ("Unknown option '%c'\n",
*s);
break;
}
s++;
}
}
/*
** Pick Name at Random.
*/
if (!name) {
name = argv[firstname + Random (argc - firstname)];
}
printf ("loading '%s'\n", name);
} else {
if (WBenchMsg->sm_NumArgs < 2) {
c = Message (NULL, "SimGen Help", wbhelp,
" Exit | Remove | More Info ");
if (c == 2) {
ShutDownOld ();
Quit (NULL);
} else if (c == 3) {
Message (NULL, "SimGen Help",wbhelp1, " More ");
Message (NULL, "SimGen Help",wbhelp2, " Exit ");
}
Quit (NULL);
}
wbarg = WBenchMsg->sm_ArgList;
wbarg++;
name = wbarg->wa_Name;
newlock = (struct FileLock *)wbarg->wa_Lock;
oldlock = CurrentDir(newlock);
if (!(IconBase = OpenLibrary (ICONNAME, LIBRARY_VERSION)))
Quit ("Couldn't open Icon.Library");
if ((dobj = GetDiskObject (name))) {
if (FindToolType (dobj->do_ToolTypes, "KEEPCOLORS")) {
KeepColors = TRUE;
}
if (FindToolType (dobj->do_ToolTypes, "WORKBENCH")) {
WorkBench = TRUE;
}
if (s = FindToolType (dobj->do_ToolTypes, "TILE")) {
Tile = TRUE;
GetOffset (s);
}
}
CloseLibrary (IconBase);
}
ShutDownOld ();
Initialize(name);
msg.mn_Node.ln_Type = NT_MESSAGE;
msg.mn_ReplyPort = SRPort;
msg.mn_Length = sizeof (msg);
PutMsg (SPort, &msg);
Wait (SIGBREAKF_CTRL_C | (1L << SRPort->mp_SigBit));
Quit (NULL);
}
SYSMESS (mess)
char *mess;
{
if (FromCLI) {
puts (mess);
} else {
Message (NULL, "SimGen", mess, " OK ");
}
}
ReportError (mess)
char *mess;
{
if (FromCLI) {
puts (mess);
} else {
Message (NULL, "SimGen Error", mess, " Exit ");
}
}
SetColors () { }
RestoreColors () { }
RemovePointer () { }
RestorePointer () { }
/*
** SeedRandom **********************************************************
**
** Seeds random number generator with current time in MicroSeconds.
*/
SeedRandom ()
{
srand (IntuitionBase->Micros);
}
/*
** Random
**
** returns a random number from 0 to range - 1.
** range must be less than 32767.
*/
int Random (range)
int range;
{
return (((rand() & 0x7FFF) * range) >> 15);
}