www.pudn.com > coolMEMORY.rar > MemoryLogic.cpp
//-----------------------------------------------------------------------------
// File: MemoryLogic.cpp
//-----------------------------------------------------------------------------
#include "AS\AS_Engine.h"
#include "ModuleHeaders.h"
// Variables: *****************************************************************
cGAME_CONFIG cGameConfig; // All the game configurations
cSTYLE *pcCardStyle; // Pointer to the current card style in the game
// configuration for an faster access
cGAME_CARD *pcGameCard; // The game cards
cGAME_INFO cGameInfo; // The game information
AS_2D_VECTOR vPlayField[2]; // The play field min/max coords
BOOL bGameFinished, // Is the game finished?
bPressAnyKeyBlend, // For the blinking 'Press any key to continue' text
bFlashBlend; // Should the screen be blended?
float fGameFinishedBlend, // The blend value for the game finished screen
fPressAnyKeyBlend, // For the blinking 'Press any key to continue' text
fFlashBlend, // For blending the screen
fCupRot; // For the cup rotation:
// The screen positions of the player information:
INT2 iPlayerInfoPos[MAX_PLAYERS] = {{50, 460}, {500, 460}, {500, 100}, {50, 100}};
// The available card numbers:
INT2 iCardDimensionStencil[11] =
{
{4, 3}, // 12 cards = 6 pairs
{4, 4}, // 16 cards = 8 pairs
{5, 4}, // 20 cards = 10 pairs
{6, 5}, // 30 cards = 15 pairs
{6, 6}, // 36 cards = 18 pairs
{7, 6}, // 42 cards = 21 pairs
{8, 7}, // 56 cards = 28 pairs
{8, 8}, // 64 cards = 32 pairs
{9, 8}, // 72 cards = 36 pairs
{10, 9}, // 90 cards = 45 pairs
{10, 10}, // 100 cards = 50 pairs
};
// The camera position for each card dimension:
FLOAT2 fCardDimensionCamera[11] = // [0] = Zoom, [1] = y position
{
{-4.8f, -1.3f}, // 6 pairs
{-6.5f, -1.95f}, // 8 pairs
{-6.5f, -1.95f}, // 10 pairs
{-8.3f, -2.58f}, // 15 pairs
{-9.8f, -3.23f}, // 18 pairs
{-9.8f, -3.2f}, // 21 pairs
{-11.5f, -3.9f}, // 28 pairs
{-13.2f, -4.5f}, // 32 pairs
{-13.2f, -4.5f}, // 36 pairs
{-15.0f, -5.2f}, // 45 pairs
{-16.5f, -5.8f}, // 50 pairs
};
FLOAT3 fCardVertices[8] =
{
{-0.5f, 0.5f, -0.05f},
{0.5f, 0.5f, -0.05f},
{0.5f, -0.5f, -0.05f},
{-0.5f, -0.5f, -0.05f},
{-0.5f, -0.5f, 0.05f},
{0.5f, -0.5f, 0.05f},
{0.5f, 0.5f, 0.05f},
{-0.5f, 0.5f, 0.05f},
};
FLOAT2 fCardTexCoords[8] =
{
{0.0f, 1.0f},
{1.0f, 1.0f},
{1.0f, 0.0f},
{0.0f, 0.0f},
{1.0f, 0.0f},
{0.0f, 0.0f},
{0.0f, 1.0f},
{1.0f, 1.0f},
};
///////////////////////////////////////////////////////////////////////////////
// Functions: *****************************************************************
void InitGameCards(void);
void DestroyGameCards(void);
void DrawGameCards(void);
void PerformLightMapOnGameCarts(void);
void CheckGameCards(void);
void PerformLightMapOnGameCarts(void);
void DrawTableBackground(void);
void SetNextComputerSelectionTime(void);
///////////////////////////////////////////////////////////////////////////////
// cSTYLE functions: **********************************************************
cSTYLE::cSTYLE(void)
{ // begin cSTYLE::cSTYLE()
memset(this, 0, sizeof(cSTYLE));
} // end cSTYLE::cSTYLE()
cSTYLE::~cSTYLE(void)
{ // begin cSTYLE::~cSTYLE()
Destroy();
} // end cSTYLE::~cSTYLE()
BOOL cSTYLE::Load(char *pbyFilename)
{ // begin cSTYLE::Load()
char byCardTemp[256], byReadTemp[256], byInfoFile[256];
AS_PROGRESS_WINDOW ProgressWindow;
AS_TEXTURE *pTextureT;
sCARD *psCardT;
int iCard, i;
ProgressWindow.CreateProgressWindow("Card sytle");
ProgressWindow.SetTask("Loading...");
ProgressWindow.SetProgress(0);
_AS->WriteLogMessage("Load card style: %s", pbyFilename);
// First, destroy the old card style:
Destroy();
strcpy(byFolderName, pbyFilename);
// Get the absolute path:
sprintf(byFilename, "%s%s\\%s", _AS->byProgramPath, _AS->byCardStylesDirectory, pbyFilename);
sprintf(byInfoFile, "%s\\info.txt", byFilename);
// Get the style name:
sprintf(byReadTemp, "general_%s", _ASConfig->byLanguage);
GetPrivateProfileString(byReadTemp, "name", "Noname", byStyleName, 256, byInfoFile);
// Get the backside texture:
GetPrivateProfileString("general", "backside_texture", "Noname", byReadTemp, 256, byInfoFile);
sprintf(sTexture[0].byFilename, "%s\\%s", byFilename, byReadTemp);
GetPrivateProfileString("general", "side_texture", "Noname", byReadTemp, 256, byInfoFile);
sprintf(sTexture[1].byFilename, "%s\\%s", byFilename, byReadTemp);
GetPrivateProfileString("general", "environment_texture", "Noname", byReadTemp, 256, byInfoFile);
sprintf(sTexture[2].byFilename, "%s\\%s", byFilename, byReadTemp);
GetPrivateProfileString("general", "background_texture", "Noname", byReadTemp, 256, byInfoFile);
sprintf(sTexture[3].byFilename, "%s\\%s", byFilename, byReadTemp);
for(i = 0; i < 4; i++)
{
_AS->WriteLogMessage("texture: %s", sTexture[i].byFilename);
ASLoadJpegRGB(&sTexture[i], sTexture[i].byFilename);
if(!sTexture[i].iWidth)
_AS->WriteLogMessage("Couldn't load that texture!");
}
ProgressWindow.SetProgress(50);
// Get the number of cards:
iCards = GetPrivateProfileInt("general", "cards", 0, byInfoFile);
if(iCards)
{
sCard = (sCARD *) malloc(sizeof(sCARD)*iCards);
memset(sCard, 0, sizeof(sCARD)*iCards);
}
// Load in the cards:
_AS->WriteLogMessage("Load cards:");
for(iCard = 0; iCard < iCards; iCard++)
{
sprintf(byCardTemp, "card_%d", iCard+1);
_AS->WriteLogMessage(byCardTemp);
psCardT = &sCard[iCard];
// Load the texture:
pTextureT = &psCardT->Texture;
GetPrivateProfileString(byCardTemp, "texture", "", byReadTemp, 256, byInfoFile);
sprintf(pTextureT->byFilename, "%s\\%s", byFilename, byReadTemp);
_AS->WriteLogMessage("texture: %s", pTextureT->byFilename);
ASLoadJpegRGB(pTextureT, pTextureT->byFilename);
pTextureT->iID = iCard;
if(!pTextureT->iWidth)
_AS->WriteLogMessage("Couldn't load that texture!");
// Load the sound:
GetPrivateProfileString(byCardTemp, "sound", "", byReadTemp, 256, byInfoFile);
sprintf(psCardT->Sound.byFilename, "%s\\%s", byFilename, byReadTemp);
if(ASLoadFmodSample(&psCardT->Sound, psCardT->Sound.byFilename, i))
_AS->WriteLogMessage("Couldn't load this sound");
sprintf(byCardTemp, "card_%d_%s", iCard+1, _ASConfig->byLanguage);
// Get its name:
GetPrivateProfileString(byCardTemp, "name", "", psCardT->byName, 256, byInfoFile);
// Get its description:
GetPrivateProfileString(byCardTemp, "description", "", psCardT->byDescription, cCARD_DESCRIPTION_LENGTH, byInfoFile);
}
return FALSE;
} // end cSTYLE::Load()
void cSTYLE::Destroy(void)
{ // begin cSTYLE::Destroy()
// Destroy all card style textures:
for(int i = 0; i < 4; i++)
{
ASDestroyOpenGLTextures(1, &sTexture[i]);
ASDestroyTextures(1, &sTexture[i]);
}
// Destroy all card textures:
for(int iCard = 0; iCard < iCards; iCard++)
{
ASDestroyOpenGLTextures(1, &sCard[iCard].Texture);
ASDestroyTextures(1, &sCard[iCard].Texture);
ASDestroyFmodSample(&sCard[iCard].Sound);
}
// Free card memory:
SAFE_DELETE(sCard);
// Set all to null:
memset(this, 0, sizeof(cSTYLE));
} // end cSTYLE::Destroy()
void cSTYLE::GenOpenGLTextures(void)
{ // begin cSTYLE::GenOpenGLTextures()
AS_PROGRESS_WINDOW ProgressWindow;
AS_TEXTURE *pTextureT;
ProgressWindow.CreateProgressWindow("Card sytle");
ProgressWindow.SetTask("Generate OpenGL textures...");
ProgressWindow.SetProgress(0);
// Card style textures:
for(int i = 0; i < 4; i++)
{
ProgressWindow.SetSubTask("%s", sTexture[i].byFilename);
ProgressWindow.SetProgress((UINT) (((float) i/4)*100));
glGenTextures(1, &sTexture[i].iOpenGLID);
glBindTexture(GL_TEXTURE_2D, sTexture[i].iOpenGLID);
if(_ASConfig->bUseMipmaps)
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sTexture[i].iWidth, sTexture[i].iHeight, GL_RGB, GL_UNSIGNED_BYTE, sTexture[i].pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sTexture[i].iWidth, sTexture[i].iHeight, GL_RGB, GL_UNSIGNED_BYTE, sTexture[i].pbyData);
}
}
else
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, sTexture[i].iWidth, sTexture[i].iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, sTexture[i].pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, sTexture[i].iWidth, sTexture[i].iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, sTexture[i].pbyData);
}
}
}
// Card textures:
for(int iCard = 0; iCard < iCards; iCard++)
{
pTextureT = &sCard[iCard].Texture;
ProgressWindow.SetSubTask("%s", pTextureT->byFilename);
ProgressWindow.SetProgress((UINT) (((float) i/iCards)*100));
glGenTextures(1, &pTextureT->iOpenGLID);
glBindTexture(GL_TEXTURE_2D, pTextureT->iOpenGLID);
if(_ASConfig->bUseMipmaps)
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pTextureT->iWidth, pTextureT->iHeight, GL_RGB, GL_UNSIGNED_BYTE, pTextureT->pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pTextureT->iWidth, pTextureT->iHeight, GL_RGB, GL_UNSIGNED_BYTE, pTextureT->pbyData);
}
}
else
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, pTextureT->iWidth, pTextureT->iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pTextureT->pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, pTextureT->iWidth, pTextureT->iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pTextureT->pbyData);
}
}
}
} // end cSTYLE::GenOpenGLTextures()
void cSTYLE::DestroyOpenGLTextures(void)
{ // begin cSTYLE::DestroyOpenGLTextures()
AS_TEXTURE *pTextureT;
// Card style textures:
for(int i = 0; i < 4; i++)
{
if(sTexture[i].pbyData)
glDeleteTextures(1, &sTexture[i].iOpenGLID);
}
// Card textures:
for(int iCard = 0; iCard < iCards; iCard++)
{
pTextureT = &sCard[iCard].Texture;
if(!pTextureT || !pTextureT->pbyData)
continue;
glDeleteTextures(1, &pTextureT->iOpenGLID);
}
} // end cSTYLE::DestroyOpenGLTextures()
void cSTYLE::UpdateTextures(void)
{ // begin cSTYLE::UpdateTextures()
DestroyOpenGLTextures();
GenOpenGLTextures();
} // end cSTYLE::UpdateTextures()
///////////////////////////////////////////////////////////////////////////////
// cGAME_CONFIG functions: ****************************************************
cGAME_CONFIG::cGAME_CONFIG(void)
{ // begin cGAME_CONFIG::cGAME_CONFIG()
memset(this, 0, sizeof(cGAME_CONFIG));
} // end cGAME_CONFIG::cGAME_CONFIG()
void cGAME_CONFIG::SetStandart(void)
{ // begin cGAME_CONFIG::SetStandart()
// Reset all:
memset(this, 0, sizeof(cGAME_CONFIG));
// Setup players:
iPlayers = 4;
PlayerType[0] = PLAYER_TYPE_HUMAN;
PlayerType[1] = PLAYER_TYPE_COMPUTER_NORMAL;
PlayerType[2] = PLAYER_TYPE_COMPUTER_EASY;
PlayerType[3] = PLAYER_TYPE_COMPUTER_CLEVER;
// Setup other:
bShowCardsAtBeginning = TRUE;
iBeginningShowTime = 5;
bTimeLimit = FALSE;
iTimeLimit = 120;
bThinkTimeLimit = TRUE;
iThinkTime = 10;
bErrorLimit = TRUE;
iErrors = 5;
iRounds = 1;
iCardDimension = 3;
iCardPairs = iCardDimensionStencil[iCardDimension][X]*iCardDimensionStencil[iCardDimension][Y]/2;
// Load the standart card script:
cStyle.Load(_AS->byStandartCardStyle);
StartMusic(_AS->byStandartMusic);
} // end cGAME_CONFIG::SetStandart()
void cGAME_CONFIG::LoadAdvancedSettings(char *pbyFilename)
{ // begin cGAME_CONFIG::LoadAdvancedSettings()
char byTemp[256];
int i, iTemp;
if(!pbyFilename)
return;
// Game:
iPlayers = GetPrivateProfileInt("game", "players", 1, pbyFilename);
for(i = 0; i < 4; i++)
{
sprintf(byTemp, "player_%d", i+1);
iTemp = GetPrivateProfileInt("game", byTemp, 1, pbyFilename);
switch(iTemp)
{
case 0: PlayerType[i] = PLAYER_TYPE_HUMAN; break;
case 1: PlayerType[i] = PLAYER_TYPE_COMPUTER_EASY; break;
case 2: PlayerType[i] = PLAYER_TYPE_COMPUTER_NORMAL; break;
case 3: PlayerType[i] = PLAYER_TYPE_COMPUTER_CLEVER; break;
}
}
bShowCardsAtBeginning = GetPrivateProfileInt("game", "show_cards_at_beginning", 1, pbyFilename);
iBeginningShowTime = GetPrivateProfileInt("game", "beginning_show_time", 5, pbyFilename);
bTimeLimit = GetPrivateProfileInt("game", "is_time_limit", 0, pbyFilename);
iTimeLimit = GetPrivateProfileInt("game", "time_limit", 120, pbyFilename);
bThinkTimeLimit = GetPrivateProfileInt("game", "is_think_time_limit", 1, pbyFilename);
iThinkTime = GetPrivateProfileInt("game", "think_time_limit", 10, pbyFilename);
bErrorLimit = GetPrivateProfileInt("game", "is_error_limit", 1, pbyFilename);
iErrors = GetPrivateProfileInt("game", "error_limit", 5, pbyFilename);
iRounds = GetPrivateProfileInt("game", "rounds", 1, pbyFilename);
GetPrivateProfileString("game", "card_style", _AS->byStandartCardStyle, byTemp, MAX_PATH, pbyFilename);
cStyle.Load(byTemp);
GetPrivateProfileString("game", "music", _AS->byStandartMusic, byTemp, MAX_PATH, pbyFilename);
StartMusic(byTemp);
} // end cGAME_CONFIG::LoadAdvancedSettings()
void cGAME_CONFIG::SaveAdvancedSettings(char *pbyFilename)
{ // begin cGAME_CONFIG::SaveAdvancedSettings()
int i, iTemp;
FILE *pFile;
if(!pbyFilename)
return;
// Save the current configurations:
pFile = fopen(pbyFilename, "wt");
if(!pFile)
return;
// Game:
fprintf(pFile, "[game]\n");
fprintf(pFile, "players=%d\n", iPlayers);
for(i = 0; i < 4; i++)
{
switch(PlayerType[i])
{
case PLAYER_TYPE_HUMAN: iTemp = 0; break;
case PLAYER_TYPE_COMPUTER_EASY: iTemp = 1; break;
case PLAYER_TYPE_COMPUTER_NORMAL: iTemp = 2; break;
case PLAYER_TYPE_COMPUTER_CLEVER: iTemp = 3; break;
}
fprintf(pFile, "player_%d=%d\n", i+1, iTemp);
}
fprintf(pFile, "show_cards_at_beginning=%d\n", bShowCardsAtBeginning);
fprintf(pFile, "beginning_show_time=%d\n", iBeginningShowTime);
fprintf(pFile, "is_time_limit=%d\n", bTimeLimit);
fprintf(pFile, "time_limit=%d\n", iTimeLimit);
fprintf(pFile, "is_think_time_limit=%d\n", bThinkTimeLimit);
fprintf(pFile, "think_time_limit=%d\n", iThinkTime);
fprintf(pFile, "is_error_limit=%d\n", bErrorLimit);
fprintf(pFile, "error_limit=%d\n", iErrors);
fprintf(pFile, "rounds=%d\n", iRounds);
fprintf(pFile, "card_style=%s\n", cStyle.byFolderName);
fprintf(pFile, "music=%s\n", byCurrentMusic);
fclose(pFile);
return;
} // end cGAME_CONFIG::SaveAdvancedSettings()
///////////////////////////////////////////////////////////////////////////////
// cGAME_CARD functions: ******************************************************
void cGAME_CARD::Draw(BOOL bOnlyDeath)
{ // begin cGAME_CARD::Draw()
int i;
glColor3f(1.0f, 1.0f, 1.0f);
ASEnableLighting();
if((bOnlyDeath && !bGoingDeath) || !bOnlyDeath && bGoingDeath)
return;
// Setup position:
glPushMatrix();
glTranslatef(vWorldPos.fX, vWorldPos.fY, vWorldPos.fZ);
glRotatef(vRot.fX, 1.0f, 0.0f, 0.0f);
glRotatef((float) (vRot.fY+180.0f+180.0f*fSelectionRotSmoothTime), 0.0f, 1.0f, 0.0f);
glRotatef(vRot.fZ, 0.0f, 0.0f, 1.0f);
// Draw the card:
if(_ASConfig->bMultitexturing)
{
glActiveTextureARB(GL_TEXTURE1_ARB);
glColor3f(0.5f, 0.5f, 0.5f);
glBindTexture(GL_TEXTURE_2D, pcCardStyle->sTexture[2].iOpenGLID);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
if(bGoingDeath)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, fSelectionRotSmoothTime);
float f = (1.0f-fSelectionRotSmoothTime)*2+1.0f;
glScalef(f, f, f);
glDepthMask(FALSE);
}
else
glColor3f(1.0f, 1.0f, 1.0f);
// Front side:
glBindTexture(GL_TEXTURE_2D, pcCardStyle->sCard[iCard].Texture.iOpenGLID);
glDrawArrays(GL_QUADS, 0, 4);
// Backside:
glBindTexture(GL_TEXTURE_2D, pcCardStyle->sTexture[0].iOpenGLID);
glDrawArrays(GL_QUADS, 4, 7);
// The four sides:
glBindTexture(GL_TEXTURE_2D, pcCardStyle->sTexture[1].iOpenGLID);
glBegin(GL_QUADS);
// Left:
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glArrayElement(0);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glArrayElement(3);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glArrayElement(4);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glArrayElement(7);
// Top:
glArrayElement(5);
glArrayElement(4);
glArrayElement(3);
glArrayElement(2);
// Right:
glArrayElement(6);
glArrayElement(5);
glArrayElement(2);
glArrayElement(1);
// Bottom:
glArrayElement(7);
glArrayElement(6);
glArrayElement(1);
glArrayElement(0);
glEnd();
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glActiveTextureARB(GL_TEXTURE0_ARB);
// Now draw the selection bounding if the card is under the mouse or selected:
if(fSelectionColor[R] != 0.0f || fSelectionColor[G] != 0.0f || fSelectionColor[B] != 0.0f)
{
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glDepthMask(FALSE);
FLOAT4 fColor = {fSelectionColor[R], fSelectionColor[G], fSelectionColor[B], fSelectionColor[A]};
FLOAT4 fBlack = {0.0f, 0.0f, 0.0f, 0.0f};
glBindTexture(GL_TEXTURE_2D, Caust1Texture[iSelectionAniStep].iOpenGLID);
for(i = 0; i < 2; i++)
{
if(!i)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBegin(GL_QUADS);
// Left side:
glColor4fv(fBlack);
glTexCoord2f(0.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][0].fV);
glTexCoord2f(1.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][1].fV);
glColor4fv(fColor);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(-0.5f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-0.5f, -0.5f);
glColor4fv(fBlack);
glTexCoord2f(0.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][1].fV);
glTexCoord2f(1.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][2].fV);
glColor4fv(fColor);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(-0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-0.5f, 0.0f);
// Top side:
glColor4fv(fColor);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.0f, -0.5f);
glColor4fv(fBlack);
glTexCoord2f(1.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][3].fV);
glTexCoord2f(0.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][0].fV);
glColor4fv(fColor);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, -0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.5f, -0.5f);
glColor4fv(fBlack);
glTexCoord2f(1.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][4].fV);
glTexCoord2f(0.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][3].fV);
// Right side:
glColor4fv(fColor);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.5f, 0.0f);
glColor4fv(fBlack);
glTexCoord2f(1.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][5].fV);
glTexCoord2f(0.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][4].fV);
glColor4fv(fColor);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glColor4fv(fBlack);
glTexCoord2f(1.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][6].fV);
glTexCoord2f(0.0f, 1.0f);
glVertex3fv(vAniSelectionPoints[1][5].fV);
// Bottom side:
glColor4fv(fBlack);
glTexCoord2f(0.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][2].fV);
glTexCoord2f(1.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][7].fV);
glColor4fv(fColor);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(0.0f, 0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(-0.5f, 0.5f);
glColor4fv(fBlack);
glTexCoord2f(0.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][7].fV);
glTexCoord2f(1.0f, 0.0f);
glVertex3fv(vAniSelectionPoints[1][6].fV);
glColor4fv(fColor);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 0.5f);
glEnd();
}
glDepthMask(TRUE);
ASEnableLighting();
glEnable(GL_CULL_FACE);
}
glDisable(GL_BLEND);
glDepthMask(TRUE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glPopMatrix();
} // end cGAME_CARD::Draw()
void cGAME_CARD::PerformLighmap(AS_DLIGHT cLight)
{ // begin cGAME_CARD::PerformLighmap()
AS_3D_VECTOR vCardVerticesT[8];
int i;
for(i = 0; i < 8; i++)
{
ASRotateVectorX(fCardVertices[i], vRot.fX, &vCardVerticesT[i].fV);
ASRotateVectorY(vCardVerticesT[i].fV, (float) (vRot.fY+180.0f+180.0f*fSelectionRotSmoothTime), &vCardVerticesT[i].fV);
ASRotateVectorZ(vCardVerticesT[i].fV, vRot.fZ, &vCardVerticesT[i].fV);
vCardVerticesT[i] *= 1.005f;
vCardVerticesT[i] += vWorldPos;
}
// Front side:
cLight.Light(vCardVerticesT[0], vCardVerticesT[1], vCardVerticesT[2]);
cLight.Light(vCardVerticesT[2], vCardVerticesT[3], vCardVerticesT[0]);
// Backside:
cLight.Light(vCardVerticesT[4], vCardVerticesT[5], vCardVerticesT[6]);
cLight.Light(vCardVerticesT[6], vCardVerticesT[7], vCardVerticesT[4]);
} // end cGAME_CARD::PerformLighmap()
void cGAME_CARD::Check(void)
{ // begin cGAME_CARD::Check()
int i, i2;
// Animate the texture of the selection bounding:
if(g_lGameTimer-lSelectionAniTime > 25 || g_lGameTimer-lSelectionAniTime < 0)
{
lSelectionAniTime = g_lGameTimer;
iSelectionAniStep++;
if(iSelectionAniStep >= 32)
iSelectionAniStep = 0;
}
if(bGoingDeath)
vWorldPos.fZ -= (float) g_lDeltatime/500;
// Animate the selection bounding itself:
if(fSelectionColor[R] != 0.0f || fSelectionColor[G] != 0.0f || fSelectionColor[B] != 0.0f)
{
for(i = 0; i < 8; i++)
{
for(i2 = 0; i2 < 3; i2++)
{
if(vAniSelectionPoints[NEW_POINT][i].fV[i2] > vAniSelectionPoints[LAST_POINT][i].fV[i2])
{
vAniSelectionPoints[POINT_VELOCITY][i].fV[i2] += (float) g_lDeltatime/50000;
vAniSelectionPoints[CURRENT_POINT][i].fV[i2] += vAniSelectionPoints[POINT_VELOCITY][i].fV[i2]/5;
if(vAniSelectionPoints[CURRENT_POINT][i].fV[i2] > vAniSelectionPoints[NEW_POINT][i].fV[i2])
{
goto GetNewPoint;
}
}
else
{
vAniSelectionPoints[POINT_VELOCITY][i].fV[i2] -= (float) g_lDeltatime/50000;
vAniSelectionPoints[CURRENT_POINT][i].fV[i2] += vAniSelectionPoints[POINT_VELOCITY][i].fV[i2]/5;
if(vAniSelectionPoints[CURRENT_POINT][i].fV[i2] < vAniSelectionPoints[NEW_POINT][i].fV[i2])
{
goto GetNewPoint;
}
}
continue;
GetNewPoint:
vAniSelectionPoints[POINT_VELOCITY][i].fV[i2] *= 0.3f;
vAniSelectionPoints[LAST_POINT][i].fV[i2] = vAniSelectionPoints[CURRENT_POINT][i].fV[i2];
if(!(rand() % 2))
vAniSelectionPoints[NEW_POINT][i].fV[i2] = vAniSelectionPoints[FIX_POINT][i].fV[i2]+((float) (rand() % 1000)/8000);
else
vAniSelectionPoints[NEW_POINT][i].fV[i2] = vAniSelectionPoints[FIX_POINT][i].fV[i2]-((float) (rand() % 1000)/8000);
}
}
}
} // end cGAME_CARD::Check()
///////////////////////////////////////////////////////////////////////////////
// cGAME_INFO functions: ******************************************************
void cGAME_INFO::Reset(void)
{ // begin cGAME_INFO::Reset()
iSelectedCard[0] = iSelectedCard[1] = -1;
iCurrentPlayer = 0;
iCardPairsOnTable = cGameConfig.iCardPairs;
iCurrentRound = 0;
memset(sPlayerInfo, 0, sizeof(sPLAYER_INFO)*MAX_PLAYERS);
lTimeLimit = g_lGameTimer;
iTimeLimitPastSeconds = 0;
} // end cGAME_INFO::Reset()
void cGAME_INFO::ShowInfo(AS_WINDOW *pWindow)
{ // begin cGAME_INFO::ShowInfo()
char byTemp[256];
float fTime;
int i, i2, iCheck, iWinner, iY;
if(!Setup.bShowHud)
return;
if(cGameInfo.bShowCardsAtBeginng)
{ // Show card show bar:
fTime = 1.0f-((float) cGameInfo.iShowCardsAtBeginningPastSeconds/cGameConfig.iBeginningShowTime);
glLoadIdentity();
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(-1.0f, -0.6f, -2.0f);
glRotatef(110.0f, 1.0f, 1.0f, 1.0f);
glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glBegin(GL_QUADS);
glVertex2f(-0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, 0.06f);
glVertex2f(-0.01f, 0.06f);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glColor4f(1.0f-fTime, 0.0f, fTime, 1.0f);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f*fTime, 0.0f);
glVertex2f(1.0f*fTime, 0.05f);
glVertex2f(0.0f, 0.05f);
glEnd();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
}
else
{
if(cGameConfig.bThinkTimeLimit)
{ // Show think time bar:
fTime = 1.0f-((float) cGameInfo.iThinkTimePastSeconds/cGameConfig.iThinkTime);
glLoadIdentity();
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(-1.0f, -0.6f, -2.0f);
glRotatef(110.0f, 1.0f, 1.0f, 1.0f);
glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glBegin(GL_QUADS);
glVertex2f(-0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, 0.06f);
glVertex2f(-0.01f, 0.06f);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glColor4f(1.0f-fTime, 0.0f, fTime, 1.0f);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f*fTime, 0.0f);
glVertex2f(1.0f*fTime, 0.05f);
glVertex2f(0.0f, 0.05f);
glEnd();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
}
}
if(cGameConfig.bTimeLimit)
{ // Show the time bar
fTime = 1.0f-((float) cGameInfo.iTimeLimitPastSeconds/cGameConfig.iTimeLimit);
glLoadIdentity();
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(-0.5f, 0.785f, -2.0f);
glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glBegin(GL_QUADS);
glVertex2f(-0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, -0.01f);
glVertex2f(1.0f*fTime+0.01f, 0.03f);
glVertex2f(-0.01f, 0.03f);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glColor4f(1.0f-fTime, 0.0f, fTime, 1.0f);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f*fTime, 0.0f);
glVertex2f(1.0f*fTime, 0.02f);
glVertex2f(0.0f, 0.02f);
glEnd();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
}
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Show the number of the current round:
if(cGameConfig.iRounds > 1)
{
sprintf(byTemp, "%s: %d", T_Round, iCurrentRound+1);
pWindow->PrintAnimated(320, 450, byTemp, 0, 1.0f, fFontAni, 1);
}
for(i = 0; i < cGameConfig.iPlayers; i++)
ShowPlayerInfo(pWindow, i);
if(fGameFinishedBlend)
{ // Draw the game finished screen:
// Draw the dark blending quad:
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glColor4f(0.1f, 0.1f, 0.1f, 1.1f-fGameFinishedBlend);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -24.0f);
glBegin(GL_QUADS);
glVertex2f(-15.0f, -11.0f);
glVertex2f( 15.0f, -11.0f);
glVertex2f( 15.0f, 11.0f);
glVertex2f(-15.0f, 11.0f);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
// Print the text:
glColor4f(1.0f, 1.0f, 1.0f, fGameFinishedBlend);
pWindow->PrintAnimated(320, 420, T_GameFinished, 0, 2.0f, fFontAni, 1);
pWindow->PrintAnimated(320, 380, T_Result, 0, 1.5f, fFontAni, 1);
if(cGameConfig.bTimeLimit)
{
sprintf(byTemp, "%s: %d %s", T_GameDuration, cGameInfo.iTimeLimitPastSeconds-1, T_Seconds);
pWindow->PrintAnimated(320, 350, byTemp, 0, 1.0f, fFontAni, 1);
}
for(i = 0, iY = 300; i < cGameConfig.iPlayers; i++, iY -= 80)
{
sprintf(byTemp, "%s %d:", T_Player, i+1);
pWindow->PrintAnimated(200, iY, byTemp, 0, 1.3f, fFontAni, 1);
sprintf(byTemp, "%s %d:", T_FoundCardPairs, cGameInfo.sPlayerInfo[i].iCardPairs);
pWindow->PrintAnimated(400, iY-20, byTemp, 0, 1.0f, fFontAni, 1);
}
glColor4f(1.0f, 1.0f, 1.0f, fPressAnyKeyBlend);
pWindow->PrintAnimated(320, 10, M_PressAnyKeyToContinue, 0, 1.0f, fFontAni, 1);
// Draw the cup:
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
ASEnableLighting();
// Get the winner: (if there is one...)
iWinner = -1;
if(cGameConfig.iPlayers == 1)
iWinner = 0;
else
for(i = 0; i < cGameConfig.iPlayers; i++)
{
for(iCheck = 0, i2 = 0; i2 < cGameConfig.iPlayers; i2++)
{
if(i == i2)
continue;
if(cGameInfo.sPlayerInfo[i].iCardPairs > cGameInfo.sPlayerInfo[i2].iCardPairs)
iCheck++;
}
if(iCheck == cGameConfig.iPlayers-1)
{ // This is our winner!
iWinner = i;
break;
}
}
if(iWinner != -1)
{
glLoadIdentity();
glTranslatef(-0.8f, 0.1f-0.29f*iWinner, -2.0f);
glRotatef(20.0f, 1.0f, 0.0f, 0.0f);
glRotatef(fCupRot, 0.0f, 1.0f, 0.0f);
glScalef(0.002f, 0.002f, 0.002f);
fCupRot += (float) g_lDeltatime/50;
glEnable(GL_TEXTURE_2D);
glColor4f(1.0f, 1.0f, 1.0f, fGameFinishedBlend);
glBindTexture(GL_TEXTURE_2D, GameTexture[2].iOpenGLID);
ASDrawMd2Frame(pCupModel, 0);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glColor4f(1.0f, 1.0f, 1.0f, fGameFinishedBlend-0.3f);
glBindTexture(GL_TEXTURE_2D, GameTexture[3].iOpenGLID);
ASDrawMd2Frame(pCupModel, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
}
}
if(fFlashBlend)
{ // Blend the screen:
glColor4f(1.0f, 1.0f, 1.0f, fFlashBlend);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -24.0f);
glBegin(GL_QUADS);
glVertex2f(-15.0f, -11.0f);
glVertex2f( 15.0f, -11.0f);
glVertex2f( 15.0f, 11.0f);
glVertex2f(-15.0f, 11.0f);
glEnd();
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
}
} // end cGAME_INFO::ShowInfo()
void cGAME_INFO::ShowPlayerInfo(AS_WINDOW *pWindow, int iPlayer)
{ // begin cGAME_INFO::ShowPlayerInfo()
char byTemp[256];
INT2 iPlayerInfoPos[MAX_PLAYERS] = {{10, 450}, {440, 450}, {440, 20}, {10, 20}};
// Show the number of the player:
sprintf(byTemp, "%d", iPlayer+1);
pWindow->PrintAnimated(iPlayerInfoPos[iPlayer][X], (int) (iPlayerInfoPos[iPlayer][Y]-(10.0f-10.0f*cos(sin(sPlayerInfo[iPlayer].fActiveBlend)*PI))),
byTemp, 0, 1.0f+(float) (1.5f-1.5f*cos(sin(sPlayerInfo[iPlayer].fActiveBlend)*PI)), fFontAni, 1);
// Show the number of pairs this player has:
sprintf(byTemp, "%s: %d", T_CardPairs, sPlayerInfo[iPlayer].iCardPairs);
pWindow->PrintAnimated(iPlayerInfoPos[iPlayer][X]+30, iPlayerInfoPos[iPlayer][Y],
byTemp, 0, 1.0f, fFontAni, 0);
} // end cGAME_INFO::ShowPlayerInfo()
void cGAME_INFO::Check(void)
{ // begin cGAME_INFO::Check()
int i;
// Screen blend:
if(bFlashBlend)
{
fFlashBlend += (float) g_lDeltatime/1000;
if(fFlashBlend > 1.0f)
{
fFlashBlend = 1.0f;
bFlashBlend = FALSE;
}
}
else
{
fFlashBlend -= (float) g_lDeltatime/1000;
if(fFlashBlend < 0.0f)
fFlashBlend = 0.0f;
}
// Game finished:
if(bGameFinished)
{
fGameFinishedBlend += (float) g_lDeltatime/1000;
if(fGameFinishedBlend > 1.0f)
fGameFinishedBlend = 1.0f;
// Animate the 'Press any key to continue' text:
if(!bPressAnyKeyBlend)
{
fPressAnyKeyBlend += (float) g_lDeltatime/1000;
if(fPressAnyKeyBlend > 1.0f)
{
fPressAnyKeyBlend = 1.0f;
bPressAnyKeyBlend = 1;
}
}
else
{
fPressAnyKeyBlend -= (float) g_lDeltatime/1000;
if(fPressAnyKeyBlend < 0.0f)
{
fPressAnyKeyBlend = 0.0f;
bPressAnyKeyBlend = 0;
}
}
if(ASIsKeyPressed())
_AS->SetNextModule(MODULE_MENU);
return;
}
else
{
fGameFinishedBlend -= (float) g_lDeltatime/1000;
if(fGameFinishedBlend < 0.0f)
fGameFinishedBlend = 0.0f;
fPressAnyKeyBlend -= (float) g_lDeltatime/1000;
if(fPressAnyKeyBlend < 0.0f)
{
fPressAnyKeyBlend = 0.0f;
bPressAnyKeyBlend = 0;
}
}
// Check card beginning show:
if(bShowCardsAtBeginng)
{
if(g_lGameTimer-lShowCardsAtBeginningTime > 1000)
{
lShowCardsAtBeginningTime = g_lGameTimer;
iShowCardsAtBeginningPastSeconds++;
if(iShowCardsAtBeginningPastSeconds > cGameConfig.iBeginningShowTime)
{
bShowCardsAtBeginng = FALSE;
lTimeLimit = lThinkTime = g_lGameTimer;
}
}
if(ASIsKeyPressed())
{
lTimeLimit = lThinkTime = g_lGameTimer;
bShowCardsAtBeginng = FALSE;
}
return;
}
// Check time limit:
if(cGameConfig.bTimeLimit)
{
if(g_lGameTimer-cGameInfo.lTimeLimit > 1000)
{
cGameInfo.lTimeLimit = g_lGameTimer;
cGameInfo.iTimeLimitPastSeconds++;
if(cGameInfo.iTimeLimitPastSeconds > cGameConfig.iTimeLimit)
{ // The time is out, the game is now finished:
cGameInfo.iCardPairsOnTable = 0;
cGameInfo.iSelectedCard[0] = cGameInfo.iSelectedCard[1] = -1;
}
}
}
// Check think time:
if(cGameConfig.bThinkTimeLimit && (cGameInfo.iSelectedCard[0] == -1 ||
cGameInfo.iSelectedCard[1] == -1))
{
if(g_lGameTimer-lThinkTime > 1000)
{
lThinkTime = g_lGameTimer;
iThinkTimePastSeconds++;
if(iThinkTimePastSeconds > cGameConfig.iThinkTime)
{ // The think time is over:
if(cGameConfig.iPlayers == 1)
{ // There is only one player:
cGameInfo.iCardPairsOnTable = 0;
cGameInfo.iSelectedCard[0] = cGameInfo.iSelectedCard[1] = -1;
return;
}
// Switch to the next player:
iThinkTimePastSeconds = 0;
cGameInfo.iCurrentPlayer++;
if(cGameInfo.iCurrentPlayer >= cGameConfig.iPlayers)
cGameInfo.iCurrentPlayer = 0;
}
}
}
// Check the players:
for(i = 0; i < cGameConfig.iPlayers; i++)
{
if(i == iCurrentPlayer)
{
sPlayerInfo[i].fActiveBlend += (float) g_lDeltatime/1000;
if(sPlayerInfo[i].fActiveBlend > 1.0f)
sPlayerInfo[i].fActiveBlend = 1.0f;
}
else
{
sPlayerInfo[i].fActiveBlend -= (float) g_lDeltatime/1000;
if(sPlayerInfo[i].fActiveBlend < 0.0f)
sPlayerInfo[i].fActiveBlend = 0.0f;
}
}
CheckGameCards();
} // end cGAME_INFO::Check()
///////////////////////////////////////////////////////////////////////////////
void InitGameCards(void)
{ // begin InitGameCards()
cGAME_CARD *pcGameCardT;
INT2 *iCard; // [0] = Card [1] = Still to spread
int i, i2, i3, iRemeber, iGetCard, iX, iY, iTemp;
// Get memory:
SAFE_DELETE(pcGameCard);
pcGameCard = (cGAME_CARD *) malloc(sizeof(cGAME_CARD)*cGameConfig.iCardPairs*2);
// Initialize the cards:
g_lGameTimer = 0;
vPlayField[MIN] = 1000;
vPlayField[MAX] = -1000;
for(i = 0, iY = 0; iY < iCardDimensionStencil[cGameConfig.iCardDimension][Y]; iY++)
for(iX = 0; iX < iCardDimensionStencil[cGameConfig.iCardDimension][X]; iX++, i++)
{
pcGameCardT = &pcGameCard[i];
memset(pcGameCardT, 0, sizeof(cGAME_CARD));
pcGameCardT->iID = i;
pcGameCardT->iCard = -1;
pcGameCardT->bActive = TRUE;
pcGameCardT->vWorldPos.fX = iX*1.2f;
pcGameCardT->vWorldPos.fY = iY*1.2f;
pcGameCardT->vWorldPos.fZ = 0.0f;
pcGameCardT->lSelectionAniTime = g_lGameTimer;
pcGameCardT->iSelectionAniStep = rand() % 32;
memset(pcGameCardT->fSelectionColor, 0, sizeof(FLOAT4));
pcGameCardT->vAniSelectionPoints[0][0].fX = pcGameCardT->vAniSelectionPoints[1][0].fX = -0.7f;
pcGameCardT->vAniSelectionPoints[0][0].fY = pcGameCardT->vAniSelectionPoints[1][0].fY = -0.7f;
pcGameCardT->vAniSelectionPoints[0][1].fX = pcGameCardT->vAniSelectionPoints[1][1].fX = -0.7f;
pcGameCardT->vAniSelectionPoints[0][1].fY = pcGameCardT->vAniSelectionPoints[1][1].fY = 0.0f;
pcGameCardT->vAniSelectionPoints[0][2].fX = pcGameCardT->vAniSelectionPoints[1][2].fX = -0.7f;
pcGameCardT->vAniSelectionPoints[0][2].fY = pcGameCardT->vAniSelectionPoints[1][2].fY = 0.7f;
pcGameCardT->vAniSelectionPoints[0][3].fX = pcGameCardT->vAniSelectionPoints[1][3].fX = 0.0f;
pcGameCardT->vAniSelectionPoints[0][3].fY = pcGameCardT->vAniSelectionPoints[1][3].fY = -0.7f;
pcGameCardT->vAniSelectionPoints[0][4].fX = pcGameCardT->vAniSelectionPoints[1][4].fX = 0.7f;
pcGameCardT->vAniSelectionPoints[0][4].fY = pcGameCardT->vAniSelectionPoints[1][4].fY = -0.7f;
pcGameCardT->vAniSelectionPoints[0][5].fX = pcGameCardT->vAniSelectionPoints[1][5].fX = 0.7f;
pcGameCardT->vAniSelectionPoints[0][5].fY = pcGameCardT->vAniSelectionPoints[1][5].fY = 0.0f;
pcGameCardT->vAniSelectionPoints[0][6].fX = pcGameCardT->vAniSelectionPoints[1][6].fX = 0.7f;
pcGameCardT->vAniSelectionPoints[0][6].fY = pcGameCardT->vAniSelectionPoints[1][6].fY = 0.7f;
pcGameCardT->vAniSelectionPoints[0][7].fX = pcGameCardT->vAniSelectionPoints[1][7].fX = 0.0f;
pcGameCardT->vAniSelectionPoints[0][7].fY = pcGameCardT->vAniSelectionPoints[1][7].fY = 0.7f;
for(i3 = 0; i3 < 8; i3++)
{
for(i2 = 0; i2 < 3; i2++)
{
pcGameCardT->vAniSelectionPoints[LAST_POINT][i3].fV[i2] = pcGameCardT->vAniSelectionPoints[CURRENT_POINT][i3].fV[i2];
if(!(rand() % 2))
pcGameCardT->vAniSelectionPoints[NEW_POINT][i3].fV[i2] = pcGameCardT->vAniSelectionPoints[FIX_POINT][i3].fV[i2]+(rand() % 1000)/10000;
else
pcGameCardT->vAniSelectionPoints[NEW_POINT][i3].fV[i2] = pcGameCardT->vAniSelectionPoints[FIX_POINT][i3].fV[i2]-(rand() % 1000)/10000;
}
}
// Updata min/max of the play field:
for(i2 = 0; i2 < 2; i2++)
{
if(pcGameCardT->vWorldPos.fV[i2] < vPlayField[MIN].fV[i2])
vPlayField[MIN].fV[i2] = pcGameCardT->vWorldPos.fV[i2];
if(pcGameCardT->vWorldPos.fV[i2] > vPlayField[MAX].fV[i2])
vPlayField[MAX].fV[i2] = pcGameCardT->vWorldPos.fV[i2];
}
}
vPlayField[MIN] -= 2.0f;
vPlayField[MAX] += 2.0f;
// Setup cards:
iCard = (INT2 *) malloc(sizeof(INT2)*cGameConfig.iCardPairs);
for(i = 0; i < cGameConfig.iCardPairs; i++)
{
iCard[i][0] = -1;
iCard[i][1] = 2;
}
for(i = 0; i < cGameConfig.iCardPairs; i++)
{
iCard[i][0] = rand() % pcCardStyle->iCards;
// Check if another card has this number already:
for(i2 = 0; i2 < cGameConfig.iCardPairs; i2++)
{
if(i != i2 && iCard[i][0] == iCard[i2][0])
break;
}
if(i2 != cGameConfig.iCardPairs)
{
i--;
continue;
}
}
// Spread chosen cards:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
iTemp = rand() % cGameConfig.iCardPairs;
if(!iCard[iTemp][1])
{
i--;
continue; // Already awarded
}
iCard[iTemp][1]--;
pcGameCard[i].iCard = iCard[iTemp][0];
cGameInfo.iError[i] = cGameConfig.iErrors;
}
free(iCard);
cGameInfo.iCardPairsOnTable = cGameConfig.iCardPairs;
g_lGameTimer = 0;
cGameInfo.iSelectedCard[0] = -1;
cGameInfo.iSelectedCard[1] = -1;
bGameFinished = FALSE;
fGameFinishedBlend = 0.0f;
fFlashBlend = 1.0f;
// Clear the computer brains:
for(i = 0; i < 4; i++)
for(i2 = 0; i2 < MAX_CARD_PAIRS; i2++)
cGameInfo.sPlayerInfo[i].bComputerMemory[i2] = FALSE;
if(cGameConfig.bShowCardsAtBeginning)
{ // Show the cards:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
pcGameCard[i].fSelectionRotTime = pcGameCard[i].fSelectionRotSmoothTime = 1.0f;
cGameInfo.bShowCardsAtBeginng = TRUE;
cGameInfo.lShowCardsAtBeginningTime = g_lGameTimer;
cGameInfo.iShowCardsAtBeginningPastSeconds = 0;
// The computer player could hold some cards in their brain:
for(i = 0; i < 4; i++)
{
// Get the number of cards the computer could remember on:
switch(cGameConfig.PlayerType[i])
{
case PLAYER_TYPE_COMPUTER_EASY:
// Get the number of cards the computer could remember on:
iRemeber = rand() % cGameConfig.iBeginningShowTime;
break;
case PLAYER_TYPE_COMPUTER_NORMAL:
iRemeber = 4+rand() % cGameConfig.iBeginningShowTime;
break;
case PLAYER_TYPE_COMPUTER_CLEVER:
iRemeber = 10+rand() % cGameConfig.iBeginningShowTime;
break;
default:
continue;
}
for(i3 = 0, i2 = 0; i3 < iRemeber; i3++, i2++)
{
if(i2 > 1000)
break;
iGetCard = rand() % (cGameConfig.iCardPairs*2);
if(cGameInfo.sPlayerInfo[i].bComputerMemory[iGetCard])
{
i3--; // Find another card!
continue;
}
cGameInfo.sPlayerInfo[i].bComputerMemory[iGetCard] = TRUE;
cGameInfo.sPlayerInfo[i].lComputerSeeTime[iGetCard] = g_lGameTimer;
}
}
}
cGameInfo.lThinkTime = g_lGameTimer;
cGameInfo.iThinkTimePastSeconds = 0;
} // InitGameCards()
void DestroyGameCards(void)
{ // begin DestroyGameCards()
SAFE_DELETE(pcGameCard);
} // end DestroyGameCards()
void DrawGameCards(void)
{ // begin DrawGameCards()
int i;
glEnable(GL_CULL_FACE);
// Setup render stuff:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, fCardVertices);
glTexCoordPointer(2, GL_FLOAT, 0, fCardTexCoords);
glDisable(GL_BLEND);
if(_AS->bCompiledVertexArraySupported)
glLockArraysEXT(0, 8);
// Draw only none transparent cards:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
if(!pcGameCard[i].bActive)
continue;
pcGameCard[i].Draw(false);
}
// Draw only transparent cards: (if they going death)
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
if(!pcGameCard[i].bActive)
continue;
pcGameCard[i].Draw(true);
}
if(_AS->bCompiledVertexArraySupported)
glUnlockArraysEXT();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} // end DrawGameCards()
void PerformLightMapOnGameCarts(void)
{ // begin PerformLightMapOnGameCarts()
AS_DLIGHT cLight1;
if(!_ASConfig->bLightmaps || cGameConfig.PlayerType[cGameInfo.iCurrentPlayer] != PLAYER_TYPE_HUMAN)
return;
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, GameTexture[1].iOpenGLID);
glDepthMask(FALSE);
glDisable(GL_LIGHTING);
cLight1.fRadius = 3.0f;
cLight1.vPos = vMouseWorldPos;
cLight1.vColor = 0.5f;
glBegin(GL_TRIANGLES);
for(int i = 0; i < cGameConfig.iCardPairs*2; i++)
{
if(!pcGameCard[i].bActive)
continue;
pcGameCard[i].PerformLighmap(cLight1);
}
glEnd();
glDepthMask(TRUE);
} // end PerformLightMapOnGameCarts()
void CheckGameCards(void)
{ // begin CheckGameCards()
int i, i2, iCard, iTime;
cGAME_CARD *pcGameCardT;
sPLAYER_INFO *psPlayerT;
if(cGameInfo.bShowCardsAtBeginng)
return;
// Check if the game is finished:
if(cGameInfo.iCardPairsOnTable <= 0 && cGameInfo.iSelectedCard[0] == -1 &&
cGameInfo.iSelectedCard[1] == -1)
{
if(cGameConfig.bTimeLimit && cGameInfo.iTimeLimitPastSeconds < cGameConfig.iTimeLimit)
{
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
if(pcGameCard[i].bActive)
break;
}
else
i = cGameConfig.iCardPairs*2;
if(i == cGameConfig.iCardPairs*2)
{ // All cards are deactivated:
cGameInfo.iCurrentRound++;
if(cGameInfo.iCurrentRound >= cGameConfig.iRounds ||
(cGameConfig.bTimeLimit && cGameInfo.iTimeLimitPastSeconds > cGameConfig.iTimeLimit))
{ // The game is now finished:
bGameFinished = TRUE;
return;
}
else
{ // Go into the next round:
bFlashBlend = TRUE;
if(fFlashBlend >= 1.0f)
InitGameCards();
else
return;
}
}
}
// Reset all cards:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
pcGameCard[i].bUnderMouse = FALSE;
// Select the card under the mouse:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
pcGameCardT = &pcGameCard[i];
if(!pcGameCardT->bActive)
continue;
if(vMouseWorldPos.fX > pcGameCardT->vWorldPos.fX-0.5f &&
vMouseWorldPos.fX < pcGameCardT->vWorldPos.fX+0.5f &&
vMouseWorldPos.fY > pcGameCardT->vWorldPos.fY-0.5f &&
vMouseWorldPos.fY < pcGameCardT->vWorldPos.fY+0.5f &&
cGameConfig.PlayerType[cGameInfo.iCurrentPlayer] == PLAYER_TYPE_HUMAN)
pcGameCardT->bUnderMouse = TRUE;
if(pcGameCardT->bSelected)
{
pcGameCardT->fSelectionColor[R] += (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[R] > 1.0f)
pcGameCardT->fSelectionColor[R] = 1.0f;
pcGameCardT->fSelectionColor[G] -= (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[G] < 0.4f)
pcGameCardT->fSelectionColor[G] = 0.4f;
pcGameCardT->fSelectionColor[B] -= (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[B] < 0.4f)
pcGameCardT->fSelectionColor[B] = 0.4f;
pcGameCardT->fSelectionColor[A] += (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[A] > 0.8f)
pcGameCardT->fSelectionColor[A] = 0.8f;
if(!pcGameCardT->fSelectionRotTime)
{
ASPlayFmodSample(pClickOnCardSample, FSOUND_LOOP_OFF);
ASPlayFmodSample(pRotateCardSample, FSOUND_LOOP_OFF);
ShowSmallMessage(pcCardStyle->sCard[pcGameCardT->iCard].byName, 2000);
ASPlayFmodSample(&pcCardStyle->sCard[pcGameCardT->iCard].Sound, FSOUND_LOOP_OFF);
}
pcGameCardT->fSelectionRotTime += (float) g_lDeltatime/1000;
if(pcGameCardT->fSelectionRotTime > 1.0f)
pcGameCardT->fSelectionRotTime = 1.0f;
}
else
{
if(pcGameCardT->fSelectionRotTime == 1.0f)
ASPlayFmodSample(pRotateCardSample, FSOUND_LOOP_OFF);
pcGameCardT->fSelectionRotTime -= (float) g_lDeltatime/1000;
if(pcGameCardT->fSelectionRotTime < 0.0f)
pcGameCardT->fSelectionRotTime = 0.0f;
if(pcGameCardT->bUnderMouse && !pcGameCardT->bGoingDeath)
{
pcGameCardT->fSelectionColor[R] -= (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[R] < 0.2f)
pcGameCardT->fSelectionColor[R] = 0.2f;
pcGameCardT->fSelectionColor[G] += (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[G] > 1.0f)
pcGameCardT->fSelectionColor[G] = 1.0f;
pcGameCardT->fSelectionColor[B] -= (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[B] < 0.2f)
pcGameCardT->fSelectionColor[B] = 0.2f;
pcGameCardT->fSelectionColor[A] += (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[A] > 0.8f)
pcGameCardT->fSelectionColor[A] = 0.8f;
}
else
{
for(i2 = 0; i2 < 4; i2++)
{
pcGameCardT->fSelectionColor[i2] -= (float) g_lDeltatime/300;
if(pcGameCardT->fSelectionColor[i2] < 0.0f)
pcGameCardT->fSelectionColor[i2] = 0.0f;
}
}
}
pcGameCardT->fSelectionRotSmoothTime = (float) (0.5f-0.5f*cos(sin(pcGameCardT->fSelectionRotTime*PId2)*PI));
pcGameCardT->Check();
}
if(cGameConfig.PlayerType[cGameInfo.iCurrentPlayer] == PLAYER_TYPE_HUMAN)
{ // Check if the player selects an game card:
if(CHECK_KEY(ASMouse.byButtons, 0))
{
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
pcGameCardT = &pcGameCard[i];
if(!pcGameCardT->bActive || !pcGameCardT->bUnderMouse ||
pcGameCardT->fSelectionRotSmoothTime != 0.0f)
continue;
pcGameCardT->bUnderMouse = FALSE;
if(cGameInfo.iSelectedCard[0] == -1)
{ // First card:
cGameInfo.iSelectedCard[0] = i;
pcGameCardT->bSelected = TRUE;
break;
}
else
{ // Second card:
if(cGameInfo.iSelectedCard[1] != -1 || cGameInfo.iSelectedCard[0] == i ||
pcGameCard[cGameInfo.iSelectedCard[0]].fSelectionRotSmoothTime != 1.0f)
continue; // This card is already selected!
cGameInfo.iSelectedCard[1] = i;
pcGameCardT->bSelected = TRUE;
break;
}
}
}
}
else
{ // Ok, the computer makes now an selection:
psPlayerT = &cGameInfo.sPlayerInfo[cGameInfo.iCurrentPlayer];
if((cGameInfo.iSelectedCard[0] == -1 || cGameInfo.iSelectedCard[1] == -1) &&
(cGameInfo.iSelectedCard[0] == -1 || (cGameInfo.iSelectedCard[0] != -1 &&
pcGameCard[cGameInfo.iSelectedCard[0]].fSelectionRotSmoothTime >= 1.0f)))
{ // Select now the cards:
// Is it time to choose?
if(g_lGameTimer >= psPlayerT->lNextSelectionTime)
{
SetNextComputerSelectionTime();
// Does the computer knows an pair?
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
if(!psPlayerT->bComputerMemory[i] ||
pcGameCard[i].bGoingDeath)
continue;
for(i2 = 0; i2 < cGameConfig.iCardPairs*2; i2++)
{
if(i == i2 || !psPlayerT->bComputerMemory[i2] ||
pcGameCard[i2].bGoingDeath)
continue;
if(pcGameCard[i].iCard == pcGameCard[i2].iCard)
{ // Wow, he knows an pair, get it:
if(cGameInfo.iSelectedCard[0] == -1)
{ // Get the fist card:
cGameInfo.iSelectedCard[0] = i;
pcGameCard[i].bSelected = TRUE;
}
else
{ // Get the second card:
if(cGameInfo.iSelectedCard[0] == i2)
{
cGameInfo.iSelectedCard[1] = i;
pcGameCard[i].bSelected = TRUE;
}
else
{
cGameInfo.iSelectedCard[1] = i2;
pcGameCard[i2].bSelected = TRUE;
}
}
i = i2 = cGameConfig.iCardPairs*2;
}
}
}
// Ok, at the moment he knows no pair so get an card by random:
if(cGameInfo.iSelectedCard[0] == -1 && cGameInfo.iSelectedCard[1] == -1)
{
for(i = 0; i < 1000; i++)
{
iCard = rand() % (cGameConfig.iCardPairs*2);
if(!pcGameCard[iCard].bActive || psPlayerT->bComputerMemory[iCard])
continue; // The player know this card already!
psPlayerT->bComputerMemory[iCard] = TRUE;
cGameInfo.iSelectedCard[0] = iCard;
pcGameCard[iCard].bSelected = TRUE;
break;
}
if(i == 1000)
{
for(i = 0; i < 1000; i++)
{
iCard = rand() % (cGameConfig.iCardPairs*2);
if(!pcGameCard[iCard].bActive)
continue;
cGameInfo.iSelectedCard[0] = iCard;
pcGameCard[iCard].bSelected = TRUE;
break;
}
}
}
else
{
if(cGameInfo.iSelectedCard[0] != -1 && pcGameCard[cGameInfo.iSelectedCard[0]].fSelectionRotSmoothTime >= 1.0f &&
cGameInfo.iSelectedCard[1] == -1)
{
for(i = 0; i < 1000; i++)
{
iCard = rand() % (cGameConfig.iCardPairs*2);
if(iCard == 17)
iCard = iCard;
if(!pcGameCard[iCard].bActive || psPlayerT->bComputerMemory[iCard])
continue; // The player know this card already!
psPlayerT->bComputerMemory[iCard] = TRUE;
cGameInfo.iSelectedCard[1] = iCard;
pcGameCard[iCard].bSelected = TRUE;
break;
}
if(i == 1000)
{
for(i = 0; i < 1000; i++)
{
iCard = rand() % (cGameConfig.iCardPairs*2);
if(!pcGameCard[iCard].bActive || cGameInfo.iSelectedCard[0] == iCard)
continue;
cGameInfo.iSelectedCard[1] = iCard;
pcGameCard[iCard].bSelected = TRUE;
break;
}
}
}
}
}
}
}
// Check the selected carts:
if(cGameInfo.iSelectedCard[0] != -1 &&
cGameInfo.iSelectedCard[1] != -1 &&
pcGameCard[cGameInfo.iSelectedCard[0]].fSelectionRotSmoothTime == 1.0f &&
pcGameCard[cGameInfo.iSelectedCard[1]].fSelectionRotSmoothTime == 1.0f)
{ // Two cards are selected and opened:
// The other computer player have a look at the cards, too:
for(i = 0; i < 4; i++)
{
for(i2 = 0; i2 < 2; i2++)
{
switch(cGameConfig.PlayerType[i])
{
case PLAYER_TYPE_COMPUTER_EASY:
if(!(rand() % 2))
break;
cGameInfo.sPlayerInfo[i].bComputerMemory[cGameInfo.iSelectedCard[i2]] = TRUE;
cGameInfo.sPlayerInfo[i].lComputerSeeTime[cGameInfo.iSelectedCard[i2]] = g_lGameTimer;
break;
case PLAYER_TYPE_COMPUTER_NORMAL: case PLAYER_TYPE_COMPUTER_CLEVER:
cGameInfo.sPlayerInfo[i].bComputerMemory[cGameInfo.iSelectedCard[i2]] = TRUE;
cGameInfo.sPlayerInfo[i].lComputerSeeTime[cGameInfo.iSelectedCard[i2]] = g_lGameTimer;
break;
default:
continue;
}
}
}
// Sometimes the computer forgets something:
for(i = 0; i < 4; i++)
{
switch(cGameConfig.PlayerType[i])
{
case PLAYER_TYPE_COMPUTER_EASY:
for(i2 = 0; i2 < cGameConfig.iCardPairs*2; i2++)
{
iTime = (int) ((5+g_lGameTimer-cGameInfo.sPlayerInfo[i].lComputerSeeTime[i2])/1000);
if(iTime < 0)
iTime = 0;
if(!(rand() % (1+iTime)))
cGameInfo.sPlayerInfo[i].bComputerMemory[i2] = FALSE;
}
break;
case PLAYER_TYPE_COMPUTER_NORMAL:
for(i2 = 0; i2 < cGameConfig.iCardPairs*2; i2++)
{
iTime = (int) ((10+g_lGameTimer-cGameInfo.sPlayerInfo[i].lComputerSeeTime[i2])/1000);
if(iTime < 0)
iTime = 0;
if(!(rand() % (6+iTime)))
cGameInfo.sPlayerInfo[i].bComputerMemory[i2] = FALSE;
}
break;
case PLAYER_TYPE_COMPUTER_CLEVER:
for(i2 = 0; i2 < cGameConfig.iCardPairs*2; i2++)
{
iTime = (int) ((15+g_lGameTimer-cGameInfo.sPlayerInfo[i].lComputerSeeTime[i2])/1000);
if(iTime < 0)
iTime = 0;
if(!(rand() % (12+iTime)))
cGameInfo.sPlayerInfo[i].bComputerMemory[i2] = FALSE;
}
break;
default:
continue;
}
}
// Does the player has found an card pair??
if(pcGameCard[cGameInfo.iSelectedCard[0]].iCard ==
pcGameCard[cGameInfo.iSelectedCard[1]].iCard)
{ // Yep, he found a card pair!
ASPlayFmodSample(pPairFoundSample, FSOUND_LOOP_OFF);
pcGameCard[cGameInfo.iSelectedCard[0]].bGoingDeath = TRUE;
pcGameCard[cGameInfo.iSelectedCard[1]].bGoingDeath = TRUE;
// Add this card pair to the players score:
cGameInfo.sPlayerInfo[cGameInfo.iCurrentPlayer].iCardPairs++;
cGameInfo.iCardPairsOnTable--;
}
else
{ // Nope, he doesn't found a card pair!
ASPlayFmodSample(pNoPairFoundSample, FSOUND_LOOP_OFF);
if(cGameConfig.bErrorLimit)
{
for(i = 0; i < 2; i++)
{
cGameInfo.iError[cGameInfo.iSelectedCard[i]]--;
if(cGameInfo.iError[cGameInfo.iSelectedCard[i]] <= 0)
{ // Delete this card pair:
for(i2 = 0; i2 < cGameConfig.iCardPairs*2; i2++)
{
if(pcGameCard[i2].iCard == pcGameCard[cGameInfo.iSelectedCard[i]].iCard)
{
pcGameCard[i2].bSelected = TRUE;
pcGameCard[i2].bGoingDeath = TRUE;
if(i != cGameInfo.iSelectedCard[i])
pcGameCard[i2].fSelectionRotSmoothTime = 0.1f;
}
}
cGameInfo.iCardPairsOnTable--;
}
}
}
// Next player:
cGameInfo.iCurrentPlayer++;
if(cGameInfo.iCurrentPlayer >= cGameConfig.iPlayers)
cGameInfo.iCurrentPlayer = 0;
SetNextComputerSelectionTime();
}
cGameInfo.lThinkTime = g_lGameTimer;
cGameInfo.iThinkTimePastSeconds = 0;
pcGameCard[cGameInfo.iSelectedCard[0]].bSelected =
pcGameCard[cGameInfo.iSelectedCard[1]].bSelected = FALSE;
}
// Check selected cards:
for(i = 0; i < 2; i++)
{
if(cGameInfo.iSelectedCard[i] == -1)
continue;
if(pcGameCard[cGameInfo.iSelectedCard[i]].bGoingDeath &&
pcGameCard[cGameInfo.iSelectedCard[i]].fSelectionRotSmoothTime <= 0.0f)
cGameInfo.iSelectedCard[i] = -1;
else
if(!pcGameCard[cGameInfo.iSelectedCard[i]].bSelected &&
!pcGameCard[cGameInfo.iSelectedCard[i]].fSelectionRotSmoothTime)
{
cGameInfo.iSelectedCard[0] = -1;
cGameInfo.iSelectedCard[1] = -1;
break;
}
}
// Check if an card is going death:
for(i = 0; i < cGameConfig.iCardPairs*2; i++)
{
pcGameCardT = &pcGameCard[i];
if(!pcGameCardT->bActive || !pcGameCardT->bGoingDeath)
continue;
if(pcGameCardT->fSelectionRotSmoothTime >= 1.0f)
pcGameCardT->bSelected = FALSE;
if(pcGameCardT->fSelectionRotSmoothTime <= 0.0f)
pcGameCardT->bActive = FALSE;
}
} // end CheckGameCards()
void DrawTableBackground(void)
{ // begin DrawTableBackground()
// Draw the table background:
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glColor3f(1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, pcCardStyle->sTexture[3].iOpenGLID);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(vPlayField[MIN].fX-1.0f, vPlayField[MAX].fY+0.5f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(vPlayField[MAX].fX+1.0f, vPlayField[MAX].fY+0.5f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(vPlayField[MAX].fX+1.0f, vPlayField[MIN].fY-0.5f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(vPlayField[MIN].fX-1.0f, vPlayField[MIN].fY-0.5f, 1.0f);
glEnd();
return;
// Perform the lightmap on it:
if(!_ASConfig->bLightmaps || cGameConfig.PlayerType[cGameInfo.iCurrentPlayer] != PLAYER_TYPE_HUMAN)
return;
AS_3D_VECTOR vField[4];
AS_DLIGHT cLight1;
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, GameTexture[1].iOpenGLID);
glDepthMask(FALSE);
glDisable(GL_LIGHTING);
cLight1.fRadius = 5.0f;
cLight1.vPos = vMouseWorldPos;
cLight1.vColor = 0.5f;
vField[0].fX = vPlayField[MIN].fX-1.0f;
vField[0].fY = vPlayField[MIN].fY-0.5f;
vField[0].fZ = 1.0f;
vField[1].fX = vPlayField[MAX].fX+1.0f;
vField[1].fY = vPlayField[MIN].fY-0.5f;
vField[1].fZ = 1.0f;
vField[2].fX = vPlayField[MAX].fX+1.0f;
vField[2].fY = vPlayField[MAX].fY+0.5f;
vField[2].fZ = 1.0f;
vField[3].fX = vPlayField[MIN].fX-1.0f;
vField[3].fY = vPlayField[MAX].fY+0.5f;
vField[3].fZ = 1.0f;
glBegin(GL_TRIANGLES);
cLight1.Light(vField[2], vField[1], vField[0]);
cLight1.Light(vField[3], vField[2], vField[0]);
glEnd();
glDepthMask(TRUE);
glDisable(GL_BLEND);
} // end DrawTableBackground()
void SetNextComputerSelectionTime(void)
{ // begin SetNextComputerSelectionTime()
switch(cGameConfig.PlayerType[cGameInfo.iCurrentPlayer])
{
case PLAYER_TYPE_COMPUTER_EASY:
cGameInfo.sPlayerInfo[cGameInfo.iCurrentPlayer].lNextSelectionTime = g_lGameTimer+1000+(rand() % 3000);
break;
case PLAYER_TYPE_COMPUTER_NORMAL:
cGameInfo.sPlayerInfo[cGameInfo.iCurrentPlayer].lNextSelectionTime = g_lGameTimer+1000+(rand() % 1500);
break;
case PLAYER_TYPE_COMPUTER_CLEVER:
cGameInfo.sPlayerInfo[cGameInfo.iCurrentPlayer].lNextSelectionTime = g_lGameTimer+1000+(rand() % 700);
break;
}
} // end SetNextComputerSelectionTime()