home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d8xx
/
d886
/
goalkeeper.lha
/
GoalKeeper
/
Sources
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
20KB
|
692 lines
/* GOALKEEPER V1.0 19-oct-92 Camiel Rouweler */
#include <intuition/intuition.h>
#include <dos/dosextens.h>
#include <exec/memory.h>
#define MODE_OLDFILE 1005L /* saves us from including dos.h */
#define MODE_NEWFILE 1006L
/* data for a played match */
struct GameData
{
UBYTE TeamA[12], TeamB[12]; /* Team names */
ULONG pl1_score, pl2_score; /* goals scored */
};
/* data for one player entry */
struct PlayerData
{
UBYTE pl_num; /* remember after sorting which player he was */
UBYTE pl_name[12]; /* name */
UWORD gw, gd, gl; /* wins, draws and losses */
ULONG gf, ga; /* goals for and against */
};
/* complete datastructure */
struct DataSeg
{
UBYTE pl_entered; /* number of players, should always be 8 */
UBYTE games_played; /* matches played, starts with 0, maximum = 8 */
struct GameData LastResults[8]; /* results of last matches */
struct PlayerData Player[8]; /* data of all entered players */
};
struct DataSeg Data =
{
8, 0, /* 8 players, no matches played */
"", "", 0, 0, /* as I said, no matches played */
"", "", 0, 0,
"", "", 0, 0,
"", "", 0, 0,
"", "", 0, 0,
"", "", 0, 0,
"", "", 0, 0,
"", "", 0, 0,
0, "Player 1", 0, 0, 0, 0, 0, /* player ID, name and scores */
1, "Player 2", 0, 0, 0, 0, 0,
2, "Player 3", 0, 0, 0, 0, 0,
3, "Player 4", 0, 0, 0, 0, 0,
4, "Player 5", 0, 0, 0, 0, 0,
5, "Player 6", 0, 0, 0, 0, 0,
6, "Player 7", 0, 0, 0, 0, 0,
7, "Player 8", 0, 0, 0, 0, 0
};
#define DATASEGSIZE sizeof(struct DataSeg)
#define DISPLAYSIZE 8 /* number of entries on display, do not change! */
#define PREFSSIZE sizeof(struct Preferences)
struct IntuitionBase *IntuitionBase; /* normal declarations */
struct Window *Window;
struct RastPort *RPort;
struct IntuiMessage *message;
void *AllocMem();
struct Filehandle *F;
UBYTE FN[] = "Soccer.data"; /* file name for data file */
struct FileLock *lock;
void *Open();
void *OpenLibrary();
BOOL GetResult();
BOOL LoadData();
BOOL SaveData();
UBYTE WinPoints = 2;
/* points for a win, can be set to three for these people in the UK, who
always should make things different */
UBYTE light, dark; /* pen numbers of the dark and light pen */
/* Use normal font even if user has set some strange Preferences */
struct TextAttr Style =
{ (UBYTE *)"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
/* All IntuiText structures I need */
struct IntuiText
Notsaved_text = { 0, 1, JAM2, 10, 10, &Style,
(UBYTE *)"New results not yet saved", NULL },
NSYes_text = { 0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Quit", NULL },
NSNo_text = { 0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Save", NULL },
SVText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Save", NULL },
QTText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Quit", NULL },
USText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Enter result", NULL },
EuroText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Winning = 2p", NULL },
UKText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Winning = 3p", NULL },
SUText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)" Results", NULL },
SSText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)" Tables", NULL },
SxText = { 1, 0, JAM2, 6, 3, &Style, (UBYTE *)"Show", NULL },
SHeaderText = { 1, 0, JAM2, 0, 0, &Style,
(UBYTE *)"Player name P W D L PTS GF - GA", NULL },
RHeaderText = { 1, 0, JAM2, 0, 0, &Style,
(UBYTE *)"Team A Team B Scores ", NULL },
ResLine = { 1, 0, JAM2, 0, 0, &Style,
(UBYTE *)" ", NULL };
/* defines define positions of certain text elements in strings */
#define plname_pos 0
#define gp_pos 14
#define gw_pos 18
#define gd_pos 22
#define gl_pos 26
#define pt_pos 31
#define gf_pos 36
#define line2_pos 38
#define ga_pos 42
#define pl1name_pos 0
#define vs_pos 12
#define pl2name_pos 15
#define pl1score_pos 29
#define line_pos 31
#define pl2score_pos 35
/* All Border structures I need */
WORD BigPairs2a[] =
{ -1, 81, -1, -1, 350, -1 };
WORD BigPairs2[] =
{ 350, 0, 350, 82, -1, 82 };
WORD BigPairsa[] =
{ 0, 12, 349, 12, 349, 1, 349, 81, 0, 81 };
WORD BigPairs[] =
{ 348, 13, 0, 13, 0, 80, 0, 0, 349, 0 };
struct Border BigBorder2a =
{ -3, -3, 2, 0, JAM1, 3, BigPairs2a, NULL };
struct Border BigBorder2 =
{ -3, -3, 1, 0, JAM1, 3, BigPairs2, &BigBorder2a };
struct Border BigBordera =
{ -3, -3, 2, 0, JAM1, 5, BigPairsa, &BigBorder2 };
struct Border BigBorder =
{ -3, -3, 1, 0, JAM1, 5, BigPairs, &BigBordera };
WORD GadgetPairs3[] =
{ 84, 1, 84, 13, 0, 13 };
WORD GadgetPairs3a[] =
{ 0, 12, 0, 0, 84, 0 };
struct Border GadgetBorder3a =
{ 0, 0, 2, 0, JAM1, 3, GadgetPairs3a, NULL };
struct Border GadgetBorder3 =
{ 0, 0, 1, 0, JAM1, 3, GadgetPairs3, &GadgetBorder3a };
struct Border GadgetBorder3ainv =
{ 0, 0, 1, 0, JAM1, 3, GadgetPairs3a, NULL };
struct Border GadgetBorder3inv =
{ 0, 0, 2, 0, JAM1, 3, GadgetPairs3, &GadgetBorder3ainv };
WORD GadgetPairs2[] =
{ 108, 1, 108, 13, 0, 13 };
WORD GadgetPairs2a[] =
{ 0, 12, 0, 0, 108, 0 };
struct Border GadgetBorder2a =
{ 0, 0, 2, 0, JAM1, 3, GadgetPairs2a, NULL };
struct Border GadgetBorder2 =
{ 0, 0, 1, 0, JAM1, 3, GadgetPairs2, &GadgetBorder2a };
WORD GadgetPairs1[] =
{ 44, 1, 44, 13, 0, 13 };
WORD GadgetPairs1a[] =
{ 0, 12, 0, 0, 44, 0 };
struct Border GadgetBorder1a =
{ 0, 0, 2, 0, JAM1, 3, GadgetPairs1a, NULL };
struct Border GadgetBorder1 =
{ 0, 0, 1, 0, JAM1, 3, GadgetPairs1, &GadgetBorder1a };
/* Borders in file res.c */
extern struct Border squarebox, squareboxa;
extern struct Border ResBorder, ResBordera;
extern struct Border IntBorder, IntBordera;
extern struct Border RGadgetBorder3, RGadgetBorder3a;
extern struct Border OKBox, OKBoxa;
/* GadgetID-defines */
#define g_SS 11
#define g_SU 10
#define g_SC 6
#define g_US 5
#define g_QT 1
#define g_SV 2
/* Gadget structures */
/* 'Tables' */
struct Gadget SSGadget =
{
NULL, 198, 20, 85, 14, GADGHNONE, GADGIMMEDIATE,
BOOLGADGET, (APTR)&GadgetBorder3inv, NULL, &SSText, NULL, NULL, g_SS, NULL
};
/* 'Results' */
struct Gadget SUGadget =
{
&SSGadget, 48, 20, 85, 14, GADGHNONE, GADGIMMEDIATE,
BOOLGADGET, (APTR)&GadgetBorder3, NULL, &SUText, NULL, NULL, g_SU, NULL
};
/* 'winpoints = x' */
struct Gadget SCGadget =
{
&SUGadget, 137, 140, 109, 14, GADGHCOMP, GADGIMMEDIATE, BOOLGADGET,
(APTR)&GadgetBorder2, NULL, &EuroText, NULL, NULL, g_SC, NULL
};
/* 'Enter result' */
struct Gadget USGadget =
{
&SCGadget, 17, 140, 109, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR)&GadgetBorder2, NULL, &USText, NULL, NULL, g_US, NULL
};
/* 'Quit' */
struct Gadget QTGadget =
{
&USGadget, 321, 140, 45, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR)&GadgetBorder1, NULL, &QTText, NULL, NULL, g_QT, NULL
};
/* 'Save' */
struct Gadget SVGadget =
{
&QTGadget, 264, 140, 45, 14, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR)&GadgetBorder1, NULL, &SVText, NULL, NULL, g_SV, NULL
};
/* NewWindow structure for main window */
struct NewWindow NewWindow =
{
100, 20, 384, 160, -1, -1,
GADGETDOWN | GADGETUP,
WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | ACTIVATE,
&SVGadget, NULL, (UBYTE *)"Goalkeeper v1.0 - by Camiel Rouweler",
NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN,
};
int main()
{
ULONG MessageClass; /* all for receiving IntuiMessages */
UWORD code, GadgetNr;
struct Gadget *GadgetPtr;
struct Message *GetMsg();
/* show what? how many points for a win? */
BOOL g_SU_sel = FALSE, Euro_selected = TRUE;
BOOL Data_saved = TRUE; /* data was not changed since last save operation */
struct Preferences *PrefsPtr;
UWORD col1, col2, r, g, b;
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L);
PrefsPtr = (struct Preferences *) AllocMem(PREFSSIZE, MEMF_PUBLIC);
/* Open Preferences structure to find out how colour settings are */
if (PrefsPtr)
{
GetPrefs(PrefsPtr, PREFSSIZE);
col1 = PrefsPtr->color1;
col2 = PrefsPtr->color2;
r = (col1 & 0x0f00) / 256;
g = (col1 & 0x00f0) /16;
b = col1 & 0x000f;
col1 = r + g + b;
r = (col2 & 0x0f00) / 256;
g = (col2 & 0x00f0) /16;
b = col2 & 0x000f;
col2 = r + g + b;
FreeMem(PrefsPtr, PREFSSIZE);
if (col1 > col2)
{
/* colour2 is darker than colour1 */
light = 1;
dark = 2;
}
else
{
/* colour1 is darker than colour2 */
light = 2;
dark = 1;
}
/* Adjust colours in Border structures for a nice 2.0 look, even in 1.3
independently from Preferences-settings */
GadgetBorder1.FrontPen = dark;
GadgetBorder1a.FrontPen = light;
GadgetBorder2.FrontPen = dark;
GadgetBorder2a.FrontPen = light;
GadgetBorder3.FrontPen = dark;
GadgetBorder3a.FrontPen = light;
GadgetBorder3inv.FrontPen = light;
GadgetBorder3ainv.FrontPen = dark;
BigBorder.FrontPen = dark;
BigBordera.FrontPen = light;
BigBorder2.FrontPen = dark;
BigBorder2a.FrontPen = light;
squarebox.FrontPen = dark;
squareboxa.FrontPen = light;
ResBordera.FrontPen = dark;
ResBorder.FrontPen = light;
IntBorder.FrontPen = dark;
IntBordera.FrontPen = light;
RGadgetBorder3.FrontPen = dark;
RGadgetBorder3a.FrontPen = light;
OKBox.FrontPen = dark;
OKBoxa.FrontPen = light;
}
Open_All(); /* Open main window */
LoadData(); /* load previously saved data, if found */
ShowTables(); /* no comment */
FOREVER /* it has to quit sometime though! */
{
/* standard message reading */
if (!(message = (struct IntuiMessage *)
GetMsg(Window->UserPort)))
{
Wait(1L << Window->UserPort->mp_SigBit);
continue;
}
MessageClass = message->Class;
code = message->Code;
GadgetPtr = (struct Gadget *) message->IAddress;
GadgetNr = GadgetPtr->GadgetID;
ReplyMsg(message);
switch(MessageClass)
{
case GADGETUP:
switch(GadgetNr)
{
case g_US:
/* Get a match result and update tables */
if (GetResult())
{
Data_saved = FALSE;
if (g_SU_sel) ShowResults();
else ShowTables();
}
break;
case g_QT:
/* if data was not yet saved, ask if you may have had forgotten */
if (!Data_saved)
{
if (AutoRequest(Window, &Notsaved_text, &NSYes_text,
&NSNo_text, 0L, 0L,
IntuiTextLength(&Notsaved_text) + 50L, 60L))
{
/* deliberately not saved, so exit! */
Close_All();
exit(0);
}
else
if (Data_saved = SaveData())
{
/* data saved after all, time to go! */
Close_All();
exit(0);
}
}
else
{
/* Data had been saved without asking. Good boy/girl! */
Close_All();
exit(0);
}
break;
case g_SV:
/* user wants to save data, so we'll try */
Data_saved = SaveData();
break;
}
break;
case GADGETDOWN:
switch(GadgetNr)
{
case g_SS:
if (g_SU_sel)
{
/* Show tables and fix results-gadget */
ShowTables();
g_SU_sel = FALSE;
SSGadget.GadgetRender = &GadgetBorder3inv;
SUGadget.GadgetRender = &GadgetBorder3;
RefreshGList(&SUGadget, Window, NULL, 2L);
}
break;
case g_SU:
if (!g_SU_sel)
{
/* Show results and fix tables-gadget */
ShowResults();
g_SU_sel = TRUE;
SUGadget.GadgetRender = &GadgetBorder3inv;
SSGadget.GadgetRender = &GadgetBorder3;
RefreshGList(&SUGadget, Window, NULL, 2L);
}
break;
case g_SC:
/* change points for a win */
Euro_selected = !Euro_selected;
if (Euro_selected)
{
SCGadget.GadgetText = &EuroText;
WinPoints = 2;
}
else
{
SCGadget.GadgetText = &UKText;
WinPoints = 3;
/* why is everything different in the UK?
why can't they measure distance in metres?
why don't they measure beet in litres?
why do they give 3 points for a win?
*/
}
RefreshGList(&SCGadget, Window, NULL, 1L);
if (!g_SU_sel) ShowTables();
break;
}
break;
}
}
}
Open_All() /* 'All' is here just one measly window */
{
struct Window *OpenWindow();
if (!(Window = (struct Window *)
OpenWindow(&NewWindow)))
{
/* show a system-request when there is no memory for the window */
/* there wont't be memory for a request then, but who cares! */
ShowText(NULL, "Fout bij openen venster", NULL);
Close_All(); /* give up already */
exit(0);
}
RPort = Window->RPort;
/* do some drawing and printing to make it look nicer */
DrawBorder(RPort, &BigBorder, 20L, 50L);
PrintIText(RPort, &SxText, 140L, 20L);
PrintDepth(RPort, &SHeaderText, 20L, 49L, 0, 0);
}
Close_All() /* we may close IntuitionBase and the window, wow! */
{
if (Window) CloseWindow(Window);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}
BOOL LoadData() /* TRUE if loading was succesfull */
{
LONG BR;
if (lock = (struct FileLock *) Lock(FN, ACCESS_READ))
{
UnLock(lock);
F = Open(FN, MODE_OLDFILE);
if (!F)
{
ShowText(NULL, "Error opening file", NULL);
return(FALSE);
}
else
{
BR = Read(F, &Data, DATASEGSIZE);
if (BR != DATASEGSIZE)
{
ShowText(NULL, "Error reading data", NULL);
Close(F);
return(FALSE);
}
Close(F);
return(TRUE);
}
}
else ShowText(NULL, "Data file not found", NULL);
}
BOOL SaveData() /* TRUE if saving was succesfull */
{
LONG BW;
F = Open(FN, MODE_NEWFILE);
if (!F)
{
ShowText(Window, "error opening file", NULL);
return(FALSE);
}
else
{
BW = Write(F, &Data, DATASEGSIZE);
if (BW != DATASEGSIZE)
{
ShowText(Window, "error writing data", NULL);
Close(F);
return(FALSE);
}
Close(F);
/* let user know all went the way it was upposed to go */
ShowText(Window, "Data saved", "Thanks");
return(TRUE);
}
}
/* print text with shadows, takes more than three times the time to print
normal text */
PrintDepth(RP, IT, X, Y, Fcol, Bcol)
struct RastPort *RP;
struct IntuiText *IT;
LONG X, Y;
UBYTE Fcol, Bcol;
{
UBYTE FP, DM;
if (!(Fcol | Bcol))
{
Fcol = light;
Bcol = dark;
}
FP = IT->FrontPen;
DM = IT->DrawMode;
IT->FrontPen = Fcol;
IT->DrawMode = JAM2;
PrintIText(RP, IT, X, Y); /* clear printing area */
IT->FrontPen = Bcol;
PrintIText(RP, IT, X + 1, Y + 1); /* shadow */
IT->FrontPen = Fcol;
IT->DrawMode = JAM1;
PrintIText(RP, IT, X, Y); /* print text over shadow */
IT->FrontPen = FP;
IT->DrawMode = DM;
}
ShowTables() /* just show the current tables */
{
int i, j;
UBYTE *SP;
struct PlayerData *PD;
SortResults(); /* always sort, even if nothing has changed. What a sin! */
PrintDepth(RPort, &SHeaderText, 20L, 49L, 0, 0);
SP = ResLine.IText;
for(i = 0; i < DISPLAYSIZE; i++)
{
for (j = 0; SP[j]; j++) SP[j] = ' ';
{
PD = &Data.Player[i];
strcpynz(&SP[plname_pos], PD->pl_name);
intcpynz(&SP[gp_pos], PD->gw + PD->gd + PD->gl);
intcpynz(&SP[gw_pos], PD->gw);
intcpynz(&SP[gd_pos], PD->gd);
intcpynz(&SP[gl_pos], PD->gl);
intcpynz(&SP[pt_pos], WinPoints*PD->gw + PD->gd);
longcpynz(&SP[gf_pos], PD->gf);
SP[line2_pos] = '-';
longcpynz(&SP[ga_pos], PD->ga);
if (PD->gw + PD->gd + PD->gl) ResLine.FrontPen = 1;
else ResLine.FrontPen = 3;
}
PrintIText(RPort, &ResLine, 20L, (LONG) 63 + i*8);
}
}
ShowResults() /* Show maximal the last 8 played matches results */
{
int i, j;
UBYTE *SP;
PrintDepth(RPort, &RHeaderText, 20L, 49L, 0, 0);
SP = ResLine.IText;
ResLine.FrontPen = 1;
for (i = 0; i < DISPLAYSIZE; i++)
{
for (j = 0; SP[j]; j++) SP[j] = ' ';
if (i < Data.games_played)
{
strcpynz(&SP[pl1name_pos], Data.LastResults[i].TeamA);
strcpynz(&SP[pl2name_pos], Data.LastResults[i].TeamB);
strcpynz(&SP[vs_pos], "vs");
longcpynz(&SP[pl1score_pos], Data.LastResults[i].pl1_score);
SP[line_pos] = '-';
longcpynz(&SP[pl2score_pos], Data.LastResults[i].pl2_score);
}
PrintIText(RPort, &ResLine, 20L, (LONG) 63 + i*8);
}
}
SortResults() /* probably the most inefficient sorting routine */
{
int i, j, h;
LONG saldo1, saldo2;
UWORD mp1, mp2, pts1, pts2;
for (i = 7; i >= 0; i--)
{
for (j = 0; j < i; j++)
{
h = j + 1;
/* first sort on points */
pts1 = Data.Player[j].gw*WinPoints + Data.Player[j].gd;
pts2 = Data.Player[h].gw*WinPoints + Data.Player[h].gd;
if (pts2 > pts1) Exchange(j, h);
else if (pts1 == pts2)
{
/* in case of equal points, sort on goal difference */
saldo1 = Data.Player[j].gf - Data.Player[j].ga;
saldo2 = Data.Player[h].gf - Data.Player[h].ga;
if (saldo2 > saldo1) Exchange(j, h);
else if (saldo1 == saldo2)
{
/* then on number of played matches */
mp1 = Data.Player[j].gw + Data.Player[j].gd + Data.Player[j].gl;
mp2 = Data.Player[h].gw + Data.Player[h].gd + Data.Player[h].gl;
if (mp1 > mp2) Exchange (j, h);
else if (mp1 == mp2)
{
/* and finally on number of matches won */
if (Data.Player[j].gw < Data.Player[h].gw) Exchange(j, h);
}
}
}
}
}
} /* boy, are these many brackets! */
Exchange(a, b) /* exchange two entries for sorting */
int a, b;
{
struct PlayerData PD;
PD = Data.Player[a];
Data.Player[a] = Data.Player[b];
Data.Player[b] = PD;
}
strcpynz(str1, str2) /* copy a string, but not the zero on the end */
UBYTE str1[], str2[];
{
int i = 0;
while (str2[i])
{
str1[i] = str2[i];
i++;
}
}
longcpynz(str1, A) /* convert a long int to a string */
UBYTE str1[];
ULONG A;
{
int i = 0;
while (A)
{
str1[i] = '0' + (A % 10);
A = A / 10;
i--; /* work from right to left */
}
if (!i) str1[i] = '0'; /* if A was 0, at least print that 0! */
}
intcpynz(str1, A) /* convert an int to a string */
UBYTE str1[];
UWORD A;
{
int i = 0;
while (A)
{
str1[i] = '0' + (A % 10);
A = A / 10;
i--; /* work from right to left */
}
if (!i) str1[i] = '0';
}