diff --git a/source/code/ScoresDisplay.cpp b/source/code/ScoresDisplay.cpp new file mode 100644 index 0000000..7206262 --- /dev/null +++ b/source/code/ScoresDisplay.cpp @@ -0,0 +1,211 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: ScoresDisplay.cpp + * Author: poul + * + * Created on 7. februar 2016, 17:34 + */ + +#include "ScoresDisplay.hpp" +#include "global.hpp" +#include "common.h" +#include "stats.h" + +using namespace std; + +static void NFont_Write(SDL_Renderer* target, int x, int y, const char* text) { + nf_standard_blue_font.draw(target, x, y, "%s", text); +} + +const int numberOfPages = 3; + +//Draws the highscores +void ScoresDisplay::DrawHighscores(int x, int y, bool endless) { + backgroundImage.Draw(screen, 0, 0, 0); + if (endless) { + nf_standard_blue_font.draw(screen, x+100,y+100, "%s",_("Endless:") ); + } + else { + nf_standard_blue_font.draw(screen, x+100,y+100, "%s",_("Time Trial:") ); + } + for (int i =0; i<10; i++) { + char playerScore[32]; + char playerName[32]; + if (endless) { + snprintf(playerScore, sizeof(playerScore), "%i", theTopScoresEndless.getScoreNumber(i)); + } + else { + snprintf(playerScore, sizeof(playerScore), "%i", theTopScoresTimeTrial.getScoreNumber(i)); + } + if (endless) { + snprintf(playerName, sizeof(playerName), "%s", theTopScoresEndless.getScoreName(i)); + } + else { + snprintf(playerName, sizeof(playerName), "%s", theTopScoresTimeTrial.getScoreName(i)); + } + nf_standard_blue_font.draw(screen, x+420,y+150+i*35, "%s",playerScore); + nf_standard_blue_font.draw(screen, x+60,y+150+i*35, "%s",playerName); + } +} + +void ScoresDisplay::DrawStats() { + backgroundImage.Draw(screen, 0, 0, 0); + int y = 5; + const int y_spacing = 30; + NFont_Write(screen, 10,y,_("Stats") ); + y+=y_spacing*2; + NFont_Write(screen, 10,y,_("Chains") ); + for (int i=2; i<13; i++) { + y+=y_spacing; + NFont_Write(screen, 10,y,(itoa(i)+"X").c_str()); + string numberAsString = itoa(Stats::getInstance()->getNumberOf("chainX"+itoa(i))); + NFont_Write(screen, 300,y,numberAsString.c_str()); + } + y+=y_spacing*2; + NFont_Write(screen, 10,y,_("Lines Pushed: ") ); + string numberAsString = itoa(Stats::getInstance()->getNumberOf("linesPushed")); + NFont_Write(screen, 300,y,numberAsString.c_str()); + + y+=y_spacing; + NFont_Write(screen, 10,y, _("Puzzles solved: ") ); + numberAsString = itoa(Stats::getInstance()->getNumberOf("puzzlesSolved")); + NFont_Write(screen, 300,y,numberAsString.c_str()); + + y+=y_spacing*2; + NFont_Write(screen, 10,y, _("Run time: ") ); + commonTime ct = TimeHandler::peekTime("totalTime",TimeHandler::ms2ct(SDL_GetTicks())); + y+=y_spacing; + NFont_Write(screen, 10, y, SPrintCF( _("Days: %i"), ct.days) ); + y+=y_spacing; + NFont_Write(screen, 10, y, SPrintCF( _("Hours: %i"), ct.hours) ); + y+=y_spacing; + NFont_Write(screen, 10, y, SPrintCF( _("Minutes: %i"), ct.minutes) ); + y+=y_spacing; + NFont_Write(screen, 10, y, SPrintCF( _("Seconds: %i"), ct.seconds) ); + + y-=y_spacing*4; //Four rows back + const int x_offset3 = xsize/3+10; //Ofset for three rows + NFont_Write(screen, x_offset3,y, _("Play time: ") ); + ct = TimeHandler::getTime("playTime"); + y+=y_spacing; + NFont_Write(screen, x_offset3, y, SPrintCF( _("Days: %i"), ct.days) ); + y+=y_spacing; + NFont_Write(screen, x_offset3, y, SPrintCF( _("Hours: %i"), ct.hours) ); + y+=y_spacing; + NFont_Write(screen, x_offset3, y, SPrintCF( _("Minutes: %i"), ct.minutes) ); + y+=y_spacing; + NFont_Write(screen, x_offset3, y, SPrintCF( _("Seconds: %i"), ct.seconds) ); + + const int x_offset = xsize/2+10; + y = 5+y_spacing*2; + NFont_Write(screen, x_offset,y, _("VS CPU (win/loss)") ); + for (int i=0; i<7; i++) { + y += y_spacing; + NFont_Write(screen, x_offset,y,string("AI "+itoa(i+1)).c_str()); + numberAsString = itoa(Stats::getInstance()->getNumberOf("defeatedAI"+itoa(i))); + string numberAsString2 = itoa(Stats::getInstance()->getNumberOf("defeatedByAI"+itoa(i))); + string toPrint = numberAsString + "/" + numberAsString2; + NFont_Write(screen, x_offset+230,y,toPrint.c_str()); + } +} + +ScoresDisplay::ScoresDisplay() { +} + +ScoresDisplay::~ScoresDisplay() { +} + +bool ScoresDisplay::IsActive() { + return isActive; +} + +void ScoresDisplay::Draw(SDL_Renderer* target) { + switch (page) { + case 0: + //Highscores, endless + DrawHighscores(100,100,true); + break; + case 1: + //Highscores, Time Trial + DrawHighscores(100,100,false); + break; + case 2: + default: + DrawStats(); + }; + + //Draw buttons: + bHighScore.Draw(screen, 0, scoreX,scoreY); + bBack.Draw(screen, 0, backX, backY); + nf_button_font.draw(screen, backX+60,backY+10, NFont::CENTER ,_("Back")); + bNext.Draw(screen, 0, nextX, nextY); + nf_button_font.draw(screen, nextX+60,nextY+10, NFont::CENTER,_("Next")); + + //Draw page number + string pageXofY = (boost::format(_("Page %1% of %2%") )%(page+1)%numberOfPages).str(); + NFont_Write(screen, xsize/2-nf_standard_blue_font.getWidth( "%s", pageXofY.c_str())/2,ysize-60,pageXofY.c_str()); +} + +void ScoresDisplay::ProcessInput(const SDL_Event& event, bool &processed) { + if ( event.type == SDL_KEYDOWN ) { + if ( (event.key.keysym.sym == SDLK_RIGHT)) { + page++; + if (page>=numberOfPages) { + page = 0; + } + } + else if ( (event.key.keysym.sym == SDLK_LEFT)) { + page--; + if (page<0) { + page = numberOfPages-1; + } + } + + if ( (event.key.keysym.sym == SDLK_RETURN)||(event.key.keysym.sym == SDLK_KP_ENTER) ) { + isActive = false; + } + else if ( (event.key.keysym.sym == SDLK_ESCAPE) ) { + isActive = false; + } + } +} + +void ScoresDisplay::Update() { + int mousex, mousey; + SDL_GetMouseState(&mousex,&mousey); + + // If the mouse button is released, make bMouseUp equal true + if (!SDL_GetMouseState(nullptr, nullptr)&SDL_BUTTON(1)) { + bMouseUp=true; + } + + if (SDL_GetMouseState(nullptr,nullptr)&SDL_BUTTON(1) && bMouseUp) { + bMouseUp = false; + + //The Score button: + if ((mousex>scoreX) && (mousexscoreY) && (mouseybackX) && (mousexbackY) && (mouseynextX) && (mousexnextY) && (mousey=numberOfPages) { + page = 0; + } + } + } +} \ No newline at end of file diff --git a/source/code/ScoresDisplay.hpp b/source/code/ScoresDisplay.hpp new file mode 100644 index 0000000..8a9141d --- /dev/null +++ b/source/code/ScoresDisplay.hpp @@ -0,0 +1,50 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: ScoresDisplay.hpp + * Author: poul + * + * Created on 7. februar 2016, 17:34 + */ + +#ifndef SCORESDISPLAY_HPP +#define SCORESDISPLAY_HPP + +#include "sago/GameStateInterface.hpp" + +class ScoresDisplay : public sago::GameStateInterface { +public: + ScoresDisplay(); + ScoresDisplay(const ScoresDisplay& orig) = delete; + virtual ~ScoresDisplay(); + + bool IsActive() override; + void Draw(SDL_Renderer* target) override; + void ProcessInput(const SDL_Event& event, bool &processed) override; + void Update() override; + + int page = 0; + //button coodinates: + int scoreX = 0; + int scoreY = 0; + int backX = 20; + int backY = 0; + int nextX = 0; + int nextY = 0; + int xsize = 0; + int ysize = 0; + int buttonXsize = 0; + int buttonYsize = 0; +private: + void DrawHighscores(int x, int y, bool endless); + void DrawStats(); + bool isActive = true; + bool bMouseUp = false; +}; + +#endif /* SCORESDISPLAY_HPP */ + diff --git a/source/code/global.hpp b/source/code/global.hpp index 9be0e65..24f8d25 100644 --- a/source/code/global.hpp +++ b/source/code/global.hpp @@ -27,13 +27,19 @@ http://blockattack.net #include "Libs/NFont.h" #include #include "sago/SagoSpriteHolder.hpp" +#include "highscore.h" void MainMenu(); void ResetFullscreen(); extern sago::SagoSprite menuMarked; extern sago::SagoSprite menuUnmarked; +extern sago::SagoSprite bHighScore; +extern sago::SagoSprite bBack; +extern sago::SagoSprite bNext; extern NFont nf_scoreboard_font; +extern NFont nf_standard_blue_font; +extern NFont nf_button_font; extern bool MusicEnabled; //true if background music is enabled extern bool SoundEnabled; //true if sound effects is enabled extern bool bFullscreen; //true if game is running fullscreen @@ -44,6 +50,8 @@ extern sago::SagoSprite mouse; extern sago::SagoSprite backgroundImage; extern bool highPriority; extern int verboseLevel; +extern Highscore theTopScoresEndless; //Stores highscores for endless +extern Highscore theTopScoresTimeTrial; //Stores highscores for timetrial #endif /* _GLOBAL_HPP */ diff --git a/source/code/highscore.h b/source/code/highscore.h index 97b6bc8..4e8d5fe 100644 --- a/source/code/highscore.h +++ b/source/code/highscore.h @@ -27,6 +27,9 @@ http://blockattack.net #include #include +#ifndef HIGHSCORE_H +#define HIGHSCORE_H + const int top = 10; struct record @@ -56,3 +59,5 @@ public: int getScoreNumber(int); const char* getScoreName(int); }; + +#endif \ No newline at end of file diff --git a/source/code/main.cpp b/source/code/main.cpp index ee79aa1..01b2a6d 100644 --- a/source/code/main.cpp +++ b/source/code/main.cpp @@ -60,6 +60,7 @@ http://blockattack.net #include "puzzlehandler.hpp" #include "stageclearhandler.hpp" #include +#include "ScoresDisplay.hpp" //if SHAREDIR is not used we look in current directory #ifndef SHAREDIR @@ -245,11 +246,11 @@ void DrawIMG_Bounded(sago::SagoSprite& sprite, SDL_Renderer* target, int x, int } -void NFont_Write(SDL_Renderer* target, int x, int y, const string& text) { +static void NFont_Write(SDL_Renderer* target, int x, int y, const string& text) { nf_standard_blue_font.draw(target, x, y, "%s", text.c_str()); } -void NFont_Write(SDL_Renderer* target, int x, int y, const char* text) { +static void NFont_Write(SDL_Renderer* target, int x, int y, const char* text) { nf_standard_blue_font.draw(target, x, y, "%s", text); } @@ -557,6 +558,7 @@ static TextManager theTextManager; #include "BlockGame.cpp" #include "os.hpp" #include "sago/SagoMiscSdl2.hpp" +#include "ScoresDisplay.hpp" class BlockGameSdl : public BlockGame { public: @@ -991,217 +993,61 @@ bool OpenDialogbox(int x, int y, std::string& name) { return accept; } -//Draws the highscores -void DrawHighscores(int x, int y, bool endless) { - DrawIMG(backgroundImage,screen,0,0); - if (endless) { - nf_standard_blue_font.draw(screen, x+100,y+100, "%s",_("Endless:") ); - } - else { - nf_standard_blue_font.draw(screen, x+100,y+100, "%s",_("Time Trial:") ); - } - for (int i =0; i<10; i++) { - char playerScore[32]; - char playerName[32]; - if (endless) { - snprintf(playerScore, sizeof(playerScore), "%i", theTopScoresEndless.getScoreNumber(i)); - } - else { - snprintf(playerScore, sizeof(playerScore), "%i", theTopScoresTimeTrial.getScoreNumber(i)); - } - if (endless) { - snprintf(playerName, sizeof(playerName), "%s", theTopScoresEndless.getScoreName(i)); - } - else { - snprintf(playerName, sizeof(playerName), "%s", theTopScoresTimeTrial.getScoreName(i)); - } - nf_standard_blue_font.draw(screen, x+420,y+150+i*35, "%s",playerScore); - nf_standard_blue_font.draw(screen, x+60,y+150+i*35, "%s",playerName); - } -} -void DrawStats() { - DrawIMG(backgroundImage,screen,0,0); - int y = 5; - const int y_spacing = 30; - NFont_Write(screen, 10,y,_("Stats") ); - y+=y_spacing*2; - NFont_Write(screen, 10,y,_("Chains") ); - for (int i=2; i<13; i++) { - y+=y_spacing; - NFont_Write(screen, 10,y,(itoa(i)+"X").c_str()); - string numberAsString = itoa(Stats::getInstance()->getNumberOf("chainX"+itoa(i))); - NFont_Write(screen, 300,y,numberAsString.c_str()); - } - y+=y_spacing*2; - NFont_Write(screen, 10,y,_("Lines Pushed: ") ); - string numberAsString = itoa(Stats::getInstance()->getNumberOf("linesPushed")); - NFont_Write(screen, 300,y,numberAsString.c_str()); - - y+=y_spacing; - NFont_Write(screen, 10,y, _("Puzzles solved: ") ); - numberAsString = itoa(Stats::getInstance()->getNumberOf("puzzlesSolved")); - NFont_Write(screen, 300,y,numberAsString.c_str()); - - y+=y_spacing*2; - NFont_Write(screen, 10,y, _("Run time: ") ); - commonTime ct = TimeHandler::peekTime("totalTime",TimeHandler::ms2ct(SDL_GetTicks())); - y+=y_spacing; - NFont_Write(screen, 10, y, SPrintCF( _("Days: %i"), ct.days) ); - y+=y_spacing; - NFont_Write(screen, 10, y, SPrintCF( _("Hours: %i"), ct.hours) ); - y+=y_spacing; - NFont_Write(screen, 10, y, SPrintCF( _("Minutes: %i"), ct.minutes) ); - y+=y_spacing; - NFont_Write(screen, 10, y, SPrintCF( _("Seconds: %i"), ct.seconds) ); - - y-=y_spacing*4; //Four rows back - const int x_offset3 = xsize/3+10; //Ofset for three rows - NFont_Write(screen, x_offset3,y, _("Play time: ") ); - ct = TimeHandler::getTime("playTime"); - y+=y_spacing; - NFont_Write(screen, x_offset3, y, SPrintCF( _("Days: %i"), ct.days) ); - y+=y_spacing; - NFont_Write(screen, x_offset3, y, SPrintCF( _("Hours: %i"), ct.hours) ); - y+=y_spacing; - NFont_Write(screen, x_offset3, y, SPrintCF( _("Minutes: %i"), ct.minutes) ); - y+=y_spacing; - NFont_Write(screen, x_offset3, y, SPrintCF( _("Seconds: %i"), ct.seconds) ); - - const int x_offset = xsize/2+10; - y = 5+y_spacing*2; - NFont_Write(screen, x_offset,y, _("VS CPU (win/loss)") ); - for (int i=0; i<7; i++) { - y += y_spacing; - NFont_Write(screen, x_offset,y,string("AI "+itoa(i+1)).c_str()); - numberAsString = itoa(Stats::getInstance()->getNumberOf("defeatedAI"+itoa(i))); - string numberAsString2 = itoa(Stats::getInstance()->getNumberOf("defeatedByAI"+itoa(i))); - string toPrint = numberAsString + "/" + numberAsString2; - NFont_Write(screen, x_offset+230,y,toPrint.c_str()); - } -} - -void OpenScoresDisplay() { +void RunGameState(sago::GameStateInterface &state ) { int mousex,mousey; bool done = false; //We are done! - int page = 0; - const int numberOfPages = 3; - //button coodinates: - const int scoreX = buttonXsize*2; - const int scoreY = 0; - const int backX = 20; - const int backY = ysize-buttonYsize-20; - const int nextX = xsize-buttonXsize-20; - const int nextY = backY; while (!done && !Config::getInstance()->isShuttingDown()) { - switch (page) { - case 0: - //Highscores, endless - DrawHighscores(100,100,true); - break; - case 1: - //Highscores, Time Trial - DrawHighscores(100,100,false); - break; - case 2: - default: - DrawStats(); - }; - - //Draw buttons: - DrawIMG(bHighScore,screen,scoreX,scoreY); - DrawIMG(bBack,screen,backX,backY); - nf_button_font.draw(screen, backX+60,backY+10, NFont::CENTER ,_("Back")); - DrawIMG(bNext,screen,nextX,nextY); - nf_button_font.draw(screen, nextX+60,nextY+10, NFont::CENTER,_("Next")); - - //Draw page number - string pageXofY = (boost::format(_("Page %1% of %2%") )%(page+1)%numberOfPages).str(); - NFont_Write(screen, xsize/2-nf_standard_blue_font.getWidth( "%s", pageXofY.c_str())/2,ysize-60,pageXofY.c_str()); - + state.Draw(screen); + SDL_Delay(1); SDL_Event event; SDL_GetMouseState(&mousex,&mousey); bool mustWriteScreenshot = false; - + while ( SDL_PollEvent(&event) ) { - - if ( event.type == SDL_QUIT ) { Config::getInstance()->setShuttingDown(5); done = true; } - - if ( event.type == SDL_KEYDOWN ) { - if ( (event.key.keysym.sym == SDLK_RIGHT)) { - page++; - if (page>=numberOfPages) { - page = 0; - } - } - else if ( (event.key.keysym.sym == SDLK_LEFT)) { - page--; - if (page<0) { - page = numberOfPages-1; - } - } - else { - done = true; - } - - if ( event.key.keysym.sym == SDLK_F9 ) { - mustWriteScreenshot = true; - } - - if ( (event.key.keysym.sym == SDLK_RETURN)||(event.key.keysym.sym == SDLK_KP_ENTER) ) { - done = true; - } - else if ( (event.key.keysym.sym == SDLK_ESCAPE) ) { - done = true; - } - } - - } //while(event) - - // If the mouse button is released, make bMouseUp equal true - if (!SDL_GetMouseState(nullptr, nullptr)&SDL_BUTTON(1)) { - bMouseUp=true; - } - - if (SDL_GetMouseState(nullptr,nullptr)&SDL_BUTTON(1) && bMouseUp) { - bMouseUp = false; - - //The Score button: - if ((mousex>scoreX) && (mousexscoreY) && (mouseybackX) && (mousexbackY) && (mouseynextX) && (mousexnextY) && (mousey=numberOfPages) { - page = 0; - } + + if ( event.key.keysym.sym == SDLK_F9 ) { + mustWriteScreenshot = true; } + + bool processed = false; + state.ProcessInput(event, processed); + } - + + state.Update(); + mouse.Draw(screen, SDL_GetTicks(), mousex, mousey); SDL_RenderPresent(screen); if (mustWriteScreenshot) { writeScreenShot(); } - } + if (!state.IsActive()) { + done = true; + } + } +} +void OpenScoresDisplay() { + ScoresDisplay d; + d.scoreX = buttonXsize*2; + d.scoreY = 0; + d.backX = 20; + d.backY = ysize-buttonYsize-20; + d.nextX = xsize-buttonXsize-20; + d.nextY = d.backY; + d.xsize = xsize; + d.ysize = ysize; + d.buttonXsize = buttonXsize; + d.buttonYsize = buttonYsize; + RunGameState(d); } diff --git a/source/code/mainVars.hpp b/source/code/mainVars.hpp index 6de66d1..233a164 100644 --- a/source/code/mainVars.hpp +++ b/source/code/mainVars.hpp @@ -45,14 +45,14 @@ const char sharedir[] = SHAREDIR; //All graphic in the game (as pointers): sago::SagoSprite backgroundImage; //Stores the background image static sago::SagoSprite backBoard; //Stores the background to the board -static sago::SagoSprite bBack; //The "Back" button +sago::SagoSprite bBack; //The "Back" button static sago::SagoSprite bForward; //The "forward" button #if NETWORK //static sago::SagoSprite bNetwork; //static sago::SagoSprite bConnect; //static sago::SagoSprite bHost; #endif -static sago::SagoSprite bHighScore; //The High Score botton +sago::SagoSprite bHighScore; //The High Score botton static sago::SagoSprite blackLine; //The seperator in stage clear static sago::SagoSprite stageBobble; //The bobble instage clear SDL_Renderer *screen; //The whole screen; @@ -94,33 +94,17 @@ static sago::SagoSprite garbageGM; static sago::SagoSprite garbageGML; static sago::SagoSprite garbageGMR; static sago::SagoSprite transCover; //The transperant block, covers the upcomming -#if LEVELEDITOR -static sago::SagoSprite bCreateFile; -static sago::SagoSprite bDeletePuzzle; -static sago::SagoSprite bLoadFile; -static sago::SagoSprite bMoveBack; -static sago::SagoSprite bMoveDown; -static sago::SagoSprite bMoveForward; -static sago::SagoSprite bMoveLeft; -static sago::SagoSprite bMoveRight; -static sago::SagoSprite bMoveUp; -static sago::SagoSprite bNewPuzzle; -static sago::SagoSprite bSaveFileAs; -static sago::SagoSprite bSavePuzzle; -static sago::SagoSprite bSaveToFile; -static sago::SagoSprite bTestPuzzle; -#endif static sago::SagoSprite bSkip; static sago::SagoSprite bRetry; -static sago::SagoSprite bNext; +sago::SagoSprite bNext; sago::SagoSprite menuMarked; sago::SagoSprite menuUnmarked; sago::SagoSprite mouse; -static NFont nf_button_font; //Font used for buttons! +NFont nf_button_font; //Font used for buttons! NFont nf_scoreboard_font; -static NFont nf_standard_blue_font; //Font used instead of the old blue SFont +NFont nf_standard_blue_font; //Font used instead of the old blue SFont static NFont nf_standard_small_font; static Mix_Music *bgMusic; //backgroundMusic @@ -155,18 +139,6 @@ bool highPriority; static bool editorMode = false; static bool editorModeTest = false; -//Things for network play: -#if NETWORK -static bool networkPlay; -static bool networkActive; -//sockets here -#define SERVERPORT 41780 -#define CLIENTPORT 41781 - - -static char serverAddress[30]; -#endif - //other ball constants: const double gravity = 200.8; //acceleration const double startVelocityY = 50.0; diff --git a/source/code/sago/GameStateInterface.hpp b/source/code/sago/GameStateInterface.hpp new file mode 100644 index 0000000..646e6ff --- /dev/null +++ b/source/code/sago/GameStateInterface.hpp @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: GameStateInterface.hpp + * Author: poul + * + * Created on 7. februar 2016, 17:26 + */ + +#ifndef GAMESTATEINTERFACE_HPP +#define GAMESTATEINTERFACE_HPP + +#include "SDL.h" + +namespace sago { + +class GameStateInterface { +public: + /** + * Is the state active. If this returns false then the State-manager will pop the state object + * @return true if active + */ + virtual bool IsActive() = 0; + + /** + * Tells the state to draw itself to target + * @param target The RenderWindow to draw to + */ + virtual void Draw(SDL_Renderer* target) = 0; + + virtual void ProcessInput(const SDL_Event& event, bool &processed) = 0; + + virtual void Update() {} +}; + +} //sago + +#endif /* GAMESTATEINTERFACE_HPP */ + diff --git a/source/code/sago/SagoMiscSdl2.cpp b/source/code/sago/SagoMiscSdl2.cpp index ce11f8b..3db095b 100644 --- a/source/code/sago/SagoMiscSdl2.cpp +++ b/source/code/sago/SagoMiscSdl2.cpp @@ -50,4 +50,5 @@ void sago::SagoFatalErrorF(const char* fmt, ...) { vsnprintf(buffer, sizeof(buffer), fmt, args); SagoFatalError(buffer); va_end(args); -} \ No newline at end of file +} +