I am having weird behavior in my SDL application. I am making a game engine and I have a project to test it, and am dynamically linking the test project to the engine. The problem is that the program seems to run fine sometimes and bad other times. If it doesn't work, it'll do everything fine until it closes the window, where it'll close the window and the pause for a few seconds before saying that it terminated with status -1073741819. Here's my code:
Engine, Screen.hpp
#ifndef SCREEN_HPP_INCLUDED
#define SCREEN_HPP_INCLUDED
#include <string>
#include "SDL.h"
namespace myeng
{
class Screen final //This class doesn't need to be derived from
{
public:
//Constructor and destructor
Screen(int height, int width, std::string caption);
~Screen();
//Functions to get the width, height, and depth of the screen
int getScreen_Width();
int getScreen_Height();
int getScreen_Depth();
//Function to get screen_ptr
SDL_Surface* getScreen_Ptr();
//Function to flip the screen
int Screen_Flip();
//Function to put something on the screen
int Screen_Put(int x, int y, SDL_Surface* source);
//Functions for backgrounds
int Screen_RepBack(int height, int width, SDL_Surface* source);
private:
//Constants
const int SCREEN_WIDTH = 0;
const int SCREEN_HEIGHT = 0;
const int SCREEN_DEPTH = 0;
//Other variables
std::string screen_name;
//Surfaces
SDL_Surface* screen_ptr = nullptr; //Creates the main surface for the screen
};
}
#endif // SCREEN_HPP_INCLUDED
Screen.cpp
#include <iostream>
#include "Screen.hpp"
//Cosntructor and destructor
myeng::Screen::Screen(int height, int width, std::string caption)
{
const_cast<int&> (SCREEN_WIDTH) = width;
const_cast<int&> (SCREEN_HEIGHT) = height;
const_cast<int&> (SCREEN_DEPTH) = 32;
screen_ptr = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, SDL_SWSURFACE);
screen_name = caption;
}
myeng::Screen::~Screen()
{
SDL_FreeSurface(screen_ptr);
}
//Functions to get width, height, and depth of the screen
int myeng::Screen::getScreen_Width()
{
return SCREEN_WIDTH;
}
int myeng::Screen::getScreen_Height()
{
return SCREEN_HEIGHT;
}
int myeng::Screen::getScreen_Depth()
{
return SCREEN_DEPTH;
}
//Function to get screen_ptr
SDL_Surface* myeng::Screen::getScreen_Ptr()
{
return screen_ptr;
}
//Function to flip the screen
int myeng::Screen::Screen_Flip()
{
if(SDL_Flip(screen_ptr) != 0)
{
std::cerr << "Failed to flip screen. Error" << SDL_GetError() << "\n";
return 1;
}
else
{
return 0;
}
}
//Function to put something on the Screen
int myeng::Screen::Screen_Put(int x, int y, SDL_Surface* source)
{
//Create a rectangle to store the offsets of the source
SDL_Rect offset;
//Set the offsets
offset.x = x;
offset.y = y;
//Apply the source to the screen
if(SDL_BlitSurface(source, nullptr, screen_ptr, &offset) != 0)
{
std::cerr << "Failed to blit the surface. Error " << SDL_GetError();
return 1;
}
else
{
return 0;
}
}
//Functions for backgrounds
int myeng::Screen::Screen_RepBack(int height, int width, SDL_Surface* source)
{
int columns = SCREEN_HEIGHT / height;
int rows = SCREEN_WIDTH / width;
if((SCREEN_HEIGHT % height != 0) || (SCREEN_WIDTH % width != 0))
{
std::cerr << "Background cannot be repeated over the screen \n";
return 1;
}
else
{
for(int i = 0; i < columns; i++)
{
for(int j = 0; j < rows; j++)
{
Screen_Put(j*width, i*height, source);
}
}
}
return 0;
}
Test Project, main.cpp
#include <iostream>
#include "SDL_Image.h"
#include "Screen.hpp"
SDL_Surface* load_image(std::string filename, bool maketransparent = false)
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load( filename.c_str() );
//If the image loaded
if( loadedImage != NULL )
{
//Log the image loading
std::cout << "Successfully loaded: " << filename << "\n";
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
//If the image was optimized just fine and the user specifies transparency
if( optimizedImage != NULL && maketransparent == true )
{
//Log the optimization
std::cout << "Generated optimized image for: " << filename << "\n";
//Map the color key
Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0xED, 0x0B, 0xB5 );
//Set all pixels of color R 0xED, G 0x0B, B 0xB5 to be transparent
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
//Log the image transparency
std::cout << "Color-keyed: " << filename << "\n";
}
else
{
//Log the generated image
std::cout << "Generated optimized image for: " << filename << ", no color key\n";
}
}
else
{
std::cerr << "Failed to load: " << filename;
}
//Return the optimized image
return optimizedImage;
}
int main ( int argc, char* argv[] )
{
SDL_Surface* background = nullptr;
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
std::cerr << "Failed to inialize SDL. Error: " << SDL_GetError() << "\n";
return 1;
}
myeng::Screen main_screen(600, 600, "Test");
SDL_WM_SetCaption("Test", "Test");
background = load_image("Background.png");
main_screen.Screen_RepBack(200, 200, background);
if(main_screen.Screen_Flip() != 0)
{
std::cerr << "Error flipping screen at line " << __LINE__ << "\n";
}
std::cout << main_screen.getScreen_Width() << "\n";
std::cout << main_screen.getScreen_Height() << "\n";
std::cout << main_screen.getScreen_Depth() << "\n";
SDL_Delay(1000);
SDL_FreeSurface(background);
SDL_Quit();
return 0;
}