0

I have built a space invaders clone using SDL and compiled with MSVC11. The code loads 4 separate PNG files and a TTF font for use in rendering. The program works perfectly fine when given an absolute file path eg "C:/spaceinvader.png".

I tried changing this to a relative file path, ie "./res/spaceinvader.png

The program is then compiled it in release mode, and placed it in a folder of its own.

Directory structure:

game\game.exe
game\(all the required SDL dlls)
game\res\image1.png (and the other 3 images)
game\res\font.ttf

The oddest thing happens when you try to run the game. The first time you attempt to run this, the program console loads up, the SDL window opens, and then it crashes to the desktop. (I have ensured there are no premature return codes in main()). All subsequent times however, the program loads and works, although one of the sprites does not display on the screen. The only error appearing in the console relates to two of the PNG files having an incorrect sRGB profile.

If the entire folder is moved to a different location the program doesn't load again the first time, but then loads subsequently

So my question is

1) why does the program not load the first time, but subsequently? 2) why is there a failure of just one sprite to display, when the files are all identical (created in photoshop) and the code to load them is identical?

(apologies for not including any code here as I didn't feel that this was a coding issue - happy to paste specific code segments on request)

Thanks! K

EDIT:

Image loading code (loadTexture function cribbed from here:

SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren)
{
SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
    log_CheckSDLPointer(std::cout, texture, "LoadTexture");

return texture;
}

int Gamestate::initialiseSprites(SDL_Renderer *Renderer)
{

enemytexture = loadTexture("./res/invader.png", Renderer);
    if (enemytexture == nullptr) {return 1;}

playertexture = loadTexture("./res/player.png", Renderer);
    if (playertexture == nullptr) {return 1;}

missiletexture = loadTexture("./res/bullet.png", Renderer);
    if (missiletexture == nullptr) {return 1;}

background = loadTexture("./res/background.png", Renderer);
   if (background == nullptr) {return 1;}

return 0;
}

This function is called in main:

if (Active_Gamestate.initialiseSprites(mainRenderer) != 0)
{
    return 1;  //quit game if sprites could not be initialised
}
K K
  • 75
  • 2
  • 10
  • 1
    The first thing you should do is to make sure you have proper error handling for all function calls that can fail. When you have that, and they e.g. print out a message to standard out then try to run from a command line, and see what errors you get. If that doesn't help, replicate the directory structure in the debug folder, and run in a debugger to catch crashes. If *that* doesn't help, you are most likely using uninitialized variables (probably pointers) and need to review your code to find those places. – Some programmer dude Feb 13 '14 at 10:07
  • 3
    It's possible your "crash on first run, works on subsequent runs" behaviour is an indication that Windows' Fault Tolerant Heap is taking action and applying a shim (which would explain why it crashes again if you move the exe) - see: http://stackoverflow.com/questions/1041550/what-is-windows-7s-fault-tolerant-heap - basically you've got a nasty bug somewhere, but Windows is automagically patching it away for you. If this is the case, to fix it you'll need to hunt down the FTH registry key (search for your exe name in the reg) and delete it, then step through with a debugger. – benjymous Feb 13 '14 at 10:09
  • You'll also see something like this in the Output window if you're launching via VS: FTH: (9556): *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *** – benjymous Feb 13 '14 at 10:11
  • Thanks! I have added the code for image loading. All SDL functions called will output to std::cout if they fail. The compiler does not come up with any errors or warnings when run in the IDE debugger, and this behaviour only occurs when running the standalone exe. – K K Feb 13 '14 at 10:29
  • @KK The FTH message isn't a compile error - it'll appear in the Output window in VS when you run your app. It's worth checking for registry keys, just to be certain. – benjymous Feb 13 '14 at 10:46
  • Thanks. I can't find the FTH message anywhere... I deleted all the registry keys associated with my application and output is as follows: `1>------ Build started: Project: SpaceInvaders, Configuration: Release Win32 ------` `1> SpaceInvaders_SDL.cpp` `1> Generating code` `1> Finished generating code` `1> SpaceInvaders.vcxproj -> D:\Visual Studio Projects\SpaceInvaders_SDL\Release\SpaceInvaders.exe` `========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========` – K K Feb 13 '14 at 10:54
  • 1
    @KK, That's still the build output - You want to run the app in the debugger, then in the Output pane, make sure it's showing "Show output from: Debug" - you should see lots of messages about dlls and symbols being loaded - that's the place the FTH message will appear, if there is one. – benjymous Feb 13 '14 at 11:08

1 Answers1

0

Thanks for all the help. I think I've worked out what's going on. If the image loading code is changed to the following:

char executablePath[FILENAME_MAX];

std::stringstream invaderpathstream;
invaderpathstream << executablePath << "/res/invader.png";
std::string invaderpath = invaderpathstream.str();

enemytexture = loadTexture(invaderpath, Renderer);
if (enemytexture == nullptr) 
     {return 1;}

The issue disappears. Perhaps the problem is with relative paths (on my system at least), and maybe after the first run of the program, the OS somehow locates the files needed and that's why it runs without a hitch on subsequent runs?

K

K K
  • 75
  • 2
  • 10