2018-01-07 14:19:35 +01:00
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
# include <math.h>
2018-01-29 23:15:40 +01:00
# include <string.h>
2018-01-09 13:22:10 +01:00
# include <time.h>
2018-01-07 14:19:35 +01:00
# include <SDL2/SDL.h>
2018-01-09 13:22:10 +01:00
# include <SDL2/SDL_image.h>
# include <SDL2/SDL_ttf.h>
2018-01-27 11:37:39 +01:00
# include <SDL2/SDL_mixer.h>
2018-01-09 13:22:10 +01:00
2018-01-10 15:37:55 +01:00
# include "breakout.h"
2018-01-09 13:22:10 +01:00
# include "vector.h"
2018-01-15 13:19:51 +01:00
# include "startmenu.h"
2018-01-15 15:34:43 +01:00
# include "gamestate.h"
2018-01-15 23:47:39 +01:00
# include "highscores.h"
2018-01-23 21:22:01 +01:00
# include "gameover.h"
2018-01-18 15:48:39 +01:00
# include "settings.h"
2018-01-19 07:57:47 +01:00
# include "background.h"
2018-01-07 14:19:35 +01:00
2018-01-29 23:15:40 +01:00
# define MAIN_MenuMusicPath "assets / sounds / menu_music.wav"
# define MAIN_AccountSaveFilePath "account.cfg"
# define MAIN_FadeTime 1000
2018-01-27 18:48:45 +01:00
2018-01-18 15:20:01 +01:00
# include "main.h"
2018-01-10 15:37:55 +01:00
2018-01-18 15:34:34 +01:00
// Default Render Size (Upscaled for bigger monitors)
const int width = 1920 ;
const int height = 1080 ;
float XScale = 1.0f , YScale = 1.0f ;
// End render properties
int numKeys ;
const Uint8 * keystate ; // TODO: export all this into scenery and enemy waves
SDL_Window * window ;
SDL_Renderer * renderer ;
SDL_Event event ;
2018-01-29 19:10:08 +01:00
bool running = true , fullscreen = false , LoggedIn = false ;
2018-01-18 15:34:34 +01:00
GameState gameState = MainMenu ;
2018-01-30 09:59:35 +01:00
GameState previousGameState = MainMenu ;
2018-01-18 15:34:34 +01:00
Scenery scenery ;
2018-01-27 18:48:45 +01:00
Mix_Music * MenuLoop ;
2018-01-29 23:15:40 +01:00
char * Username ;
char * Password ;
2018-02-01 13:22:27 +01:00
int background = 0 ;
2018-01-18 15:34:34 +01:00
2018-01-07 14:19:35 +01:00
int main ( int argc , char * args [ ] ) {
2018-01-29 21:26:48 +01:00
AttemptLogin ( ) ;
2018-01-27 18:48:45 +01:00
INITIALIZE ( ) ;
2018-01-21 14:33:51 +01:00
Uint32 fps_lasttime = SDL_GetTicks ( ) ; // the last recorded time.
Uint32 fps_current ; // the current FPS.
Uint32 fps_frames = 0 ; // frames passed since the last recorded fps.
2018-01-27 18:48:45 +01:00
GAME_ChangeState ( MainMenu ) ;
2018-01-10 15:37:55 +01:00
while ( running ) { // Gameloop
2018-01-15 20:28:47 +01:00
HandleSDLEvents ( ) ;
2018-01-15 13:54:17 +01:00
DrawBackground ( renderer ) ;
switch ( gameState ) {
case Game :
2018-01-15 22:01:58 +01:00
BREAKOUT_Update ( & scenery , keystate ) ;
2018-02-01 13:22:27 +01:00
BACKGROUND_Draw ( renderer , background ) ;
2018-01-15 22:01:58 +01:00
BREAKOUT_Draw ( & scenery , renderer ) ;
2018-01-15 13:54:17 +01:00
break ;
case MainMenu :
2018-01-15 15:34:43 +01:00
// Startmenu_Update(keystate);
2018-01-15 13:54:17 +01:00
Startmenu_Draw ( renderer ) ;
break ;
2018-01-15 23:47:39 +01:00
case Highscores :
HIGHSCORES_Draw ( renderer ) ;
break ;
2018-01-18 15:48:39 +01:00
case Settings :
2018-02-01 13:22:27 +01:00
Settings_Draw ( renderer , & scenery , & background ) ;
2018-01-24 14:50:34 +01:00
break ;
2018-01-23 21:22:01 +01:00
case GameOver :
GAMEOVER_Draw ( renderer , & scenery ) ;
2018-01-18 15:48:39 +01:00
break ;
2018-01-15 13:54:17 +01:00
default :
printf ( " Unknow state was updated: %d \n " , gameState ) ;
2018-01-16 12:10:37 +01:00
break ;
2018-01-23 21:22:01 +01:00
} /* switch */
2018-01-15 13:54:17 +01:00
SDL_RenderPresent ( renderer ) ;
2018-01-21 14:33:51 +01:00
fps_frames + + ;
if ( fps_lasttime < SDL_GetTicks ( ) - 1000 ) {
fps_lasttime = SDL_GetTicks ( ) ;
fps_current = fps_frames ;
fps_frames = 0 ;
printf ( " Frames/s: %u \n " , fps_current ) ;
}
2018-01-07 14:19:35 +01:00
}
QUIT ( ) ;
return 0 ;
} /* main */
2018-01-29 23:15:40 +01:00
bool PushNewCredentialsToSaveFile ( const char * filename ) {
FILE * file ;
if ( file = fopen ( filename , " w " ) ) {
fprintf ( file , " %s \n %s " , Username , Password ) ;
fclose ( file ) ;
return true ;
}
return false ;
}
bool GrabAccountFromSaveFile ( const char * filename ) {
FILE * file ;
if ( file = fopen ( filename , " r " ) ) {
bool success = true ;
success = ( fscanf ( file , " %s \n %s " , Username , Password ) > 0 ) ;
if ( success ) printf ( " Account save file found \" %s \" ! \n Attempting automatic login for user \" %s \" ... \n " , MAIN_AccountSaveFilePath , Username ) ;
else printf ( " Account save file \" %s \" is invalid! \n " , MAIN_AccountSaveFilePath ) ;
fclose ( file ) ;
return success ;
}
return false ;
} /* GrabAccountFromSaveFile */
void GAME_ReadCredentials ( ) {
printf ( " Input your username: " ) ;
gets ( Username ) ;
printf ( " Input your password: " ) ;
gets ( Password ) ;
}
bool GAME_Login ( ) {
printf ( " Login: \n " ) ;
bool loginSuccess = HIGHSCORES_Login ( Username , Password ) ;
if ( loginSuccess ) {
printf ( " Successfully logged in as %s! \n " , Username ) ;
LoggedIn = true ;
} else
printf ( " Login failed! \n " ) ;
return loginSuccess ;
}
bool GAME_Register ( ) {
printf ( " Register: \n " ) ;
bool loginSuccess = HIGHSCORES_Register ( Username , Password ) ;
if ( loginSuccess ) {
printf ( " Successfully registered new account: %s! \n " , Username ) ;
LoggedIn = true ;
} else
printf ( " Registration failed! \n " ) ;
return loginSuccess ;
}
2018-01-29 19:10:08 +01:00
void AttemptLogin ( ) {
2018-01-29 23:15:40 +01:00
Username = calloc ( 50 , sizeof ( char ) ) ;
Password = calloc ( 50 , sizeof ( char ) ) ;
2018-01-29 21:26:48 +01:00
int state ;
bool loginSuccess = false ;
2018-01-29 19:10:08 +01:00
2018-01-29 23:15:40 +01:00
if ( GrabAccountFromSaveFile ( MAIN_AccountSaveFilePath ) ) {
if ( GAME_Login ( ) ) {
printf ( " Automatic login succeded! \n " ) ;
return ;
} else {
printf ( " Automatic login failed! Try manually! \n " ) ;
system ( " pause " ) ;
}
}
while ( ! loginSuccess ) {
2018-01-29 21:26:48 +01:00
system ( " cls " ) ;
printf ( " If you want to upload your score to the scoreboard you need to login! Enter \n \t - 1 for logging in with an existing account \n \t - 2 for creating a new account \n \t - 3 for playing unranked \n " ) ;
state = readIntFromIO ( " Input> " , " Invalid input! Awaited a number from 1 to 3. \n " , " %d is not a valid mode! \n " , 1 , 3 ) ;
switch ( state ) {
case 1 :
2018-01-29 23:15:40 +01:00
GAME_ReadCredentials ( ) ;
loginSuccess = GAME_Login ( ) ;
2018-01-29 21:26:48 +01:00
break ;
case 2 :
2018-01-29 23:15:40 +01:00
GAME_ReadCredentials ( ) ;
loginSuccess = GAME_Register ( ) ;
2018-01-29 21:26:48 +01:00
break ;
case 3 :
printf ( " Skipping login! " ) ;
LoggedIn = false ;
loginSuccess = true ;
break ;
default :
printf ( " This should not happen! State is %d... \n " , state ) ;
LoggedIn = false ;
loginSuccess = false ;
break ;
} /* switch */
if ( ! loginSuccess ) system ( " pause " ) ;
2018-01-29 23:15:40 +01:00
}
if ( PushNewCredentialsToSaveFile ( MAIN_AccountSaveFilePath ) ) printf ( " New login credentials were automatically saved! \n " ) ;
else printf ( " Login credentials could not be autosaved! \n " ) ;
2018-01-29 21:26:48 +01:00
} /* AttemptLogin */
int readIntFromIO ( char * m1 , char * m2 , char * m3 , int min , int max ) {
int nitems , num ;
while ( 1 ) {
while ( 1 ) {
printf ( m1 ) ;
nitems = scanf ( " %d " , & num ) ;
if ( nitems = = 0 ) {
printf ( m2 ) ;
fflush ( stdin ) ;
continue ;
} else {
break ;
}
}
if ( ( num < min ) | | ( num > max ) ) {
printf ( m3 , num ) ;
} else {
break ;
}
}
fflush ( stdin ) ;
return ( num ) ;
} /* readIntFromIO */
2018-01-29 19:10:08 +01:00
2018-01-18 13:15:12 +01:00
void GAME_Escape ( ) {
running = false ;
printf ( " GAME_Escape was called! \n " ) ;
}
2018-01-27 18:48:45 +01:00
void MENU_StartMusic ( ) {
printf ( " Attempting to start menu music... \n " ) ;
if ( ! Mix_PlayingMusic ( ) )
Mix_FadeInMusic ( MenuLoop , - 1 , MAIN_FadeTime ) ;
else printf ( " Menu music is already playing! \n " ) ;
}
void MENU_PauseMusic ( ) {
printf ( " Attempting to pause menu music... \n " ) ;
if ( Mix_PlayingMusic ( ) )
Mix_HaltMusic ( ) ;
// Mix_FadeOutMusic(MAIN_FadeTime);
else printf ( " There is no menu music to be paused! \n " ) ;
}
2018-01-16 12:10:37 +01:00
void GAME_ChangeState ( GameState state ) {
2018-01-27 18:48:45 +01:00
if ( state = = Game ) {
printf ( " Game music starting! \n " ) ;
MENU_PauseMusic ( ) ;
BREAKOUT_StartMusic ( ) ;
} else {
printf ( " Menu music starting! \n " ) ;
BREAKOUT_PauseMusic ( ) ;
MENU_StartMusic ( ) ;
}
2018-01-18 16:13:54 +01:00
if ( gameState = = state ) {
printf ( " State wasn't changed! \n " ) ;
return ;
}
2018-01-30 09:59:35 +01:00
previousGameState = gameState ;
2018-01-16 12:10:37 +01:00
gameState = state ;
switch ( gameState ) {
2018-01-25 17:05:12 +01:00
case Game :
BALL_ResetPosition ( & ( scenery . ball ) ) ;
break ;
2018-01-16 12:10:37 +01:00
case Highscores :
HIGHSCORES_ReloadList ( ) ;
2018-01-18 15:20:01 +01:00
HIGHSCORES_GenerateTexture ( renderer ) ;
2018-01-16 12:10:37 +01:00
printf ( " State was changed to Highscores! \n " ) ;
break ;
default :
printf ( " State was changed to %d! \n " , gameState ) ;
break ;
}
2018-01-27 18:48:45 +01:00
} /* GAME_ChangeState */
2018-01-30 09:59:35 +01:00
void GAME_ReturnToLastScreen ( ) {
if ( previousGameState = = gameState ) {
printf ( " Cannot \" return \" to the same screen! \n " ) ;
} else {
GAME_ChangeState ( previousGameState ) ;
}
}
2018-01-16 12:10:37 +01:00
2018-01-15 20:28:47 +01:00
void HandleSDLEvents ( ) {
while ( SDL_PollEvent ( & event ) ) {
switch ( event . type ) {
case SDL_QUIT :
2018-01-15 23:47:39 +01:00
printf ( " NOTICE: User manually quit window! \n " ) ;
2018-01-15 20:28:47 +01:00
running = false ;
break ;
case SDL_KEYDOWN :
2018-01-18 11:45:19 +01:00
// if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false;
// else
keyPress ( event . key ) ;
2018-01-15 20:28:47 +01:00
break ;
case SDL_MOUSEBUTTONDOWN :
mousePress ( event . button ) ;
break ;
case SDL_WINDOWEVENT :
windowChanged ( event . window ) ;
break ;
}
}
2018-01-18 11:45:19 +01:00
} /* HandleSDLEvents */
2018-01-15 20:28:47 +01:00
2018-01-07 14:19:35 +01:00
void mousePress ( SDL_MouseButtonEvent b ) { // Debug prop
2018-01-29 19:10:08 +01:00
switch ( gameState ) {
case GameOver :
2018-01-29 21:26:48 +01:00
GAMEOVER_MouseClicked ( b , & scenery ) ;
2018-01-29 19:10:08 +01:00
break ;
2018-01-30 09:59:35 +01:00
case MainMenu :
STARTMENU_ButtonClicked ( event . button , gameState ) ;
break ;
case Highscores :
HIGHSCORES_MouseClicked ( b ) ;
break ;
2018-01-29 19:10:08 +01:00
default :
printf ( " Gamestate currently ignores Mouse press event: %d! \n " , gameState ) ;
break ;
}
2018-01-07 14:19:35 +01:00
if ( b . button = = SDL_BUTTON_LEFT ) {
2018-01-10 15:37:55 +01:00
printf ( " Left mouse pressed at %d, %d \n " , b . x , b . y ) ;
2018-01-07 14:19:35 +01:00
} else if ( b . button = = SDL_BUTTON_RIGHT ) {
printf ( " Right mouse pressed... \n " ) ;
} else {
printf ( " Unknown mouse button pressed: %d \n " , b . button ) ;
}
2018-01-30 09:59:35 +01:00
} /* mousePress */
2018-01-07 14:19:35 +01:00
2018-01-07 14:45:07 +01:00
void keyPress ( SDL_KeyboardEvent b ) { // Debug prop
printf ( " Key pressed: ID is %d \n " , b . keysym . scancode ) ;
2018-01-11 18:45:00 +01:00
if ( b . keysym . scancode = = SDL_SCANCODE_F11 | | b . keysym . scancode = = SDL_SCANCODE_5 ) {
2018-01-08 00:45:32 +01:00
toggleFullscreen ( ) ;
2018-01-23 22:13:57 +01:00
} else {
switch ( gameState ) {
case Game :
BREAKOUT_KeyPressed ( & scenery , & b ) ;
break ;
default :
break ;
}
2018-01-08 00:45:32 +01:00
}
}
void toggleFullscreen ( ) {
if ( fullscreen ) {
SDL_SetWindowFullscreen ( window , SDL_WINDOW_FULLSCREEN_DESKTOP ) ;
} else {
SDL_SetWindowFullscreen ( window , 0 ) ;
}
fullscreen = ! fullscreen ;
}
void windowChanged ( SDL_WindowEvent b ) { // Debug prop
switch ( b . event ) {
case SDL_WINDOWEVENT_SIZE_CHANGED :
printf ( " Window was resized to (%d|%d)! \n " , event . window . data1 , event . window . data2 ) ;
2018-01-15 13:54:17 +01:00
// BREAKOUT_ChangeSize(event.window.data1, event.window.data2);
XScale = ( ( double ) ( event . window . data1 ) / ( double ) width ) ;
YScale = ( ( double ) ( event . window . data2 ) / ( double ) height ) ;
SDL_RenderSetScale ( renderer , XScale , YScale ) ;
2018-01-08 00:45:32 +01:00
break ;
}
2018-01-07 14:19:35 +01:00
}
2018-01-15 13:54:17 +01:00
void DrawBackground ( SDL_Renderer * renderer ) {
2018-01-10 15:37:55 +01:00
SDL_SetRenderDrawColor ( renderer , 0 , 0 , 0 , 255 ) ;
SDL_RenderClear ( renderer ) ;
2018-01-15 13:54:17 +01:00
} /* DrawFrame */
2018-01-14 13:47:05 +01:00
2018-01-30 09:59:35 +01:00
void GAME_Restart ( ) {
printf ( " Starting new game! \n " ) ;
scenery = BREAKOUT_CreateDefault ( ) ;
}
2018-01-29 21:26:48 +01:00
void INITIALIZE ( ) {
2018-01-15 22:01:58 +01:00
printf ( " Initializing started... \n " ) ;
2018-01-07 14:19:35 +01:00
srand ( time ( NULL ) ) ;
2018-01-14 13:47:05 +01:00
if ( SDL_Init ( SDL_INIT_EVERYTHING ) ! = 0 ) printf ( " SDL could not initialize! Error: %s \n " , SDL_GetError ( ) ) ;
2018-01-07 14:19:35 +01:00
else printf ( " SDL was successfully initialized! \n " ) ;
2018-01-15 22:01:58 +01:00
keystate = SDL_GetKeyboardState ( & numKeys ) ;
2018-01-14 13:47:05 +01:00
if ( IMG_Init ( IMG_INIT_PNG ) ! = IMG_INIT_PNG ) printf ( " IMG could not initialize! Error: %s \n " , IMG_GetError ( ) ) ;
2018-01-10 15:37:55 +01:00
else printf ( " IMG was successfully initialized! \n " ) ;
2018-01-14 13:47:05 +01:00
if ( TTF_Init ( ) = = - 1 ) printf ( " TTF could not initialize! Error: %s \n " , TTF_GetError ( ) ) ;
else printf ( " TTF was successfully initialized! \n " ) ;
2018-01-27 11:37:39 +01:00
if ( Mix_OpenAudio ( 44100 , MIX_DEFAULT_FORMAT , 2 , 2048 ) < 0 ) printf ( " Mixer could not initialize! Error %s \n " , Mix_GetError ( ) ) ;
else printf ( " Mixer was successfully initialized! \n " ) ;
2018-01-14 13:47:05 +01:00
2018-01-09 14:36:57 +01:00
window = SDL_CreateWindow ( " BreakING " , SDL_WINDOWPOS_UNDEFINED , SDL_WINDOWPOS_UNDEFINED , width , height , SDL_WINDOW_OPENGL ) ;
2018-01-08 00:45:32 +01:00
SDL_SetWindowResizable ( window , true ) ;
2018-01-24 14:50:34 +01:00
SDL_SetWindowFullscreen ( window , SDL_WINDOW_FULLSCREEN_DESKTOP ) ;
2018-01-07 14:19:35 +01:00
printf ( " Window was created! \n " ) ;
renderer = SDL_CreateRenderer ( window , - 1 , SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC ) ;
printf ( " Renderer was created! \n " ) ;
2018-01-23 21:22:01 +01:00
BREAKOUT_INITIALIZE ( renderer ) ;
2018-01-30 09:59:35 +01:00
GAME_Restart ( ) ;
2018-01-15 13:19:51 +01:00
Load_Textures ( renderer ) ;
2018-01-15 23:47:39 +01:00
HIGHSCORES_Initialize ( ) ;
2018-01-18 17:03:37 +01:00
BACKGROUND_Initialize ( renderer , width , height ) ;
2018-01-27 11:37:39 +01:00
Settings_Initialize ( renderer , & scenery ) ;
2018-01-23 21:22:01 +01:00
GAMEOVER_Initialize ( renderer ) ;
2018-01-27 18:48:45 +01:00
MenuLoop = Mix_LoadMUS ( MAIN_MenuMusicPath ) ;
2018-01-15 22:01:58 +01:00
printf ( " Initializing finished! \n " ) ;
2018-01-07 14:19:35 +01:00
} /* INITIALIZE */
void QUIT ( ) {
printf ( " De-initializing started... \n " ) ;
2018-01-29 23:15:40 +01:00
free ( Username ) ;
free ( Password ) ;
2018-01-27 18:48:45 +01:00
Mix_FreeMusic ( MenuLoop ) ;
2018-01-23 21:22:01 +01:00
GAMEOVER_Deinitialize ( ) ;
2018-01-19 07:57:47 +01:00
BACKGROUND_Deinitialize ( ) ;
2018-01-18 15:59:24 +01:00
Settings_Deinitialize ( ) ;
2018-01-15 23:47:39 +01:00
HIGHSCORES_Deinitialize ( ) ;
2018-01-15 22:01:58 +01:00
BREAKOUT_DestroyObject ( & scenery ) ;
2018-01-10 23:56:47 +01:00
BREAKOUT_DEINITIALIZE ( ) ;
2018-01-27 11:37:39 +01:00
Mix_CloseAudio ( ) ;
2018-01-10 15:37:55 +01:00
TTF_Quit ( ) ;
IMG_Quit ( ) ;
2018-01-07 14:19:35 +01:00
printf ( " Quitting SDL_IMG finished! \n " ) ;
SDL_DestroyRenderer ( renderer ) ;
printf ( " De-initializing renderer finished! \n " ) ;
SDL_DestroyWindow ( window ) ;
printf ( " De-initializing window finished! \n " ) ;
SDL_Quit ( ) ;
printf ( " Quitting SDL finished! \n " ) ;
printf ( " De-initializing finished! \n " ) ;
} /* QUIT */