Issue with the SDL IMG_Load() function

Hello!
First of all, thanks to everyone who's reading my post and wants to help.
As the title says, I have a problem with the SDL IMG_Load() function.

In my code, I'm using the GetOpenFileName() function to get the absolute path of a file that is containing the path of an image that I will apply to a SDL_Surface with the IMG_Load() function. But it fails and I don't know why...

I tried to load the image directly by giving the relative (and absolute) path of the image and it works fine.

I also tried to directly open a file by giving the path of the file, get the path of the image and apply it to the SDL_Surface and it works fine too.

It only fails when I get the file path with the GetOpenFileName() function...

Here is the different functions I use to try to load the image :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

bool CApp::OpenF(){
    FILE* FileHandle;
    char* FileName;

    //Useful stuff to correctly load the GetOpenFileName() function
    OPENFILENAME ofn;
    char szFile[260];
    HWND hwnd = NULL;
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFile = szFile;
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    if(!GetOpenFileName( &ofn )){ //Check if there is no error while getting the file
        return false;
    }
    FileName = ofn.lpstrFile;
    MessageBox ( NULL , FileName , "File Name" , MB_OK); //check if the filename is correct
	
    if(CArea::AreaControl.OnLoad(FileName) == false) { //Give the file name to try to open it then load the image
        return false;
    }
    return true;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
bool CArea::OnLoad(char* File) {
    char TilesetFile[260];
    char MapFile[255];
    char DecorFile[255];
    FILE* FileHandle = fopen(File, "r"); //open the file
    if(FileHandle == NULL) {
        return false;
    }
    fscanf(FileHandle, "%s\n", TilesetFile); //Image file path

    if((Surf_Tileset = CSurface::OnLoad(TilesetFile))==NULL){//Try to load the image to a SDL Surface
        return false; //Fails here
    }
    //Not important stuff concerning my problem
    fscanf(FileHandle, "%dx%d,%d\n", &Map_Rows, &Map_Cols,&Tile_Size);
    CTilePicker::CTilePickerControl.OnLoad(Surf_Tileset,Tile_Size);
    fscanf(FileHandle, "%s ", MapFile);
    fscanf(FileHandle, "%s\n", DecorFile);
    fclose(FileHandle);
    FILE* MapFileHandle = fopen(MapFile, "r");
    FILE* DecorFileHandle = fopen(DecorFile, "r");
    if(MapFileHandle == NULL || DecorFileHandle == NULL) {
        return false;
    }
    for(int X = 0;X < Map_Rows;X++) {
        for(int Y = 0;Y < Map_Cols;Y++) {
            fscanf(MapFileHandle, "%d:%d ", &Map_Tiles_ID[X][Y], &Map_Tiles_Type[X][Y]);
            fscanf(DecorFileHandle, "%d:%d ", &Decor_Tiles_ID[X][Y], &Decor_Tiles_Type[X][Y]);
        }
        fscanf(MapFileHandle, "\n");
        fscanf(DecorFileHandle, "\n");
    }
    fclose(MapFileHandle);
    fclose(DecorFileHandle);
    return true;
}


1
2
3
4
5
6
7
8
9
10
11
12
SDL_Surface* CSurface::OnLoad(char* File) {
    SDL_Surface* Surf_Temp = NULL;
    SDL_Surface* Surf_Return = NULL;
    
    if((Surf_Temp = IMG_Load(File)) == NULL) { //Fails here
        return NULL;
    }
    Surf_Return = SDL_DisplayFormatAlpha(Surf_Temp);
    SDL_FreeSurface(Surf_Temp);

    return Surf_Return;
}


If you need some more details, just ask.

Thank you again!

Last edited on
After you have called fscanf, are you sure that TilesetFile contains the path correctly? Maybe you should print TilesetFile to see if it's correct. You could also print SDL_GetError() after IMG_Load has failed to see what error message SDL is giving.
I already did several tests to know what was containing TilesetFile and the path is correct, it's the one that I give in the file. And when I don't use the GetOpenFileName function to get the file name it works correctly...

SDL_GetError() tells me that it couldn't open the file.

So I took a second to think about that and as TilesetFile path was relative to my .exe file I tried to give the absolute path.
It was still not working because there were some spaces in the path so fscanf returned me only the first part of the line.
I could use fgets but I wanted to try to give the relative path of the TilesetFile but, this time, relative to the location of the file that I open to get the path. And guess what? It's working now!
So apparently, as I am opening a file with the absolute path that I got with GetOpenFileName I have to give to IMG_Load the path relative to the file location, not relative to the .exe file.

I hope you understood what I said ^^

Thank you Peter for your help!
Last edited on
Ah so GetOpenFileName changes the working directory of the program.
So, I checked and by default it does change the working directory. But you can add the flag OFN_NOCHANGEDIR to avoid that.
Good to know :)

But I am going to change the fscanf function to fgets and always write absolute path with the flag OFN_NOCHANGEDIR, maybe it will be easier to manage everything.
Last edited on
Topic archived. No new replies allowed.