Search code examples
csdl-2dry

How to make DRY code from these duplicates in C


I'm trying to avoid duplicate code by writing a function that I will call. I use SDL2 library, and call function to render pictures on the screen, it looks like this

SDL_Surface* surface = NULL;

surface = IMG_Load("./images/star.png");
if (surface == NULL)
{
    printf("Cannot find star.png \n\n");
    SDL_Quit();
    exit(1);
}
game->star = SDL_CreateTextureFromSurface(game->renderer, surface);
SDL_FreeSurface(surface);
    surface = IMG_Load("./images/clouds.png");
if (surface == NULL)
{
    printf("Cannot find clouds.png \n\n");
    SDL_Quit();
    exit(1);
}
game->clouds = SDL_CreateTextureFromSurface(game->renderer, surface);
SDL_FreeSurface(surface);
    surface = IMG_Load("./images/bridge.png");
if (surface == NULL)
{
    printf("Cannot find bridge.png \n\n");
    SDL_Quit();
    exit(1);
}
game->bridge = SDL_CreateTextureFromSurface(game->renderer, surface);
SDL_FreeSurface(surface);

I understand that I can remake this lines of code into a function that I'll just call, I tried to make it this way

void loadImg(GameState* game, char fileName[]) 
{
    SDL_Surface* surface = NULL;

    surface = IMG_Load(fileName);
    if (surface == NULL)
    {
        printf("Cannot find %s.png \n\n", fileName);
        SDL_Quit();
        exit(1);
    }
    game = SDL_CreateTextureFromSurface(game->renderer, surface); /*I have error here*/
    SDL_FreeSurface(surface);
}

and call this way, and have an error

loadImg(game->star, "./images/star.png");
> Exception thrown: read access violation.
game was 

Struct of GameState

typedef struct
{
    Man man;
    Star stars[100];
    Ledge ledges[100];
    SDL_Texture *clouds;
    SDL_Texture *star;
    SDL_Texture *manFrames[7];
    SDL_Texture *bridge;
    SDL_Renderer *renderer;
} GameState;

Solution

  • This

    void loadImg(GameState* game, char fileName[]) 
    

    expects a pointer to GameState as the first parameter

    This

    loadImg(game->star, "./images/star.png");
    

    is passing an SDL_texture as the first parameter

    so try this:

    void loadImg(GameState *game,SDL_texture** texture, char fileName[])
    

    You will need to re-write to use the texture parameter

    void loadImg(GameState *game, SDL_texture** texture, char fileName[])
    {
        SDL_Surface* surface = NULL;
    
        surface = IMG_Load(fileName);
        if (surface == NULL)
        {
            printf("Cannot find %s.png \n\n", fileName);
            SDL_Quit();
            exit(1);
        }
        *texture = SDL_CreateTextureFromSurface(game->renderer, surface); 
        SDL_FreeSurface(surface);
    }
    

    Then your call would be

    loadImg(game, &game->star, "./images/star.png");
    

    Note: you get this error because when you de-reference a texture as a pointer to a GameState struct you reference a random location in memory (which you don't have rights to access)