

/*
 *
 * Module	: hilow.c
 *
 * Description	: Card game to demonstrate the use of my IFF tools.
 *
 * Author	: Simon J Raybould.	(sie@fulcrum.bt.co.uk)
 *
 * Date		:  9th September 1990.
 *
 */

#include <stdio.h>
#include <signal.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>

#include "hilow.h"


main()
{
	struct Screen *OpenScreen();
	struct Window *OpenWindow();
	void CleanExit(), UpdateBank(), PlaySound(), Catch();
	int Cash = STARTCASH, Winnings;	/* In Pence */
	long Seed;

	signal(SIGINT, Catch);
	if(!(IntuitionBase = (struct IntuitionBase *)
				OpenLibrary("intuition.library", 33L))) {
		fprintf(stderr, "Failed to open intuition!!\n");
		CleanExit(1);
	}
	if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33L))) {
		fprintf(stderr, "Failed to open graphics!!\n");
		CleanExit(1);
	}
	if(!(Screen = OpenScreen(&NewScreen))) {
		fprintf(stderr, "Failed to open screen.\n");
		CleanExit(1);
	}
	NewWindow.Screen = Screen;
	if(!(Window = OpenWindow(&NewWindow))) {
		fprintf(stderr, "Failed to open window.\n");
		CleanExit(1);
	}
	LoadRGB4(&Screen->ViewPort, ColourTable, NCOLOURS);

	RPort = Window->RPort;	/* Stick this in a register */

	/* Get rid of title bar */
	SetAPen(RPort, 0);
	SetDrMd(RPort, JAM1);
	RectFill(RPort, 0, 0, 320, 10);

	/* Set seed for random numbers */
	time(&Seed);
	srand((unsigned)Seed);

	DRAWSIG;
	DrawImage(RPort, &TitleImage, TITLEX, TITLEY);

	SetAPen(RPort, 11);
	SetDrMd(RPort, JAM2);
	Move(RPort, BANKX+5, BANKY);
	Text(RPort, "Bank", 4);
	UpdateBank(Cash);

	SetAPen(RPort, 5);
	SetDrMd(RPort, JAM2);
	Move(RPort, 50, 100);
	Text(RPort, "Loading data, please wait", 25);

	if(InitCards()) {
		fprintf(stderr, "Can't find a pack of cards to use !!\n");
		CleanExit(1);
	}
	if(InitSounds()) {
		fprintf(stderr, "Can't find sound effects\n");
		CleanExit(1);
	}
	SetAPen(RPort, 5);
	SetDrMd(RPort, JAM2);
	Move(RPort, 10, 100);
	Text(RPort, "Ready to start, press DEAL to start", 35);
	while(Cash) {
		/* Wait before starting */
		switch(GetChoice()) {
		case CHOSE_QUIT:
			CleanExit(0);
			break;
		case CHOSE_DEAL:
			SetAPen(RPort, 0);
			SetDrMd(RPort, JAM1);
			RectFill(RPort, CARDX, CARDY, 320, CARDY+CHEIGHT+10);/*for Arw*/
			Cash -= PPERGAME;	/* Must pay before you play */
			UpdateBank(Cash);
			if((Winnings = Play()) == -1) {
				fprintf(stderr, "Problem encoutered during game\n");
				CleanExit(1);
			}
			Cash += Winnings;
			if(Winnings)
				UpdateBank(Cash);
			break;
		default:
			break;
		}
	}
	Delay(300);
	CleanExit(0);
}

Play()
{
	UBYTE TurnNo, CardNo;
	int Choice=0, LastCard = 0, ThisCard = 0;

	/* Display card backs */
	for(TurnNo=0; TurnNo<NTURNS; TurnNo++) {
		DisplayCard(TurnNo, 0);	/* Display card back */
		PlaySound(S_DEAL);
		Delay(5);
	}
	Delay(50);	/* Show all backs before turning first card */
	for(TurnNo=0; TurnNo<NTURNS; TurnNo++) {
		LastCard = ThisCard;
		if(TurnNo)	/* Don't wait for choice for first card i.e. Turn 0 */
			while(Choice!=CHOSE_QUIT && Choice!=CHOSE_HIGH && Choice!=CHOSE_LOW)
				if((Choice = GetChoice())<0)
					return -1;
		if(Choice == CHOSE_QUIT)
			CleanExit(0);
		/* Pick an unused card */
		CardNo = 0;
		while(!CardNo || CardUsed(TurnNo, CardNo))
			CardNo = rand()%51 + 1;
		ThisCard = (CardNo-1)%13;
		/* Display it */
		DisplayCard(TurnNo, CardNo);	/* Display card */
		PlaySound(S_TURN);
		/* Check to see if LOSE */
		if(TurnNo) {	/* Not first card */
			switch(Choice) {
			case CHOSE_HIGH:
				DrawImage(RPort, &UpAImage, TurnNo*(CARDX+CWIDTH+CGAP)-8,
						CARDY+CHEIGHT-2);
				if(ThisCard <= LastCard) {
					PlaySound(S_LOSE);
					return 0;
				}
				break;
			case CHOSE_LOW:
				DrawImage(RPort, &DnAImage, TurnNo*(CARDX+CWIDTH+CGAP)-8,
						CARDY+CHEIGHT-2);
				if(ThisCard >= LastCard) {
					PlaySound(S_LOSE);
					return 0;
				}
				break;
			default:
				return -1;
			}
		}
		Choice = 0;
	}
	PlaySound(S_WIN);
	return ((rand()%5+1)*10);
}

