CRM32Pro SDK  v5.22
SpacePong.cpp


*SpacePong source - A little pong clone game

/*--------------------------------------------
SpacePong Minigame - Roberto Prieto
Copyright (C) 2001-2011 MegaStorm Systems
--------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Roberto Prieto
contact@megastormsystems.com
http://www.megastormsystems.com
Used software licenses, including the one for this game, are located
at /licenses directory. Please, include them on your distributions.
------------------------------------------------------------------------
SpacePong Minigame, a pong clone with 3 different game modes:
- Auto demo mode
- 1 player
- 2 players (on the same computer)
- 2D environment at 800x600
- Graphics, sounds and musics using DPF
Supported platforms:
- Any Windows x86 or x86-64 version.
- Any Linux x86 or x86-64 distribution.
- MacOS X 10.x x86 or x86-64.
Thanks to Worvast for the new in-game graphics.
Changelog: Check history.txt
------------------------------------------------------------------------ */
// ---Includes---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include "CRM32Pro.h"
#include "SpacePong.h"
#ifdef _WINDOWS
#include <conio.h>
#include <windows.h>
#elif defined(_LINUX) || defined(_MACOSX)
#include <math.h>
char *_itoa(int i,char *a,size_t len)
{
sprintf(a,"%d",i % static_cast<int>(pow(10,len-1-(i<0))));
return a;
}
#endif
// -------------------------MAIN ENTRY POINT---------------------------------
int main(int argc,char *argv[])
{
Uint8 done;
int iRet;
// -Init log system-
ILogSystem.Init("spacepong.log",LOG_FILE,LOG_NORMAL,PONG_VERSION);
// -Init CRM32Pro-
if(CRM32Pro.Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0)
{
ILogSystem.Msg(LOG_NORMAL," ·[PONG Init Error] - Couldnīt initialize CRM32Pro: %s\n",SDL_GetError());
exit(1);
}
// -Desired config-
if(!CRM32Pro.LoadConfig("setup.dpf","setup.xml"))
{
ILogSystem.Msg(LOG_NORMAL," ·[PONG Init Error] - Couldnīt load 'setup.xml'. Please, run 'Setup.exe'\n");
exit(1);
}
CRM32Pro.Config.Title = PONG_VERSION;
CRM32Pro.Config.Icon = IImage->Load(GFX_RESOURCE,"icono");
// -Graphics system initialize-
if(!CRM32Pro.SetVideoMode())
{
CRM32Pro.Quit();
return 1;
}
ICursor->Init();
// -Time system initialize-
ITimeSystem->Init();
ITimeSystem->SetRate(0,40); // Optional: desired Rendering and Logic Frame Rate
// -Init sound system-
iRet = ISoundFX->Init(); // It uses the config of CRM32Pro.Config
if(iRet == -1) ILogSystem.Msg(LOG_NORMAL," ·[PONG Sound System] - Couldnīt init sound system: %s\n",SDL_GetError());
else if(iRet == 1) LoadAudio();
// -MegaStorm Systems presentation-
/* ISoundFX->SoundPlay(1,thunder,0);
sGameBg = IImage->Load(GFX_RESOURCE,"logotipoMS");
SDL_FillRect(CRM32Pro.screen,NULL,SDL_MapRGB(CRM32Pro.screen->format,0,0,0));
IScreenFX->FadeToImage(sGameBg,500);
while(ISoundFX->IsPlaying(1)) SDL_Delay(50);
IScreenFX->FadeToColor(0,0,0,500);
SDL_FreeSurface(sGameBg);*/
// -Loading gfx-
LoadGraphics();
// -Main menu loop-
IButton->SetState(bGoalID,B_PRESS);
sGameDat.iTipo = GAME_GOAL;
done = PONG_ENTRY;
while(done != PONG_QUIT)
{
// 1.First execution or after a game match:
// - initial fade, music play, show cursor
// - set our render callback
if(done == PONG_ENTRY)
{
IScreenFX->FadeToImage(sMenuBg,600);
ISoundFX->MusicPlay(music_menu, 100);
ICursor->Show();
ICursor->Invalidate();
CRM32Pro.SetRenderCallback(RenderInMenu);
CRM32Pro.CleanUp();
bID = -1;
done = PONG_LOOP;
}
// 2.Buttons management. The bID is retrieved by our render callback.
// 2.1.Exit to OS
if(bID == bExitID)
{
ISoundFX->SoundPlay(1,click,0);
while(ISoundFX->IsPlaying(1)) SDL_Delay(200);
done = PONG_QUIT;
}
// 2.2.Start game with 1 Player
else if(bID == bPlayer1ID)
{
ISoundFX->SoundPlay(1,click,0);
// Execute the game loop
sGameDat.iModo = MODE_1PLAYER;
GameLoop();
done = PONG_ENTRY;
}
// 2.3.Start game with 2 Players
else if(bID == bPlayer2ID)
{
ISoundFX->SoundPlay(1,click,0);
// Execute the game loop
sGameDat.iModo = MODE_2PLAYER;
GameLoop();
done = PONG_ENTRY;
}
// 2.4.Start game with autoplay
else if(bID == bAutoID)
{
ISoundFX->SoundPlay(1,click,0);
// Execute the game loop
sGameDat.iModo = MODE_COMPUTER;
GameLoop();
done = PONG_ENTRY;
}
// 2.5.Change game mode to normal
else if(bID == bNormalID)
{
ISoundFX->SoundPlay(1,click2,0);
IButton->SetState(bGoalID,B_NORMAL);
IButton->SetState(bTimeID,B_NORMAL);
IButton->SetState(bNormalID,B_PRESS);
sGameDat.iTipo = GAME_NORMAL;
}
// 2.6.Change game mode to goal
else if(bID == bGoalID)
{
ISoundFX->SoundPlay(1,click2,0);
IButton->SetState(bGoalID,B_PRESS);
IButton->SetState(bTimeID,B_NORMAL);
IButton->SetState(bNormalID,B_NORMAL);
sGameDat.iTipo = GAME_GOAL;
}
// 2.7.Change game mode to time
else if(bID == bTimeID)
{
ISoundFX->SoundPlay(1,click2,0);
IButton->SetState(bGoalID,B_NORMAL);
IButton->SetState(bTimeID,B_PRESS);
IButton->SetState(bNormalID,B_NORMAL);
sGameDat.iTipo = GAME_TIME;
}
// 3.Main update: blit to screen, update time system, etc.
while(CRM32Pro.Update());
}
// -Exiting...-
ISoundFX->MusicFadeOut(500);
SDL_Delay(250);
ISoundFX->MusicStop();
IScreenFX->FadeToColor(0,0,0,500);
FreeAudio();
FreeGraphics();
CRM32Pro.AudioInfo();
CRM32Pro.VideoInfo();
CRM32Pro.Quit();
ILogSystem.Msg(LOG_NORMAL,"\n · End of execution\n");
return 1;
}
// Callback function called by CRM32Pro.Update() fulfilling with Rendering Frame Rate
// Used in the menu screen. Not in the game.
void RenderInMenu(int bLogicUpdate)
{
if(!CRM32Pro.IsRenderNeeded()) return;
{
CRM32Pro.Blit(sMenuBg,NULL,CRM32Pro.screen,NULL);
rRect.x = 27;rRect.y = 20;rRect.w = sMenuTitle->w; rRect.h = sMenuTitle->h;
CRM32Pro.Blit(sMenuTitle,NULL,CRM32Pro.screen,&rRect);
rRect.x = 133;rRect.y = 578;rRect.w = sMenuInfo->w; rRect.h = sMenuInfo->h;
CRM32Pro.Blit(sMenuInfo,NULL,CRM32Pro.screen,&rRect);
bID = IButton->Draw();
}
}
// ------------------------------GAME LOOP------------------------------------
void GameLoop()
{
Uint8 done;
Uint32 iTmp = 0;
// Hide cursor, stop previous render callback
ICursor->Hide();
CRM32Pro.SetRenderCallback(NULL);
// Init vars, starting position and init ball
srand(SDL_GetTicks());
sGameDat.iWinP1 = 0; sGameDat.iWinP2 = 0;
sPadder[0].x = 384.0f; sPadder[0].size = 64; sPadder[0].speed=0.0f; sPadder[0].random=64/2;
sPadder[1].x = 384.0f; sPadder[1].size = 64; sPadder[1].speed=0.0f; sPadder[1].random=64/2;
InitBall(0);
sBall.spr->SetPosition((int)sBall.x,(int)sBall.y);
sPadder[0].spr->SetPosition((int)sPadder[0].x,Y_POSITION_1);
sPadder[1].spr->SetPosition((int)sPadder[1].x,Y_POSITION_2);
ILogSystem.Msg(LOG_NORMAL,"\n · Match started...");
// Finish previous click sound and music. Fade to black and start music with fade to image.
while(ISoundFX->IsPlaying(1)) SDL_Delay(200);
ISoundFX->MusicFadeOut(500);
IScreenFX->FadeToColor(0,0,0,500);
ISoundFX->MusicStop();
ISoundFX->MusicPlay(music_game, 100);
IScreenFX->FadeToImage(sGameBg,500);
// Show game type string
switch(sGameDat.iTipo)
{
case GAME_TIME:
strcpy(sCad,"TIME"); break;
case GAME_GOAL:
strcpy(sCad,"GOAL"); break;
case GAME_NORMAL:
strcpy(sCad,"INFI"); break;
}
// Set our in-game render callback function
CRM32Pro.SetRenderCallback(RenderInGame);
CRM32Pro.CleanUp();
// As we are using smooth sprite movement, we set the render engine to draw always
// Main game loop with a Fixed Logic Rate of 20 executions per seconds
done = PONG_ENTRY;
while(done < PONG_QUIT)
{
// 1.Event management
if(CRM32Pro.GetKeystate(SDLK_ESCAPE)) done = PONG_QUIT;
if(CRM32Pro.GetKeystate(SDLK_F2)) SDL_SaveBMP(CRM32Pro.screen,"pong.bmp");
// 2.Ball behaviour
sBall.x = sBall.x + (sBall.sx * sBall.speed);
sBall.y = sBall.y + (sBall.sy * sBall.speed);
// 2.1.Detect wall bounds
if(sBall.x < LEFT_BAR)
{
sBall.x = LEFT_BAR;
sBall.sx = sBall.sx * (-1.0f); ISoundFX->SoundPlay(2,pared,0);
}
else if(sBall.x + X_SIZE_BALL > RIGHT_BAR)
{
sBall.x = RIGHT_BAR - X_SIZE_BALL;
sBall.sx = sBall.sx * (-1.0f); ISoundFX->SoundPlay(2,pared,0);
}
// 2.2.Detect Padder1 goal
if(sBall.y < UP_LIMIT)
{
InitBall(1);
sGameDat.iWinP1++;
ISoundFX->SoundPlay(2,gol,0);
SDL_Delay(250);
}
// 2.3.Detect Padder2 goal
else if(sBall.y > DOWN_LIMIT)
{
InitBall(2);
sGameDat.iWinP2++;
ISoundFX->SoundPlay(2,gol,0);
SDL_Delay(250);
}
// 3.Padder movement
switch(sGameDat.iModo)
{
case MODE_COMPUTER:
AIPadder(0);
AIPadder(1);
break;
case MODE_2PLAYER:
if(CRM32Pro.GetKeystate(SDLK_x)) SET_SPEED(1,1);
if(CRM32Pro.GetKeystate(SDLK_z)) SET_SPEED(1,0);
if(CRM32Pro.GetKeystate(SDLK_RIGHT)) SET_SPEED(0,1);
if(CRM32Pro.GetKeystate(SDLK_LEFT)) SET_SPEED(0,0);
break;
case MODE_1PLAYER:
if(CRM32Pro.GetKeystate(SDLK_RIGHT)) SET_SPEED(0,1);
if(CRM32Pro.GetKeystate(SDLK_LEFT)) SET_SPEED(0,0);
AIPadder(1);
break;
}
// 3.1.Adjust padders speed and set right animation
for(iTmp = 0; iTmp < 2; iTmp++)
{
sPadder[iTmp].spr->SelectAnim(SPRSTATE_NORMAL); // Trend to be stopped
if(sPadder[iTmp].speed > PADDER_MAXSPEED) sPadder[iTmp].speed = PADDER_MAXSPEED;
if(sPadder[iTmp].speed < -PADDER_MAXSPEED) sPadder[iTmp].speed = -PADDER_MAXSPEED;
if(sPadder[iTmp].speed > 0.0f)
{
sPadder[iTmp].speed -= PADDER_ACEL / 4; // Trend to stop
sPadder[iTmp].spr->SelectAnim(SPRSTATE_LEFT);
}
if(sPadder[iTmp].speed < 0.0f)
{
sPadder[iTmp].speed += PADDER_ACEL / 4; // Trend to stop
sPadder[iTmp].spr->SelectAnim(SPRSTATE_RIGHT);
}
}
// 3.2.Calculate new positions
for(iTmp = 0; iTmp < 2; iTmp++) sPadder[iTmp].x = sPadder[iTmp].x + sPadder[iTmp].speed;
// 3.3.Adjust padders position
for(iTmp = 0; iTmp < 2; iTmp++)
{
if(sPadder[iTmp].x > RIGHT_BAR - sPadder[iTmp].size)
{
sPadder[iTmp].x = RIGHT_BAR - sPadder[iTmp].size;
sPadder[iTmp].speed = 0.0f;
}
if(sPadder[iTmp].x < LEFT_BAR)
{
sPadder[iTmp].x = LEFT_BAR;
sPadder[iTmp].speed = 0.0f;
}
}
// 4.Detect ball hit on padder1 and padder2. Margin of 12 pixels
if((sBall.y + Y_SIZE_BALL >= Y_POSITION_1) && (sBall.y + Y_SIZE_BALL <= (Y_POSITION_1 + 12))) PadderHitBall(0);
if((sBall.y <= Y_POSITION_2 + Y_SIZE_PADDER) && (sBall.y >= (Y_POSITION_2 + Y_SIZE_PADDER - 12))) PadderHitBall(1);
// 5.Update sprites with smooth system
sBall.spr->SetPosition((int)sBall.x,(int)sBall.y,1);
sPadder[0].spr->SetPosition((int)sPadder[0].x,Y_POSITION_1,1);
sPadder[1].spr->SetPosition((int)sPadder[1].x,Y_POSITION_2,1);
// 6.End of match conditions
switch(sGameDat.iTipo)
{
// Play a match during 5 minutes
case GAME_TIME:
if(iAux == 5) done = PONG_ENDMATCH;
break;
// Play a match until one player reach 10 points
case GAME_GOAL:
if((sGameDat.iWinP1 == 10) || (sGameDat.iWinP2 == 10)) done = PONG_ENDMATCH;
break;
}
// 7.Main update: draw sprites using callback function, update interfaces, blit to screen, update time system, etc.
while(CRM32Pro.Update());
}
// Show the winner! (0=player1 1=tie 2=player2)
ISoundFX->SoundPlay(1,end,0);
// Did we a break? (ESCAPE key was pressed)
if(done == PONG_QUIT)
{
if(sGameDat.iTipo != GAME_NORMAL) iTmp = 1;
else
{
if(sGameDat.iWinP1 > sGameDat.iWinP2) iTmp = 0;
else if(sGameDat.iWinP1 < sGameDat.iWinP2) iTmp = 2;
else iTmp = 1;
}
}
// There is a winner!
else
{
if(sGameDat.iWinP1 > sGameDat.iWinP2) iTmp = 0;
else if(sGameDat.iWinP1 < sGameDat.iWinP2) iTmp = 2;
}
switch(iTmp)
{
case 0:
fFont->PutString(CRM32Pro.screen,260,290,"PLAYER 1 WINS !!");
break;
case 1:
fFont->PutString(CRM32Pro.screen,300,290,"TIE GAME !!");
break;
case 2:
fFont->PutString(CRM32Pro.screen,260,290,"PLAYER 2 WINS !!");
break;
}
ILogSystem.Msg(LOG_NORMAL,"\n · Player 1 wins: %d - Player 2 wins: %d\n",sGameDat.iWinP1,sGameDat.iWinP2);
ITimeSystem->Info();
ILogSystem.Msg(LOG_NORMAL," · Match finished\n");
// Remove our in-game render callback
CRM32Pro.SetRenderCallback(NULL);
// Flip now the screen to show the name of the winner
SDL_Flip(CRM32Pro.screen);
SDL_Delay(2000);
// Menu music stop
ISoundFX->MusicFadeOut(500);
SDL_Delay(250);
ISoundFX->MusicStop();
IScreenFX->FadeToColor(0,0,0,500);
}
// Callback function called by CRM32Pro.Update() fulfilling with Rendering Frame Rate
// Used in the game. Not in the menu screen.
void RenderInGame(int bLogicUpdate)
{
// Check if we need to render everything.
if(!CRM32Pro.IsRenderNeeded() && (!bLogicUpdate)) return;
CRM32Pro.Blit(sGameBg,NULL,CRM32Pro.screen,NULL);
sBall.spr->Draw();
sPadder[0].spr->Draw();
sPadder[1].spr->Draw();
DrawInterfaz(1);
DrawInterfaz(2);
fFont->PutString(CRM32Pro.screen,36,463,sCad);
fFont->PutString(CRM32Pro.screen,685,463,sCad);
}
void DrawInterfaz(int m)
{
char sAux[4], sCad[8];
Uint32 iTime = 0;
iTime = (Uint32)ITimeSystem->GetSeconds();
switch(m)
{
case 1:
// Restore info pannel of the Player 1
rRect.x = 25; rRect.y = 199; rRect.w = sRestoreBg[0]->w; rRect.h = sRestoreBg[0]->h;
SDL_BlitSurface(sRestoreBg[0],NULL,CRM32Pro.screen,&rRect);
// Score board of the Player 1
_itoa(sGameDat.iWinP1,sAux,10);
strcpy(sCad,"");
if(sGameDat.iWinP1 < 10) strcpy(sCad,"0");
strcat(sCad,sAux);
fFont->PutString(CRM32Pro.screen,55,203,sCad);
// Time left
strcpy(sCad,"");
iAux = iTime / 60;
_itoa(iAux,sAux,10);
strcpy(sCad,sAux);
strcat(sCad,":");
_itoa(iTime - (iAux * 60),sAux,10);
if(iTime - (iAux * 60) < 10) strcat(sCad,"0");
strcat(sCad,sAux);
fFont->PutString(CRM32Pro.screen,44,264,sCad);
break;
case 2:
// Restore info pannel of the Player 2
rRect.x = 685; rRect.y = 201; rRect.w = sRestoreBg[1]->w; rRect.h = sRestoreBg[1]->h;
SDL_BlitSurface(sRestoreBg[1],NULL,CRM32Pro.screen,&rRect);
// Score board of the Player 1
_itoa(sGameDat.iWinP2,sAux,10);
strcpy(sCad,"");
if(sGameDat.iWinP2 < 10) strcpy(sCad,"0");
strcat(sCad,sAux);
fFont->PutString(CRM32Pro.screen,704,203,sCad);
// Time left
strcpy(sCad,"");
iAux = iTime / 60;
_itoa(iAux,sAux,10);
strcpy(sCad,sAux);
strcat(sCad,":");
_itoa(iTime - (iAux * 60),sAux,10);
if(iTime - (iAux * 60) < 10) strcat(sCad,"0");
strcat(sCad,sAux);
fFont->PutString(CRM32Pro.screen,692,264,sCad);
break;
}
}
/* AIPadder() - AI movement of the given padder
m=0 for Padder 1, with limitY at 100 (old 225)
m=1 for Padder 2, with limitY at 500 (old 375)
With y>limitY the player tend to move at the center
when the ball is greater than limitY, the player will try to pursuit it*/
void AIPadder(int m)
{
// Movement to screen center when the ball is going to the other player
if(((!m) && (sBall.y < 100)) || ((m) && (sBall.y > 500)))
{
if(sPadder[m].x < 368) { SET_SPEED(m,1); } // Try to center
else if(sPadder[m].x > 368) { SET_SPEED(m,0); } // Try to center
}
// Movement towards the ball with a little random behaviour
else
{
if(((sBall.x + 8)) < (sPadder[m].x + sPadder[m].random))
{
if(sPadder[m].x > LEFT_BAR) { SET_SPEED(m,0); }
}
else if(((sBall.x + 8)) > (sPadder[m].x + sPadder[m].random))
{
if(sPadder[m].x <= RIGHT_BAR - sPadder[m].size) { SET_SPEED(m,1); }
}
}
}
// InitBall() - Initialize the ball
void InitBall(int mode)
{
// Center ball with starting speed
sBall.sx = 0.0;
sBall.x = 400.0;
sBall.y = 300.0;
sBall.speed = 0.9;
switch(mode)
{
// mode=0, start match with random direction
case 0:
if((rand() % 10) >= 5) sBall.sy = -4.0;
else sBall.sy = 4.0;
break;
// mode=1, ball for padder1
case 1:
sBall.sy = -4.0;
break;
// mode=2, ball for padder2
case 2:
sBall.sy = 4.0;
break;
}
}
// PadderHitBall() - Change the ball speed and direction depending on current hit. Select the next random hit point.
void PadderHitBall(int m) // Support 7 differents directions
{
int iTmp;
float mod = -1.0;
if(m == 0) mod = 1.0;
if(((sBall.x + 12) >= sPadder[m].x) && ((sBall.x + 4) <= (sPadder[m].x + 64)))
{
if(m == 0) ISoundFX->SoundPlay(1,p1,0);
else ISoundFX->SoundPlay(1,p2,0);
iTmp = 24 + (int)sBall.x - (int)sPadder[m].x;
// The best hit!
if(iTmp <= 18)
{
sBall.sx = -5;sBall.sy = -4 * mod;
}
else if((iTmp > 18) && (iTmp <= 24))
{
sBall.sx = -4.0f;sBall.sy = -4.0f * mod;
}
else if((iTmp > 24) && (iTmp <= 40))
{
sBall.sx = -2.0f;sBall.sy = -6.0f * mod;
}
else if((iTmp > 40) && (iTmp <= 56))
{
sBall.sx = 0.0f;sBall.sy = -8.0f * mod;
}
else if((iTmp > 56) && (iTmp <= 72))
{
sBall.sx = 2.0f;sBall.sy = -6.0f * mod;
}
else if((iTmp > 72) && (iTmp <= 78))
{
sBall.sx = 4.0f;sBall.sy = -4.0f * mod;
}
// The best hit!
else if(iTmp >= 79)
{
sBall.sx = 5.0f;sBall.sy = -4.0f * mod;
}
else ILogSystem.Msg(LOG_NORMAL,"Padder[%d] - Error %d\n",m + 1,iTmp);
// Set ball speed
sBall.speed = sBall.speed + 0.03f;
if(sBall.speed >= MAX_BALL_SPEED) sBall.speed = MAX_BALL_SPEED;
// Set next attempt to hit on a random way
sPadder[m].random=rand()%sPadder[m].size;
}
}
// LoadAudio() - Load audio resources
void LoadAudio()
{
thunder = ISoundFX->SoundLoad(MUS_RESOURCE,"thunder");
end = ISoundFX->SoundLoad(MUS_RESOURCE,"endplay");
gol = ISoundFX->SoundLoad(MUS_RESOURCE,"goal");
p1 = ISoundFX->SoundLoad(MUS_RESOURCE,"padder1");
p2 = ISoundFX->SoundLoad(MUS_RESOURCE,"padder2");
pared = ISoundFX->SoundLoad(MUS_RESOURCE,"pared");
click = ISoundFX->SoundLoad(MUS_RESOURCE,"click");
click2 = ISoundFX->SoundLoad(MUS_RESOURCE,"click2");
music_menu = ISoundFX->MusicLoad(MUS_RESOURCE,"game");
music_game = ISoundFX->MusicLoad(MUS_RESOURCE,"game");
}
// FreeAudio() - Free audio resources
void FreeAudio()
{
ISoundFX->MusicFree(music_menu);
ISoundFX->MusicFree(music_game);
ISoundFX->SoundFree(thunder);
ISoundFX->SoundFree(click);
ISoundFX->SoundFree(click2);
ISoundFX->SoundFree(p1);
ISoundFX->SoundFree(p2);
ISoundFX->SoundFree(pared);
ISoundFX->SoundFree(gol);
ISoundFX->SoundFree(end);
}
// LoadGraphics() - Load graphics resources
void LoadGraphics()
{
sGameBg = IImage->Load(GFX_RESOURCE,"gamebg");
sRestoreBg[0] = SDL_CreateRGBSurface(CRM32Pro.screen->flags,100,95,sGameBg->format->BitsPerPixel,
sGameBg->format->Rmask,sGameBg->format->Gmask,sGameBg->format->Bmask,
sGameBg->format->Amask);
rRect.x = 25;rRect.y = 199;rRect.w = 100;rRect.h = 95;
SDL_BlitSurface(sGameBg,&rRect,sRestoreBg[0],NULL);
sRestoreBg[1] = SDL_CreateRGBSurface(CRM32Pro.screen->flags,100,90,sGameBg->format->BitsPerPixel,
sGameBg->format->Rmask,sGameBg->format->Gmask,sGameBg->format->Bmask,
sGameBg->format->Amask);
rRect.x = 685;rRect.y = 201;rRect.w = 100;rRect.h = 90;
SDL_BlitSurface(sGameBg,&rRect,sRestoreBg[1],NULL);
sMenuBg = IImage->Load(GFX_RESOURCE,"menubg");
sMenuTitle = IImage->Load(GFX_RESOURCE,"menutitle");
sMenuInfo = IImage->Load(GFX_RESOURCE,"menuinfo");
sPadder[0].spr = new CRM32Pro_CSprite();
sPadder[0].spr->Load(GFX_RESOURCE,"SPR_PADDER1");
sPadder[1].spr = new CRM32Pro_CSprite();
sPadder[1].spr->Load(GFX_RESOURCE,"SPR_PADDER2");
sBall.spr = new CRM32Pro_CSprite();
sBall.spr->Load(GFX_RESOURCE,"SPR_BALL");
fFont = new CRM32Pro_CFont;
fFont->Load(GFX_RESOURCE,"FVerde");
bExitID = IButton->Load(GFX_RESOURCE,"bExit");
bPlayer1ID = IButton->Load(GFX_RESOURCE,"bPlayer1");
bPlayer2ID = IButton->Load(GFX_RESOURCE,"bPlayer2");
bAutoID = IButton->Load(GFX_RESOURCE,"bAuto");
bTimeID = IButton->Load(GFX_RESOURCE,"bTime");
bGoalID = IButton->Load(GFX_RESOURCE,"bGoal");
bNormalID = IButton->Load(GFX_RESOURCE,"bNormal");
cCursor = ICursor->Load(GFX_RESOURCE,"cursor");
ICursor->Select(cCursor);
}
// FreeGraphics() - Free graphics resources
void FreeGraphics()
{
delete sPadder[0].spr;
delete sPadder[1].spr;
delete sBall.spr;
delete fFont;
SDL_FreeSurface(sGameBg);
SDL_FreeSurface(sMenuBg);
SDL_FreeSurface(sMenuTitle);
SDL_FreeSurface(sMenuInfo);
SDL_FreeSurface(sRestoreBg[0]);
SDL_FreeSurface(sRestoreBg[1]);
IButton->RemoveAll();
ICursor->Delete(cCursor);
}