When I run the game:
// Compile with: g++ main.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -o "Five Nights At Chipflakes"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#define SDL_INITIALIZATION_ERROR 1
#define IMG_INITIALIZATION_ERROR 2
#define TTF_INITIALIZATION_ERROR 3
#define SAVEDATA_LOADING_ERROR 4
#define WINDOW_CREATION_ERROR 5
#define RENDERER_CREATION_ERROR 6
#define IMAGE_LOADING_ERROR 7
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* imageSlot[10];
SDL_Rect imageRect[10];
std::vector<SDL_Texture*> animationFrames1;
std::vector<SDL_Rect> animationFrameRects1;
std::vector<SDL_Texture*> animationFrames2;
std::vector<SDL_Rect> animationFrameRects2;
std::vector<SDL_Texture*> animationFrames3;
std::vector<SDL_Rect> animationFrameRects3;
int animationIndex = 0;
bool animationOnePlaying = false;
bool animationTwoPlaying = false;
bool animationThreePlaying = false;
int animationOneLoops;
int animationTwoLoops;
int animationThreeLoops;
SDL_Texture* textTexture[10];
SDL_Rect textRect[10];
TTF_Font* mainFont;
int imageIndex = 0;
int textIndex = 0;
int buttonIndex = 0;
int elapsedFrames = 0;
int elaspedMilliseconds = 0;
int scene = 1;
bool scenesLoaded[1] = {false};
const char* staticEffect[8] = {"./Assets/Animations/Static/Frame1.png", "./Assets/Animations/Static/Frame2.png", "./Assets/Animations/Static/Frame3.png", "./Assets/Animations/Static/Frame4.png", "./Assets/Animations/Static/Frame5.png", "./Assets/Animations/Static/Frame6.png", "./Assets/Animations/Static/Frame7.png", "./Assets/Animations/Static/Frame8.png"};
SDL_Rect staticEffectRect[8];
const char* saveDataPath = "./savadata.ini";
std::string saveDataLines[4];
int night;
bool star1;
bool star2;
bool star3;
bool printElapsedMilliseconds = false;
bool printMousePos = false;
bool printRandomNumber = false;
bool printFrameRate = false;
int mouseX;
int mouseY;
bool mouseDown;
int randomNumber;
float averageFPS;
bool evilChipLoaded = false;
SDL_Rect button[10];
int createWindow()
{
if(SDL_Init(SDL_INIT_EVERYTHING) != 0){return SDL_INITIALIZATION_ERROR;}
if(IMG_Init(IMG_INIT_PNG) == 0){return IMG_INITIALIZATION_ERROR;}
if(TTF_Init() != 0){return TTF_INITIALIZATION_ERROR;}
std::ifstream saveData("savedata.ini");
if(!saveData.is_open()){return SAVEDATA_LOADING_ERROR;}
for(int i = 0; i < 4; i++)
{
std::getline(saveData, saveDataLines[i]);
}
std::cout << saveDataLines[0] << ", " << saveDataLines[1] << ", " << saveDataLines[2] << ", " << saveDataLines[3] << std::endl;
for(int i = 0; i < saveDataLines[0].length(); i++)
{
char c;
c = saveDataLines[0][i];
switch(c)
{
case '1':
night = 1;
break;
case '2':
night = 2;
break;
case '3':
night = 3;
break;
case '4':
night = 4;
break;
case '5':
night = 5;
break;
case '6':
night = 6;
break;
case '7':
night = 7;
break;
default:
break;
}
}
mainFont = TTF_OpenFont("./Assets/mainFont.ttf", 32);
if(mainFont == nullptr)
{
std::cout << "Error trying to load font." << std::endl;
}
window = SDL_CreateWindow("Five Nights at Chipflakes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_FULLSCREEN);
if(window == NULL){return WINDOW_CREATION_ERROR;}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
if(renderer == NULL){return RENDERER_CREATION_ERROR;}
return 0;
}
void destroyTextures()
{
for(int i = 0; i < 10; i++)
{
SDL_DestroyTexture(imageSlot[i]);
imageSlot[i] = nullptr;
}
}
void destroyTexture(int slot)
{
SDL_DestroyTexture(imageSlot[slot]);
imageSlot[slot] = nullptr;
}
void destroyTextTexture(int slot)
{
textTexture[slot] = nullptr;
}
void destroyTextTextures()
{
for(int i = 0; i < 10; i++)
{
destroyTextTexture(i);
textTexture[i] = nullptr;
}
}
int quit()
{
std::string replacementLines[4] = {"night=" + std::to_string(night), "star1=" + std::to_string(star1), "star2=" + std::to_string(star2), "star3=" + std::to_string(star3)};
std::string lines[4];
std::ifstream saveDataRead("savedata.ini");
std::ofstream saveDataWrite("savedata.ini", std::ios::trunc);
std::getline(saveDataRead, lines[0]);
std::getline(saveDataRead, lines[1]);
std::getline(saveDataRead, lines[2]);
std::getline(saveDataRead, lines[0]);
for (const auto& replacementLine : replacementLines)
{
saveDataWrite << replacementLine << std::endl;
}
saveDataRead.close();
saveDataWrite.close();
destroyTextures();
destroyTextTextures();
SDL_DestroyWindow(window);
SDL_Quit();
exit(0);
}
int loadImage(const char* path, int posX, int posY, int width, int height)
{
if(imageIndex > 9 || imageIndex < 0)
{
imageIndex == 0;
std::cout << "imageIndex rollover." << std::endl;
}
imageSlot[imageIndex] = IMG_LoadTexture(renderer, path);
imageRect[imageIndex].x = posX;
imageRect[imageIndex].y = posY;
imageRect[imageIndex].w = width;
imageRect[imageIndex].h = height;
if(imageSlot[imageIndex] == NULL){return IMAGE_LOADING_ERROR;}
std::cout << "imageIndex " << imageIndex << " loaded." << std::endl;
imageIndex++;
return 0;
}
int loadImageAtSpecificSlot(int slot, const char* path, int posX, int posY, int width, int height)
{
imageSlot[slot] = IMG_LoadTexture(renderer, path);
imageRect[slot].x = posX;
imageRect[slot].y = posY;
imageRect[slot].w = width;
imageRect[slot].h = height;
if(imageSlot[slot] == NULL){return IMAGE_LOADING_ERROR;}
std::cout << "Image slot " << slot << " was loaded." << std::endl;
return 0;
}
void displayText(const char* text, Uint8 colorR, Uint8 colorG, Uint8 colorB, int posX, int posY, int width, int height)
{
SDL_Surface* textSurface = TTF_RenderText_Solid(mainFont, text, {colorR, colorG, colorB});
textTexture[textIndex] = SDL_CreateTextureFromSurface(renderer, textSurface);
SDL_FreeSurface(textSurface);
textRect[textIndex].x = posX;
textRect[textIndex].y = posY;
textRect[textIndex].w = width;
textRect[textIndex].h = height;
std::cout << "textTexture " << textIndex << " loaded." << std::endl;
textIndex++;
}
void createButton(int posX, int posY, int width, int height)
{
button[buttonIndex].x = posX;
button[buttonIndex].y = posY;
button[buttonIndex].w = width;
button[buttonIndex].h = height;
buttonIndex++;
}
void createButtonAtSpecificSlot(int slot, int posX, int posY, int width, int height)
{
button[slot].x = posX;
button[slot].y = posY;
button[slot].w = width;
button[slot].h = height;
}
void clearScene()
{
destroyTextures();
destroyTextTextures();
scene++;
}
void playAnimation(const char* framePaths[], SDL_Rect frameRects[], int size, int loops)
{
if(animationIndex > 2 || animationIndex < 0)
{
std::cout << "Animation index overflow." << std::endl;
}
if(animationIndex == 0)
{
animationOneLoops = loops;
animationFrames1.resize(size);
animationFrameRects1.resize(size);
for(int i = 0; i < size; i++)
{
animationFrames1.insert(animationFrames1.begin(), IMG_LoadTexture(renderer, framePaths[i]));
}
animationOnePlaying = true;
}
else if(animationIndex == 1)
{
animationTwoLoops = loops;
animationFrames2.resize(size);
animationFrameRects2.resize(size);
for(int i = 0; i < size; i++)
{
animationFrames2.insert(animationFrames2.begin(), IMG_LoadTexture(renderer, framePaths[i]));
}
animationTwoPlaying = true;
}
else if(animationIndex == 2)
{
animationThreeLoops = loops;
animationFrames3.resize(size);
animationFrameRects3.resize(size);
for(int i = 0; i < size; i++)
{
animationFrames3.insert(animationFrames3.begin(), IMG_LoadTexture(renderer, framePaths[i]));
}
animationThreePlaying = true;
}
animationIndex++;
}
void declareAnimationRects()
{
for(int i = 0; i < sizeof(staticEffectRect); i++)
{
staticEffectRect[i].x = 0;
staticEffectRect[i].y = 0;
staticEffectRect[i].w = 1920;
staticEffectRect[i].h = 1080;
}
}
void getInput()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_F1:
if(printElapsedMilliseconds)
{
printElapsedMilliseconds = false;
}
else
{
printElapsedMilliseconds = true;
}
break;
case SDLK_F2:
if(printMousePos)
{
printMousePos = false;
}
else
{
printMousePos = true;
}
break;
case SDLK_F3:
if(printRandomNumber)
{
printRandomNumber = false;
}
else
{
printRandomNumber = true;
}
break;
case SDLK_F4:
if(printFrameRate)
{
printFrameRate = false;
}
else
{
printFrameRate = true;
}
}
break;
case SDL_MOUSEBUTTONDOWN:
if(event.button.button == SDL_BUTTON_LEFT)
{
mouseDown = true;
}
break;
case SDL_MOUSEBUTTONUP:
if(event.button.button == SDL_BUTTON_LEFT)
{
mouseDown = false;
}
break;
case SDL_QUIT:
quit();
break;
}
}
}
void callEvents()
{
if(scene == 1)
{
if(scenesLoaded[0] == false)
{
std::cout << night << std::endl;
if(loadImage("./Assets/Sprites/mainMenuChipflake1.png", 1279, 0, 641, 1081) == IMAGE_LOADING_ERROR)
{
std::cout << "Error loading image. Program will be terminated. " << IMG_GetError() << std::endl;
}
displayText("Five Nights at Chipflakes", 255, 255, 255, 25, 25, 1200, 150);
displayText("New Game", 255, 255, 255, 30, 360, 450, 150);
if(night == 1)
{
displayText("Continue", 125, 125, 125, 30, 540, 450, 150);
}
else
{
displayText("Continue", 255, 255, 255, 30, 540, 450, 150);
}
displayText("Wimp?", 255, 255, 255, 30, 720, 350, 150);
createButton(10, 350, 490, 190);
createButton(10, 520, 490, 190);
createButton(10, 690, 490, 190);
scenesLoaded[0] = true;
}
if(randomNumber == 1 || randomNumber == 2 || randomNumber == 3 || randomNumber == 4)
{
if(!evilChipLoaded)
{
std::cout << "Chip has turned evil." << std::endl;
destroyTexture(0);
if(loadImageAtSpecificSlot(0, "./Assets/Sprites/mainMenuChipflake2.png", 1279, 0, 641, 1081) == IMAGE_LOADING_ERROR)
{
std::cout << "Error loading image. Program will be terminated. " << IMG_GetError() << std::endl;
}
evilChipLoaded = true;
}
else
{
if(randomNumber == 1 || randomNumber == 2 || randomNumber == 3 || randomNumber == 4 || randomNumber == 5 || randomNumber == 6 || randomNumber == 7 || randomNumber == 8)
{
std::cout << "Chip has been redeemed." << std::endl;
destroyTexture(0);
if(loadImageAtSpecificSlot(0, "./Assets/Sprites/mainMenuChipflake1.png", 1279, 0, 641, 1081) == IMAGE_LOADING_ERROR)
{
std::cout << "Error loading image. Program will be terminated. " << IMG_GetError() << std::endl;
}
evilChipLoaded = false;
}
}
}
playAnimation(staticEffect, staticEffectRect, 8, -1);
}
}
void refreshScreen()
{
bool framePlayed = false;
SDL_RenderClear(renderer);
if(animationOnePlaying)
{
while(animationOneLoops != 0)
{
for(int i = 0; i < animationFrameRects1.size(); i++)
{
if(i != 0)
{
SDL_DestroyTexture(animationFrames1[i-1]);
}
SDL_RenderCopy(renderer, animationFrames1[i], NULL, &animationFrameRects1[i]);
animationOneLoops--;
}
}
}
if(animationTwoPlaying)
{
while(animationOneLoops != 0)
{
for(int i = 0; i < animationFrameRects2.size(); i++)
{
if(i != 0)
{
SDL_DestroyTexture(animationFrames2[i-1]);
}
SDL_RenderCopy(renderer, animationFrames2[i], NULL, &animationFrameRects2[i]);
animationTwoLoops--;
}
}
}
if(animationThreePlaying)
{
while(animationOneLoops != 0)
{
for(int i = 0; i < animationFrameRects3.size(); i++)
{
if(i != 0)
{
SDL_DestroyTexture(animationFrames3[i-1]);
}
SDL_RenderCopy(renderer, animationFrames3[i], NULL, &animationFrameRects3[i]);
animationThreeLoops--;
}
}
}
if(animationTwoPlaying)
{
}
if(animationThreePlaying)
{
}
for(int i = 0; i < 10; ++i)
{
SDL_RenderCopy(renderer, imageSlot[i], NULL, &imageRect[i]);
}
for(int i = 0; i < 10; ++i)
{
SDL_RenderCopy(renderer, textTexture[i], NULL, &textRect[i]);
}
for(int i = 0; i < 10; ++i)
{
if(mouseX > button[i].x && mouseX < button[i].x + button[i].w && mouseY > button[i].y && mouseY < button[i].y + button[i].h)
{
if(mouseDown)
{
switch(scene)
{
case 1:
switch(i)
{
case 0:
clearScene();
case 1:
if(night != 1)
{
clearScene();
}
break;
case 2:
quit();
break;
}
break;
}
}
}
}
SDL_RenderPresent(renderer);
}
int main()
{
srand(time(nullptr));
declareAnimationRects();
int windowReturn = createWindow();
switch(windowReturn)
{
case SDL_INITIALIZATION_ERROR:
std::cout << "Error initializing SDL. The program will be terminated. " << SDL_GetError() << std::endl;
quit();
break;
case IMG_INITIALIZATION_ERROR:
std::cout << "Error initializing SDL image. The program will be terminated. " << IMG_GetError() << std::endl;
quit();
break;
case TTF_INITIALIZATION_ERROR:
std::cout << "Error initializing TTF. The program will be terminated. " << TTF_GetError() << std::endl;
quit();
break;
case SAVEDATA_LOADING_ERROR:
std::cout << "Error opening savedata file. The program will be terminated." << std::endl;
quit();
break;
case WINDOW_CREATION_ERROR:
std::cout << "Error creating SDL window. The program will be terminated. " << SDL_GetError() << std::endl;
quit();
break;
case RENDERER_CREATION_ERROR:
std::cout << "Error creating SDL renderer. The program will be terminated. " << SDL_GetError() << std::endl;
quit();
break;
}
Uint32 lastTime = SDL_GetTicks();
Uint32 elapsedTime = 0;
Uint32 elapsedMilliseconds = 0;
while(true)
{
if(elapsedMilliseconds > 1000)
{
averageFPS = elapsedFrames / (elapsedMilliseconds/1000);
}
Uint32 currentTime = SDL_GetTicks();
elapsedTime = currentTime - lastTime;
lastTime = currentTime;
elapsedMilliseconds += elapsedTime;
getInput();
callEvents();
refreshScreen();
elapsedFrames++;
if(printElapsedMilliseconds)
{
std::cout << elapsedMilliseconds << std::endl;
}
SDL_GetMouseState(&mouseX, &mouseY);
if(printMousePos)
{
std::cout << "The mouse X position is: " << mouseX << " and the mouse Y position is: " << mouseY << std::endl;
}
if(printFrameRate)
{
std::cout << "The frame rate is:" << averageFPS << std::endl;
}
if(elapsedMilliseconds > 1000)
{
randomNumber = rand() % 1200 + 1;
if(printRandomNumber)
{
std::cout << "The random number this second is: " << randomNumber << "." << std::endl;
}
}
}
}
…through terminal it gives me a segmentation fault and then after using GDB to run it, it says “Bad file descriptor”.
Specifically with the std::getline function:
Thread 1 "Five Nights At " received signal SIGSEGV, Segmentation fault.
std::getline<char, std::char_traits<char>, std::allocator<char> > (__in=..., __str="", __delim=10 'n') at ../../../../../src/libstdc++-v3/src/c++98/istream-string.cc:141
141 ../../../../../src/libstdc++-v3/src/c++98/istream-string.cc: Bad file descriptor.
New contributor
ThatGuyWithSpaghettiCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
9