GetChoice()
{
	struct IntuiMessage *Message, *GetMsg();

	/* Clear message queue */
	while(Message = GetMsg(Window->UserPort))
		ReplyMsg(Message);

	/* Wait for event */
	Message = GetMsg(Window->UserPort);
	while (Message == NULL) {
		Wait(1<<Window->UserPort->mp_SigBit);
		Message = GetMsg(Window->UserPort);
	};
	if (Message)
		ReplyMsg(Message);

	switch(Message->Class) {
	case GADGETUP:
		if(Message->IAddress == (APTR)&HiGadg)
			return CHOSE_HIGH;
		if(Message->IAddress == (APTR)&LoGadg)
			return CHOSE_LOW;
		if(Message->IAddress == (APTR)&DealGadg)
			return CHOSE_DEAL;
		if(Message->IAddress == (APTR)&QuitGadg)
			return CHOSE_QUIT;
		break;
	default:
		fprintf(stderr, "Unkown message (0x%x) recieved\n", Message->Class);
		return -1;
	}
	return -1;
}

CardUsed(TNo, CNo)
UBYTE TNo, CNo;
{
	UBYTE i;
	static UBYTE CrdUsd[NTURNS];

	for(i=0; i<TNo; i++)
		if(CNo == CrdUsd[i])
			return TRUE;
	
	CrdUsd[TNo] = CNo;
	return FALSE;
}

void
CleanExit(Status)
int Status;
{
	FreeBitMaps();
	FreeSounds();
	if(Window)
		CloseWindow(Window);
	if(Screen)
		CloseScreen(Screen);
	if(GfxBase)
		CloseLibrary(GfxBase);
	if(IntuitionBase)
		CloseLibrary(IntuitionBase);
	exit(Status);
}

InitCards()
{
	int CardNo;
	char *CardBM[] = {
		"Back", "SA", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
		"S10", "SJ", "SQ", "SK", "CA", "C2", "C3", "C4", "C5", "C6",
		"C7", "C8", "C9", "C10", "CJ", "CQ", "CK", "HA", "H2", "H3",
		"H4", "H5", "H6", "H7", "H8", "H9", "H10", "HJ", "HQ", "HK",
		"DA", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10",
		"DJ", "DQ", "DK",
	};
	char Buffer[BUFSIZ];

	for(CardNo=0; CardNo<53; CardNo++) {
		sprintf(Buffer, "%s%s", BITMAPDIR, CardBM[CardNo]);
		if(SetUpBitMap(&CardArray[CardNo], Buffer))
			return -1;
	}
	return 0;
}

void
UpdateBank(Cash)	/* Cash is is pence */
int Cash;
{
	char Buffer[BUFSIZ];

	SetAPen(RPort, 3);
	SetDrMd(RPort, JAM2);
	Move(RPort, BANKX, BANKY+10);
	sprintf(Buffer, "%c%d.%02d   ", C_SYMBOL, Cash/100, Cash%100);
	Text(RPort, Buffer, strlen(Buffer));
}

DisplayCard(TNo, CNo)
int TNo, CNo;
{
	int x;

	if(TNo > NTURNS-1)
		return -1;

	x = (CWIDTH + CGAP) * TNo + CARDX;
	
	BltBitMapRastPort(&CardArray[CNo], 0, 0, RPort, x, CARDY, CWIDTH,
			CHEIGHT, MINTERM);
	return 0;
}

void
Catch(s)
int s;
{
	signal(SIGINT, SIG_IGN);	/* Lock out further breaks */
	fprintf(stderr, "Caught signal %d, exiting\n", s);
	CleanExit(1);
}
