home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
108.lha
/
Labyrinthe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-03-02
|
21KB
|
751 lines
/************************************************************************
**************************************************************************
** **
** Labyrinthe.c **
** ------------ **
** **
** Auteur : Eric Le Saux **
** **
** Club Amiga Montreal (CAM) **
** C.P. 195 STATION "N" **
** Montreal (Quebec) **
** H2X 3M2, CANADA **
** **
** Date : 7 mars 1988 **
** **
** Statut : DOMAINE PUBLIC - Distribution non-commerciale seulement **
** PUBLIC DOMAIN - Freely redistributable **
** **
**************************************************************************
************************************************************************/
/*** Fichiers d'entetes *************************************************/
#include <stdio.h>
#include <ctype.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/view.h>
/*** Fonctions et variables externes ************************************/
extern struct Library *OpenLibrary ();
extern struct TextFont *OpenFont ();
extern struct Screen *OpenScreen ();
extern struct Window *OpenWindow ();
extern struct IntuiMessage *GetMsg ();
extern struct Process *FindTask ();
extern int Enable_Abort;
/*** Structures pour la fenetre d'instructions **************************/
#define GadgRechercheID 0
#define GadgCreationID 1
#define Gadg_640_400_ID 2
#define Gadg_640_200_ID 3
#define Gadg_320_400_ID 4
#define Gadg_320_200_ID 5
SHORT BorderVectors1[] = {0,0,86,0,86,61,0,61,0,0};
struct Border Border1 = {-1,-1,3,0,JAM1,5,BorderVectors1,NULL};
struct IntuiText IText3 = {1,0,JAM1,17,40,NULL,(UBYTE *)"Sortie",NULL};
struct IntuiText IText2 = {1,0,JAM1,21,26,NULL,(UBYTE *)"de la",&IText3};
struct IntuiText IText1 = {1,0,JAM1,7,12,NULL,(UBYTE *)"Recherche",&IText2};
struct Gadget GadgRecherche =
{
NULL,97,78,85,60,
NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border1,NULL,&IText1,
NULL,NULL,GadgRechercheID,NULL
};
SHORT BorderVectors2[] = {0,0,86,0,86,61,0,61,0,0};
struct Border Border2 = {-1,-1,3,0,JAM1,5,BorderVectors2,NULL};
struct IntuiText IText6 = {1,0,JAM1,2,40,NULL,(UBYTE *)"Labyrinthe",NULL};
struct IntuiText IText5 = {1,0,JAM1,34,26,NULL,(UBYTE *)"du",&IText6};
struct IntuiText IText4 = {1,0,JAM1,10,12,NULL,(UBYTE *)"Creation",&IText5};
struct Gadget GadgCreation =
{
&GadgRecherche,97,14,85,60,
NULL,RELVERIFY,BOOLGADGET,
(APTR)&Border2,NULL,&IText4,
NULL,NULL,GadgCreationID,NULL
};
SHORT BorderVectors3[] = {0,0,86,0,86,29,0,29,0,0};
struct Border Border3 = {-1,-1,3,0,JAM1,5,BorderVectors3,NULL};
struct IntuiText IText7 = {2,0,JAM1,13,10,NULL,(UBYTE *)"640x400",NULL};
struct Gadget Gadg_640_400 =
{
&GadgCreation,7,110,85,28,
NULL,RELVERIFY|TOGGLESELECT,BOOLGADGET,
(APTR)&Border3,NULL,&IText7,
NULL,NULL,Gadg_640_400_ID,NULL
};
SHORT BorderVectors4[] = {0,0,86,0,86,29,0,29,0,0};
struct Border Border4 = {-1,-1,3,0,JAM1,5,BorderVectors4,NULL};
struct IntuiText IText8 = {2,0,JAM1,13,10,NULL,(UBYTE *)"640x200",NULL};
struct Gadget Gadg_640_200 =
{
&Gadg_640_400,7,78,85,28,
NULL,RELVERIFY|TOGGLESELECT,BOOLGADGET,
(APTR)&Border4,NULL,&IText8,
NULL,NULL,Gadg_640_200_ID,NULL
};
SHORT BorderVectors5[] = {0,0,86,0,86,29,0,29,0,0};
struct Border Border5 = {-1,-1,3,0,JAM1,5,BorderVectors5,NULL};
struct IntuiText IText9 = {2,0,JAM1,13,10,NULL,(UBYTE *)"320x400",NULL};
struct Gadget Gadg_320_400 =
{
&Gadg_640_200,7,46,85,28,
NULL,RELVERIFY|TOGGLESELECT,BOOLGADGET,
(APTR)&Border5,NULL,&IText9,
NULL,NULL,Gadg_320_400_ID,NULL
};
SHORT BorderVectors6[] = {0,0,86,0,86,29,0,29,0,0};
struct Border Border6 = {-1,-1,3,0,JAM1,5,BorderVectors6,NULL};
struct IntuiText IText10 = {2,0,JAM1,13,10,NULL,(UBYTE *)"320x200",NULL};
struct Gadget Gadg_320_200 =
{
&Gadg_320_400,7,14,85,28,
NULL,RELVERIFY|TOGGLESELECT,BOOLGADGET,
(APTR)&Border6,NULL,&IText10,
NULL,NULL,Gadg_320_200_ID,NULL
};
#define GadgetList Gadg_320_200
struct Window *FenetreWB;
struct NewWindow FenetreWBData =
{
169,20,189,143,1,2,
GADGETUP|CLOSEWINDOW|MOUSEBUTTONS,
WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|RMBTRAP|ACTIVATE|SMART_REFRESH,
&GadgetList,NULL,(UBYTE *)" Labyrinthe ",
NULL,NULL,5,5,640,200,WBENCHSCREEN
};
/*** Variables globales pour le maintient du systeme ********************/
SHORT Largeur, Hauteur;
#define Profond 2
#define CarMinX 1
#define CarMinY 1
SHORT CarMaxX, CarMaxY;
#define AbsMinX 0
#define AbsMinY 0
USHORT AbsMaxX, AbsMaxY;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct TextAttr FonteAttr = { (UBYTE *) "topaz.font", 8, 0, 0 };
struct TextFont *Fonte;
struct Screen *Ecran;
struct NewScreen EcranData =
{
0,0,0,0,Profond,
0,1,HIRES|LACE,CUSTOMSCREEN|SCREENBEHIND,&FonteAttr,
(UBYTE *) "Labyrinthe -ELS- Club Amiga Montreal", NULL, NULL
};
struct Window *Fenetre;
struct NewWindow FenetreData =
{
0,0,0,0,-1,-1,NULL,
BACKDROP|BORDERLESS|RMBTRAP|SMART_REFRESH,
NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN
};
struct RastPort *RP;
/*************************************************************************
**************************************************************************
**
** Sortie ()
**
** Ferme ce qui a ete ouvert.
**
*/
void Sortie ()
{
if (FenetreWB) CloseWindow (FenetreWB);
if (Fenetre) CloseWindow (Fenetre);
if (Ecran) CloseScreen (Ecran);
if (IntuitionBase) CloseLibrary (IntuitionBase);
if (GfxBase) CloseLibrary (GfxBase);
if (Fonte) CloseFont (Fonte);
_exit (0L);
}
/*************************************************************************
**************************************************************************
**
** Erreur ()
**
** Affiche un message d'erreur a travers un requester.
** Laisse le choix entre l'abandon de la procedure et
** un autre essai.
**
*/
#define ErrGfxLib 0
#define ErrIntuiLib 1
#define ErrOpenWin 2
#define ErrOpenScr 3
#define ErrFonte 4
struct IntuiText Message = { 2, 1, JAM1, 17, 10, NULL, NULL, NULL };
struct IntuiText Essai = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Tentative", NULL };
struct IntuiText Abandon = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Abandon", NULL };
void Erreur (Err)
SHORT Err;
{
struct Process *Proc;
SHORT EssaieEncore;
switch (Err)
{
case ErrGfxLib : Message.IText = (UBYTE *) "Erreur: OpenLibrary: GfxLib";
break;
case ErrIntuiLib : Message.IText = (UBYTE *) "Erreur: OpenLibrary: IntuiLib)";
break;
case ErrOpenWin : Message.IText = (UBYTE *) "Erreur: OpenWindow";
break;
case ErrOpenScr : Message.IText = (UBYTE *) "Erreur: OpenScreen";
break;
case ErrFonte : Message.IText = (UBYTE *) "Erreur: OpenFont: Topaz 8";
break;
default : Message.IText = (UBYTE *) "Erreur inconnue !";
break;
}
/*=== On envoie le requester sur le Workbench ===*/
Proc = FindTask (0L);
EssaieEncore = AutoRequest (Proc->pr_WindowPtr, &Message, &Essai, &Abandon,
NULL, NULL, 300L, 60L);
if (EssaieEncore) return;
Sortie ();
}
/*************************************************************************
**************************************************************************
**
** SelectCouleurs ()
**
** On s'arrange pour que les deux premieres couleurs de l'ecran passe
** en parametre soient dans un ordre decroissant d'intensite.
*/
void SelectCouleurs (Ecran)
struct Screen *Ecran;
{
UWORD *Couleurs;
UWORD Moy0, Moy1;
Couleurs = (UWORD *) (Ecran->ViewPort.ColorMap->ColorTable);
Moy0 = (((Couleurs[0]&0x0F00)>>8)+((Couleurs[0]&0x00F0)>>4)+(Couleurs[0]&0x000F))/3;
Moy1 = (((Couleurs[1]&0x0F00)>>8)+((Couleurs[1]&0x00F0)>>4)+(Couleurs[1]&0x000F))/3;
if (Moy0 < Moy1)
{
Moy0 = Couleurs[0];
Couleurs[0] = Couleurs[1];
Couleurs[1] = Moy0;
}
Couleurs[1] = 0x0000;
Couleurs[2] = 0x0400;
Couleurs[3] = 0x0D00;
MakeScreen (Ecran);
RethinkDisplay ();
}
/*************************************************************************
**************************************************************************
**
** AfficheCarrefours ()
**
*/
void AfficheCarrefours ()
{
SHORT Index;
SetRast (RP, 0L);
SetAPen (RP, 1L);
RP->LinePtrn = 0xAAAA;
for (Index=0; Index<(FenetreData.Height-1); Index+=2)
{
Move (RP, 0L, (LONG)Index);
Draw (RP, (LONG)FenetreData.Width-1L, (LONG)Index);
}
RP->LinePtrn = 0xFFFF;
}
/*************************************************************************
**************************************************************************
**
** OuvreFenetre ()
**
*/
#define Mode_320_200 0
#define Mode_320_400 1
#define Mode_640_200 2
#define Mode_640_400 3
void OuvreFenetre (Mode)
UBYTE Mode;
{
USHORT ModeVision;
/*=== On ferme si c'etait ouvert ===*/
if (Fenetre) CloseWindow (Fenetre);
if (Ecran) CloseScreen (Ecran);
/*=== On change l'etat des gadgets de resolutions ===*/
RemoveGList (FenetreWB, &GadgetList, 4L);
GadgetList.Flags &= ~SELECTED;
GadgetList.NextGadget->Flags &= ~SELECTED;
GadgetList.NextGadget->NextGadget->Flags &= ~SELECTED;
GadgetList.NextGadget->NextGadget->NextGadget->Flags &= ~SELECTED;
/*=== On initialise les structures ===*/
switch (Mode)
{
case Mode_320_200 : Largeur = 320;
Hauteur = 200;
ModeVision = NULL;
Gadg_320_200.Flags |= SELECTED;
break;
case Mode_320_400 : Largeur = 320;
Hauteur = 400;
ModeVision = LACE;
Gadg_320_400.Flags |= SELECTED;
break;
case Mode_640_200 : Largeur = 640;
Hauteur = 200;
ModeVision = HIRES;
Gadg_640_200.Flags |= SELECTED;
break;
case Mode_640_400 : Largeur = 640;
Hauteur = 400;
ModeVision = HIRES|LACE;
Gadg_640_400.Flags |= SELECTED;
break;
}
CarMaxX = Largeur/2; CarMaxY = Hauteur/2;
AbsMaxX = Largeur-1; AbsMaxY = Hauteur-1;
/*=== On remet les gadgets ===*/
AddGList (FenetreWB, &GadgetList, 0L, 4L, NULL);
RefreshGList (&GadgetList, FenetreWB, NULL, 4L);
/*=== On ouvre l'ecran ===*/
EcranData.Width = Largeur;
EcranData.Height = Hauteur;
EcranData.ViewModes = ModeVision;
FOREVER
{
Ecran = OpenScreen (&EcranData);
if (!Ecran) Erreur (ErrOpenScr);
else break;
}
SelectCouleurs (Ecran);
ShowTitle (Ecran, (LONG)FALSE);
/*=== On ouvre la fenetre ===*/
FenetreData.Screen = Ecran;
FenetreData.Width = Largeur;
FenetreData.Height = Hauteur;
FOREVER
{
Fenetre = OpenWindow (&FenetreData);
if (!Fenetre) Erreur (ErrOpenWin);
else break;
}
/*=== On pointe le RastPort de la fenetre ===*/
RP = Fenetre->RPort;
/*=== On prepare l'ecran ===*/
AfficheCarrefours ();
}
/*************************************************************************
**************************************************************************
**
** Rnd ()
**
** Retourne un nb dans un intervalle donne, bornes incluses.
** Le premier argument devrait etre plus petit que le second.
**
*/
USHORT Rnd (N1, N2)
USHORT N1, N2;
{
return ( ( ((rand()&0x00FF) * (N2-N1+1)) >> 8 ) + N1 );
}
/*************************************************************************
**************************************************************************
**
** Initialise ()
**
*/
void Initialise ()
{
ULONG Secondes, Micros; /* Temps courant */
/*=== La librairie Intuition ===*/
/*=== Si on n'a pas la bonne version, on ouvre celle presente pour ===*/
/*=== appeler la fonction AutoRequest (). ===*/
FOREVER
{
IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 33L); /* v1.2+ */
if (!IntuitionBase)
{
IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L);
if (!IntuitionBase) Sortie (); /* Plus le choix ! */
Erreur (ErrIntuiLib);
Sortie ();
}
else break;
}
/*=== La librairie graphique ===*/
FOREVER
{
GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
if (!GfxBase) Erreur (ErrGfxLib);
else break;
}
/*=== La ROMFonte par defaut ===*/
FOREVER
{
Fonte = OpenFont (&FonteAttr);
if (!Fonte) Erreur (ErrFonte);
else break;
}
/*=== Ouverture de la fenetre de controle ===*/
FOREVER
{
FenetreWB = OpenWindow (&FenetreWBData);
if (!FenetreWB) Erreur (ErrOpenWin);
else break;
}
SetFont (FenetreWB->RPort, Fonte);
/*=== Init de la fonction aleatoire ===*/
CurrentTime (&Secondes, &Micros);
srand ( (SHORT) (Secondes&0x00FF) );
Rnd (0,0); Rnd (0,0); Rnd (0,0);
}
/*************************************************************************
**************************************************************************
**
** _abort ()
**
** On remplace quelques fonctions par defaut.
**
*/
void _abort () { Sortie (); }
void _cli_parse () {}
void _wb_parse () {}
/*************************************************************************
**************************************************************************
**
** Cvt ()
**
** Converti de coordonnees carrefour a coordonnees raster.
**
*/
ULONG Cvt (X)
USHORT X;
{
return (ULONG) ( (X-1) << 1 );
}
/*************************************************************************
**************************************************************************
**
** Laby ()
**
*/
void Laby (MinX, MaxX, MinY, MaxY)
USHORT MinX, MaxX, MinY, MaxY;
{
USHORT MoyX, MoyY, dX, dY, Cote;
if ( (MinX==MaxX) || (MinY==MaxY) )
{
Move (RP, Cvt(MinX), Cvt(MinY));
Draw (RP, Cvt(MaxX), Cvt(MaxY));
}
else
{
Cote = Rnd (1,4);
MoyX = (MaxX+MinX)/2; dX = (MaxX-MinX+1)/5;
MoyY = (MaxY+MinY)/2; dY = (MaxY-MinY+1)/5;
MoyX = Rnd (MoyX-dX,MoyX+dX-1);
MoyY = Rnd (MoyY-dY,MoyY+dY-1);
Laby ( MinX,MoyX, MinY,MoyY );
Laby ( MoyX+1,MaxX, MinY,MoyY );
Laby ( MoyX+1,MaxX, MoyY+1,MaxY );
Laby ( MinX,MoyX, MoyY+1,MaxY );
if (Cote != 1) WritePixel (RP, Cvt(MoyX)+1L, Cvt(Rnd(MinY,MoyY)));
if (Cote != 3) WritePixel (RP, Cvt(MoyX)+1L, Cvt(Rnd(MoyY+1,MaxY)));
if (Cote != 2) WritePixel (RP, Cvt(Rnd(MinX,MoyX)), Cvt(MoyY)+1L);
if (Cote != 4) WritePixel (RP, Cvt(Rnd(MoyX+1,MaxX)), Cvt(MoyY)+1L);
};
}
/*************************************************************************
**************************************************************************
**
** Recherche ()
**
*/
void NewPos (X1,Y1,X2,Y2,Dir,Dist)
USHORT X1,Y1,*X2,*Y2; UBYTE Dir; USHORT Dist;
{
switch (Dir)
{
case 0 : *X2 = X1; *Y2 = Y1-Dist; break;
case 1 : *X2 = X1+Dist; *Y2 = Y1; break;
case 2 : *X2 = X1; *Y2 = Y1+Dist; break;
case 3 : *X2 = X1-Dist; *Y2 = Y1; break;
}
}
BOOL PasDeMur (X,Y,Dir)
USHORT X,Y; UBYTE Dir;
{
USHORT nX,nY;
NewPos (X,Y,&nX,&nY,Dir,1);
if ( (nX<AbsMinX) || (nX>AbsMaxX) || (nY<AbsMinY) || (nY>AbsMaxY) )
return (FALSE);
else
return (ReadPixel(RP, (ULONG)nX, (ULONG)nY)!=0);
}
#define FilArianne 3
#define Trace 2
void Avance (X,Y,Dir)
USHORT *X,*Y; UBYTE Dir;
{
USHORT nX,nY;
NewPos (*X,*Y,&nX,&nY,Dir,2);
if ( ReadPixel(RP,(ULONG)nX,(ULONG)nY) == FilArianne )
SetAPen (RP, (ULONG)Trace);
else
SetAPen (RP, (ULONG)FilArianne);
Draw (RP,(ULONG)nX,(ULONG)nY);
*X = nX; *Y = nY;
}
void Recherche (DepartX, DepartY, ArriveeX, ArriveeY)
USHORT DepartX, DepartY, ArriveeX, ArriveeY;
{
register UBYTE Dir; /* 0..3 */
USHORT X1, Y1;
register USHORT X2, Y2;
X1 = (USHORT) Cvt (DepartX); (USHORT) Y1 = Cvt (DepartY);
X2 = (USHORT) Cvt (ArriveeX); (USHORT) Y2 = Cvt (ArriveeY);
Dir = 1;
Move (RP, (ULONG)X1, (ULONG)Y1);
while ( (X1 != X2) || (Y1 != Y2) )
{
if ( PasDeMur(X1,Y1,(Dir+1)%4) ) /* Pas de mur a droite ? */
{
Avance (&X1,&Y1,Dir=(Dir+1)%4);
continue;
}
if ( PasDeMur(X1,Y1,Dir) ) /* Pas de mur devant ? */
{
Avance (&X1,&Y1,Dir);
continue;
}
Dir = (Dir+2)%4; /* Cul-de-sac : volte-face */
}
}
/*************************************************************************
**************************************************************************
**************************************************************************
***
*** main ()
***
**/
main ()
{
struct IntuiMessage *Msg; /* Pointeur pour prendre les messages */
ULONG Classe; /* Pour noter la classe du message */
USHORT Code; /* Pour noter le code du message */
struct Gadget *Adresse; /* Pour noter l'addresse du gadget */
BOOL LabyExiste = FALSE; /* TRUE quand il y a un labyrinthe a fouiller */
BOOL TitleOn = FALSE;
BOOL LabyCree = FALSE;
/*=== Init ===*/
Initialise ();
/*=== On attends un evenement: IntuiMessage ou CTRL_C. ===*/
FOREVER
{
if (Wait (SIGBREAKF_CTRL_C|1L<<FenetreWB->UserPort->mp_SigBit)==SIGBREAKF_CTRL_C)
Sortie ();
while (Msg=GetMsg(FenetreWB->UserPort))
{
Classe = Msg->Class;
Code = Msg->Code;
Adresse = (struct Gadget *) Msg->IAddress;
ReplyMsg (Msg);
if (Classe == CLOSEWINDOW) Sortie ();
if (Classe==MOUSEBUTTONS)
{
if (!LabyExiste || Code!=MENUDOWN) continue;
if (TitleOn)
{
ShowTitle (Ecran, (LONG)(TitleOn=FALSE));
}
else
{
ShowTitle (Ecran, (LONG)(TitleOn=TRUE));
ScreenToFront (Ecran);
}
continue; /* le while */
}
switch (Adresse->GadgetID)
{
case GadgRechercheID : if (LabyCree)
{
ShowTitle (Ecran, (LONG)(TitleOn=FALSE));
ScreenToFront (Ecran);
Recherche (CarMinX, CarMinY, CarMaxX, CarMaxY);
LabyCree = FALSE;
}
else DisplayBeep (0L);
break;
case GadgCreationID : if (LabyExiste)
{
AfficheCarrefours ();
ShowTitle (Ecran, (LONG)(TitleOn=FALSE));
ScreenToFront (Ecran);
Laby (CarMinX, CarMaxX, CarMinY, CarMaxY);
LabyCree = TRUE;
}
else DisplayBeep (0L);
break;
case Gadg_640_400_ID : OuvreFenetre (Mode_640_400);
TitleOn = FALSE;
LabyExiste = TRUE;
LabyCree = FALSE;
break;
case Gadg_640_200_ID : OuvreFenetre (Mode_640_200);
TitleOn = FALSE;
LabyExiste = TRUE;
LabyCree = FALSE;
break;
case Gadg_320_400_ID : OuvreFenetre (Mode_320_400);
TitleOn = FALSE;
LabyExiste = TRUE;
LabyCree = FALSE;
break;
case Gadg_320_200_ID : OuvreFenetre (Mode_320_200);
TitleOn = FALSE;
LabyExiste = TRUE;
LabyCree = FALSE;
break;
}
}
}
}