0) Don't include source files from headers!!! The way to get the SDL_Engine.cpp code to compile is to compile it explicitly, and then *link* that code with the main code.
1) With proper design, you won't need to worry about the order of include files. One aspect of this is that your headers shouldn't have anything "concrete" in them, such as global variables, and ideally not function implementations. For globals, you want to declare them, as 'extern', in the header, and define them in exactly one (usually, the corresponding one) .cpp file. But we won't need to do that here, for reasons explained further below.
2) Proper design involves avoiding these massive "just include everything to make sure I have everything" include files. It only ultimately bites you in the butt. Actually, in general, don't include things until you know you need them.
3) There's no reason for the SDL_event in main() to be a global variable; there's only one function hanging around that could possibly use it.
4) Your code is fine for instantiating the SDL_Engine; don't dynamically allocate when you don't need to.
5) Don't write 'init' functions; use constructors. That's what they're there for.
6) As it stands, if the SDL_Flip fails, you won't get to free the surface. The surface in question should be the responsibility of the SDL_Engine, though, because that's who inits it. Thus, use the destructor of that class to make the SDL_FreeSurface call. Since that destructor will always be called, there is no problem.
7) Since it's the engine's responsibility to track the surface, it should be the engine's responsibility to flip it, too. You can indicate failure by throwing an exception; since nothing catches it, this will terminate the program, but it will do it in a controlled, safe way. In fact, it ought to *hold* the surface, too.
8) Use a while loop to process events, because you can accumulate more than one event in the same game loop.
9) Don't be afraid to make helper functions.
10) There is no need to return explicitly at the end of main(). main() is a special case in C++.
11) Use forward slashes in paths to file names, even though DOS uses backslashes internally. C++ will translate them for you automatically, and it avoids having to double up the backslash characters to avoid problems with string escape characters.
//MAIN.CPP#include "SDL/SDL.h" // for the Event functionality#include "SDL_Engine.h"// Returns whether or not the game should keep running.bool handleEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT){ return false; } } return true;}int main(int args, char* argv[]) { // For flexibility, I pass the name of the background image as a parameter. SDL_Engine myEngine("background.jpg"); // See how neat this becomes now: while (handleEvents()) { myEngine.flip(); }}
//SDL_ENGINE.h#ifndef SDL_ENGINE_SDL#define SDL_ENGINE_SDL#include "SDL/SDL.h"#include "SDL/SDL_image.h"#include "SDL/SDL_ttf.h"class std::string; // a forward declaration.class SDL_Engine { // I'll explain these two lines later SDL_Engine& operator=(const SDL_Engine&); SDL_Engine(const SDL_Engine&); SDL_Surface* screen, background; public: SDL_Engine(const std::string& background_name); ~SDL_Engine(); void flip();};#endif
//SDL_ENGINE.cpp#include <string>#include <stdexcept>SDL_Engine::SDL_Engine(const std::string& background_name) { if (SDL_Init(SDL_INIT_EVERYTHING) == -1) { throw std::runtime_error("SDL Init failed."); } SDL_WM_SetCaption("Learning SDL", 0); screen = SDL_SetVideoMode(1440, 900, 0, SDL_RESIZABLE); if (!screen) { throw std::runtime_error("SDL Init failed."); } background = IMG_Load(background_name); SDL_BlitSurface(background, NULL, screen, NULL); SDL_Flip(screen);}~SDL_Engine() { if (screen) { SDL_FreeSurface(screen); } if (background) { SDL_FreeSurface(background); }}void flip() { if (SDL_Flip(screen) == -1) { throw std::runtime_error("SDL flip failed."); }}