I have recently started learning game programming in C. I am using a virtual studio code on linux Ubuntu, and image star.png is not displaying on the screen, there are no errors or problems reported by vs code. I have tried reinstalling sdl2-dev and sdl2-image-dev libraries. Maybe it is a problem with SDL, or maybe with my code (it was written in 2013).
The code should draw a white ractangl, which i can move around, on a blue screen and place a star in upper left corner of a window. It does everything except placing a star.
The code: (doesn't show "Cannot dinf star.png!" so I guess it is not that)
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
typedef struct
{
int x, y;
short life;
char *name;
}Man;
typedef struct
{
//players
Man man;
//image
SDL_Texture *star;
} GameState;
/////////////////////////////////////////////////////////////////////processEvents
int processEvents(SDL_Window *window , GameState *game)
{
SDL_Event event;
int done = 0;
//Check for events
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_WINDOWEVENT_CLOSE:
{
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
done = 1;
}
}
break;
case SDL_KEYDOWN:
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
done = 1;
break;
}
}
break;
case SDL_QUIT:
done = 1;
break;
}
}
const Uint8 *state = SDL_GetKeyboardState(NULL);
if(state[SDL_SCANCODE_LEFT])
{
game->man.x -= 1;
}
if(state[SDL_SCANCODE_RIGHT])
{
game->man.x += 1;
}
if(state[SDL_SCANCODE_UP])
{
game->man.y -= 1;
}
if(state[SDL_SCANCODE_DOWN])
{
game->man.y += 1;
}
SDL_Delay(10);
return done;
}
/////////////////////////////////////////////////////////////////////////////////////doRender
void doRedner(SDL_Renderer *renderer, GameState *game)
{
SDL_SetRenderDrawColor(renderer , 0, 0, 255, 255); //blue
//screen clean up into blue
SDL_RenderClear(renderer);
//set color
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_Rect rect = {game->man.x, game->man.y, 80, 80};
SDL_RenderFillRect(renderer, &rect);
//draw a star
SDL_Rect starRect = { 50, 50, 64, 64 };
SDL_RenderCopy(renderer, game->star, NULL, &starRect);
SDL_RenderPresent(renderer);
}
/////////////////////////////////////////////////////////////////////////////////////main funkction
int main(int argc, char *argv[])
{
GameState gameState;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Surface *starSurface = NULL;
SDL_Init(SDL_INIT_VIDEO);
gameState.man.x = 340-40;
gameState.man.y = 240-40;
window = SDL_CreateWindow("Game Widnow",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
//load image
starSurface = IMG_Load("star.png");
if(starSurface = NULL)
{
printf("Cannot find star.png!\n\n");
SDL_Quit();
return 1;
}
gameState.star = SDL_CreateTextureFromSurface(renderer, starSurface);
SDL_FreeSurface(starSurface);
int done = 0;
while(!done)
{
//check events
done = processEvents(window, &gameState);
//render
doRedner(renderer, &gameState);
}
SDL_Delay(1000);
//exit game and free memory
SDL_DestroyTexture(gameState.star);
//destroy and close window
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
TL;DR: Your intention is to perform a comparison, but you are using the assignment operator (i.e., =) instead of the comparison operator ==.
The conditional expression in your if statement:
if(starSurface = NULL)
{
...
}
does not check whether starSurface is NULL. The expression starSurface = NULL assigns NULL to starSurface and evaluates to NULL. Therefore, the condition evaluates to false and no error message is displayed.
Instead, you should write (note the double = below):
if (starSurface == NULL)
or just:
if (!starSurface)
Related
I have this code that is setting up a window, along with the close button functionality.
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
int initialize();
void handle_input();
typedef struct {
SDL_Renderer *renderer;
SDL_Window *window;
bool running;
int FPS;
int width;
int height;
bool close_requested;
} Game;
Game game = {
.running = true,
.FPS = 60,
.width = 600,
.height = 600,
.close_requested = false,
};
int main(int argc, char* argv[]) {
initialize();
handle_input();
while(game.running) { //Game loop
SDL_SetRenderDrawColor(game.renderer, 255, 0, 0, 255);
SDL_RenderPresent(game.renderer);
SDL_Delay(1000/game.FPS);
} //End of game loop
SDL_DestroyRenderer(game.renderer);
SDL_DestroyWindow(game.window);
SDL_Quit();
return 0;
}
int initialize() {
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) { //return 0 on success
printf("error initializing SDL: %s\n", SDL_GetError());
return 1;
}
SDL_Window* window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, game.width, game.height, 0); //creates window
if (!window) {
printf("error creating window: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; //creates a renderer
game.renderer = SDL_CreateRenderer(window, -1, render_flags);
if (!game.renderer) {
printf("error creating renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
}
void handle_input() {
SDL_Event event;
while (!game.close_requested) { //close button
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
game.close_requested = true;
game.running = false;
}
}
}
}
However, whenever I try to run this program, the window won't even open and I'm getting 0 errors in the console, besides a warning that states control may reach end of non-void function at the initialize() function. What does that warning mean? What is going on with my code? What did I do wrong?
I see 2 issues here:
you call handle_input() in your main before you enter the main loop and it gets stuck there until you exit, so SDL_RenderPresent() is never called.
the initialize function doesn't return anything in case of success, this is why you see the warning.
Try with the following changes, in main() move your input handling inside the loop:
int main(int argc, char* argv[]) {
initialize();
while(game.running && !game.close_requested) {
handle_input(); // <-- move here
SDL_SetRenderDrawColor(game.renderer, 255, 0, 0, 255);
SDL_RenderPresent(game.renderer);
SDL_Delay(1000/game.FPS);
}
// the rest...
}
In initialize() add a return 0; at the end.
In handle_input() remove the outer loop:
void handle_input() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
game.close_requested = true;
game.running = false;
}
}
}
I've been working on a game with SDL2 and C, and this is my code so far:
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#define BLOCK_SIZE 50
#define SPEED 5
int initialize();
void handle_input();
void draw_player();
typedef struct {
SDL_Renderer *renderer;
SDL_Window *window;
bool running;
int FPS;
int width;
int height;
bool close_requested;
int input[256];
} Game;
Game game = {
.running = true,
.FPS = 60,
.width = 600,
.height = 600,
.close_requested = false,
.input = {},
};
SDL_Rect player = {
.x = 300,
.y = 300,
.w = BLOCK_SIZE,
.h = BLOCK_SIZE
};
int main(int argc, char* argv[]) {
initialize();
while(game.running && !game.close_requested) { //Game loop
SDL_SetRenderDrawColor(game.renderer, 0, 0, 0, 255);
SDL_RenderClear(game.renderer);
handle_input();
draw_player();
SDL_RenderPresent(game.renderer);
SDL_Delay(1000/game.FPS);
} //End of game loop
SDL_DestroyRenderer(game.renderer);
SDL_DestroyWindow(game.window);
SDL_Quit();
return 0;
}
int initialize() {
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) { //return 0 on success
printf("error initializing SDL: %s\n", SDL_GetError());
return 1;
}
game.window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, game.width, game.height, 0); //creates window
if (!game.window) {
printf("error creating window: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; //creates a renderer
game.renderer = SDL_CreateRenderer(game.window, -1, render_flags);
if (!game.renderer) {
printf("error creating renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(game.window);
SDL_Quit();
return 1;
}
return 0;
}
void handle_input() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
game.close_requested = true;
game.running = false;
}
//printf("input: %p code: %i\n", game.input, event.key.keysym.scancode);
if (event.type == SDL_KEYDOWN) {
game.input[event.key.keysym.scancode] = true;
//printf("True");
}
if (event.type == SDL_KEYUP) {
game.input[event.key.keysym.scancode] = false;
//printf("False");
}
if (game.input[SDL_SCANCODE_UP]) {
player.y -= SPEED;
} else if (game.input[SDL_SCANCODE_DOWN]) {
player.y += SPEED;
} else if (game.input[SDL_SCANCODE_LEFT]) {
player.x -= SPEED;
} else if (game.input[SDL_SCANCODE_RIGHT]) {
player.x += SPEED;
}
}
}
void draw_player() {
SDL_SetRenderDrawColor(game.renderer, 0, 200, 50, 255);
SDL_RenderFillRect(game.renderer, &player);
}
I'm using an array called int input[] within the typedef struct, and within the handle_input() function, I'm using the array like this:
if (event.type == SDL_KEYDOWN) {
game.input[event.key.keysym.scancode] = true;
}
if (event.type == SDL_KEYUP) {
game.input[event.key.keysym.scancode] = false;
}
So that I can easily check if a key is pressed like this:
if (game.input[SDL_SCANCODE_UP]) {
//do something
}
However, when this code is run, the movement is broken up and choppy, and there is a slight delay when you press the key down. I've set the SDL_Delay to 60 FPS, so this shouldn't be an issue with that. The issue must be with the way I'm handling the inputs. Why isn't the input code firing at a consistent and fast rate?
Situation
I am working on an SDL2 program and I want to remove the black terminal window that shows up everytime I fire the program,
its kinda annoying to have a black window randomly in my screen :/
What I've Tried
I've tried looking up in Google but nothing actually shows up that can fix my situation
Here's The Rest Of My Code
#include <stdio.h>
#include <SDL.h>
int main(int argc, char **args) {
// SDL Window Declaration
SDL_Surface* screen;
SDL_Window* window;
SDL_Rect plrBox;
SDL_Rect plrMot;
plrMot.x = 1;
plrMot.y = 1;
plrBox.x = 0;
plrBox.y = 0;
plrBox.w = 10;
plrBox.h = 10;
// SDL Initialization
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
printf("Fail At SDL_Init()\n");
return 1;
}
// Window Creation
window = SDL_CreateWindow(
"Paint",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
400,
300,
SDL_WINDOW_SHOWN
);
if (!window) {
printf("Fail at SDL_CreateWindow\n");
}
// Surface Creation
screen = SDL_GetWindowSurface(window);
if (!screen) {
printf("Fail at Screen\n");
return 1;
}
int run = 1;
while (run) {
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
SDL_FillRect(screen, &plrBox, SDL_MapRGB(screen->format, 0, 0, 0));
plrBox.x += plrMot.x;
plrBox.y += plrMot.y;
if (plrBox.y > 300) {
plrMot.y = -plrMot.y;
}
if (plrBox.x > 400) {
plrMot.x = -plrMot.x;
}
if (plrBox.y < 0) {
plrMot.y = -plrMot.y;
}
if (plrBox.x < 0) {
plrMot.x = -plrMot.x;
}
SDL_Event events;
while (SDL_PollEvent(&events)){
switch (events.type) {
case SDL_QUIT:
run = 0;
}
}
SDL_UpdateWindowSurface(window);
}
// Quit
window = NULL;
screen = NULL;
SDL_Quit();
return 0;
}
I use mingw for all the comments out there
I'm working through Lazy Foo's SDL2 tutorials and stuck trying to render multiple viewports. The idea is to load a PNG as a texture, create SDL_Rect structs for 3 different viewports (top left, top right, bottom), then copy the texture onto each viewport, and finally render all 3 viewports. My code is only rendering the first viewport.
I've tried changing the order - in every case, whichever viewport is defined first is the only one that renders.
I also tried changing the viewport dimensions, in case overlap was the issue - same problem.
The only question I found about multiple viewports didn't point me in the right direction. But it did start me thinking - my code is written in C, the tutorial in C++. Although I think I'm translating everything correctly (the other lessons work fine), maybe I'm missing something obvious here?
I'm compiling with CFLAGS = -Wall -Wextra -pedantic -std=c99 - no warnings or errors.
Edit: I tried rendering filled rectangles instead of a loaded PNG, but the issue is the same - only the first one renders.
Here's my code:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
int init_renderer();
int load_media();
SDL_Texture *load_texture(char *);
void close_renderer();
SDL_Window *g_window = NULL;
SDL_Renderer *g_renderer = NULL;
SDL_Texture *g_texture = NULL;
int main()
{
if (init_renderer() != 1) {
return -1;
}
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) {
printf("Warning: Linear texture filtering not enabled!\n");
}
if (load_media() != 1) {
return -1;
}
int quit = 0;
SDL_Event e;
while (quit != 1) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT || e.key.keysym.sym == SDLK_q) {
quit = 1;
}
}
SDL_SetRenderDrawColor(g_renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(g_renderer);
SDL_Rect top_left_vp;
top_left_vp.x = 0;
top_left_vp.y = 0;
top_left_vp.w = SCREEN_WIDTH / 2;
top_left_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &top_left_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_Rect top_right_vp;
top_right_vp.x = SCREEN_WIDTH / 2;
top_right_vp.y = 0;
top_right_vp.w = SCREEN_WIDTH / 2;
top_right_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &top_right_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_Rect bottom_vp;
bottom_vp.x = 0;
bottom_vp.y = SCREEN_HEIGHT / 2;
bottom_vp.w = SCREEN_WIDTH;
bottom_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &bottom_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_RenderPresent(g_renderer);
}
close_renderer();
return 0;
}
int init_renderer()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Failed to initialize SDL. Error: %s\n", SDL_GetError());
return 0;
}
g_window = SDL_CreateWindow("SDL Tuts",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if (g_window == NULL) {
printf("Failed to create window. Error: %s\n", SDL_GetError());
return 0;
}
g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED);
if (g_renderer == NULL) {
printf("Failed to create renderer. Error: %s\n", SDL_GetError());
return 0;
}
SDL_SetRenderDrawColor(g_renderer, 0x29, 0xAB, 0x87, 0xFF);
int img_flags = IMG_INIT_PNG;
if (!(IMG_Init(img_flags) & img_flags)) {
printf("Failed to initialize SDL Image. SDL_Image Error: %s\n", IMG_GetError());
return 0;
}
return 1;
}
int load_media()
{
g_texture = load_texture("assets/texture.png");
if (g_texture == NULL) {
return 0;
}
return 1;
}
SDL_Texture *load_texture(char *path)
{
SDL_Texture *new_texture = NULL;
SDL_Surface *loaded_surface = IMG_Load(path);
if (loaded_surface == NULL) {
printf("Failed to load image. SDL_Image Error: %s\n", IMG_GetError());
} else {
new_texture = SDL_CreateTextureFromSurface(g_renderer, loaded_surface);
if (new_texture == NULL) {
printf("Failed to create texture from %s. Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(loaded_surface);
}
return new_texture;
}
void close_renderer()
{
SDL_DestroyTexture(g_texture);
g_texture = NULL;
SDL_DestroyRenderer(g_renderer);
SDL_DestroyWindow(g_window);
g_renderer = NULL;
g_window = NULL;
IMG_Quit();
SDL_Quit();
}
To check for more errors, you should see what the calls to SDL_RenderSetViewPort are returning. According to the docs, it returns an int, which is 0 on success or a negative int if there's an error. It's entirely possible that something deeper in SDL is having a fit.
Additional pro tips: you can define the SDL_Rect structs outside of your while loop to save a miniscule margin of processing power. And to spare yourself some typing, you can initialize a SDL_Rect using a list constructor instead of manually punching each property. E.G.:
SDL_Rect top_left_vp;
top_left_vp.x = 0;
top_left_vp.y = 0;
top_left_vp.w = SCREEN_WIDTH / 2;
top_left_vp.h = SCREEN_HEIGHT / 2;
is more simply
SDL_Rect top_left_vp = {
0,
0,
SCREEN_WIDTH / 2,
SCREEN_HEIGHT / 2
};
I am looking through the code and i cant find solution for the problem of invalid renderer. I am beginner with SDL2 and i have to write code in pure C.
I think that in my code there is more errors but because of this one i cant go further. Code is half in polish language so if u cant get what is where i can rewrite this a bit . Problem occure when in main i try to load function"Odczyt_z_Pliku". Probably somewhere there is a problem.
SDL_GetError() says" invalid renderer.
#include<SDL.h>
#include<stdio.h>
#include<SDL_image.h>
#pragma warning(disable : 4996)
#define WYSOKOSC_EKRANU 768
#define SZEROKOSC_EKRANU 1024
typedef enum bool{
false,true
}bool;
typedef struct sTekstura {
int wysokosc;
int szerokosc;
SDL_Texture *Tekstura;
}sTekstura;
void IniTekstury(sTekstura T)
{
T.wysokosc = 0;
T.szerokosc = 0;
T.Tekstura = NULL;
}
void free(sTekstura T)
{
//Free texture if it exists
if (T.Tekstura != NULL)
{
SDL_DestroyTexture(T.Tekstura);
T.Tekstura = NULL;
T.szerokosc = 0;
T.wysokosc = 0;
}
}
int Odczyt_z_Pliku(char nazwa[50],sTekstura T,SDL_Renderer* Renderer)
{
free(T);
SDL_Texture* nTekstura = NULL;
//Load image at specified path
SDL_Surface* Powierzchnia = IMG_Load(nazwa);
if (Powierzchnia == NULL)
{
printf("Unable to load image %s! SDL_image Error: %s\n", nazwa, IMG_GetError());
}
else
{
SDL_SetColorKey(Powierzchnia, SDL_TRUE, SDL_MapRGB(Powierzchnia->format, 0xFF, 0xFF, 0xFF));
//Create texture from surface pixels
nTekstura = SDL_CreateTextureFromSurface(Renderer, Powierzchnia);
if (nTekstura == NULL)
{
printf("Unable to create texture from %s! SDL Error: %s\n", nazwa, SDL_GetError());
}
else
{
//Get image dimensions
T.szerokosc = Powierzchnia->w;
T.wysokosc = Powierzchnia->h;
}
//Get rid of old loaded surface
SDL_FreeSurface(Powierzchnia);
}
//Return success
T.Tekstura = nTekstura;
if (T.Tekstura != NULL)
{
return 1;
}
else
{
return 0;
}
}
bool Inicjalizacja(SDL_Window *Okno,SDL_Renderer *Renderer)
{
//Initialization flag
bool success = true;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
//Create window
Okno = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SZEROKOSC_EKRANU, WYSOKOSC_EKRANU, SDL_WINDOW_SHOWN);
if (Okno == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create renderer for window
Renderer = SDL_CreateRenderer(Okno, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (Renderer == NULL)
{
printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Initialize renderer color
SDL_SetRenderDrawColor(Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
success = false;
}
}
}
}
return success;
}
void setBlendMode(sTekstura T, SDL_BlendMode blending) //MK: Funkcja ustawiająca przezroczystosc
{
//Set blending function
SDL_SetTextureBlendMode(T.Tekstura, blending);
}
void setAlpha(sTekstura T,Uint8 alpha) //MK: Funkcja ustawiająca przezroczystość
{
//Modulate texture alpha
SDL_SetTextureAlphaMod(T.Tekstura, alpha);
}
void render(int x, int y,sTekstura T,SDL_Renderer *Renderer)
{
//Set rendering space and render to screen
SDL_Rect renderQuad = { x, y, T.szerokosc, T.wysokosc };
SDL_RenderCopy(Renderer, T.Tekstura, NULL, &renderQuad);
}
int main(int argc, char *argv[])
{
SDL_Window * Okno = NULL;
SDL_Renderer* Renderer = NULL;
sTekstura TloMenu;
TloMenu.szerokosc = 0;
TloMenu.wysokosc = 0;
TloMenu.Tekstura = NULL;
sTekstura TloGra;
TloGra.szerokosc = 0;
TloGra.wysokosc = 0;
TloGra.Tekstura = NULL;
sTekstura Pudlo;
Pudlo.szerokosc = 0;
Pudlo.wysokosc = 0;
Pudlo.Tekstura = NULL;
sTekstura Sciana;
Sciana.szerokosc = 0;
Sciana.wysokosc = 0;
Sciana.Tekstura = NULL;
sTekstura StartGry;
StartGry.szerokosc = 0;
StartGry.wysokosc = 0;
StartGry.Tekstura = NULL;
sTekstura KoniecGry;
KoniecGry.szerokosc = 0;
KoniecGry.wysokosc = 0;
KoniecGry.Tekstura = NULL;
SDL_Event e;
//Start up SDL and create window
if (!Inicjalizacja(Okno,Renderer))
{
printf("Failed to initialize!\n");
}
else
{
if(!Odczyt_z_Pliku("MENU BOMBERMAN.png", Sciana, Renderer))
{
puts("Nie wczytano kostki");
return 0;
}
if (!Odczyt_z_Pliku("pudlo3.bmp", Pudlo, Renderer))
{
puts("Nie wczytano pudla");
return 0;
}
if (!Odczyt_z_Pliku("MenuBomberman.bmp", TloMenu, Renderer))
{
puts("Nie wczytano menu");
return 0;
}
if (!Odczyt_z_Pliku("Mapa.bmp", TloGra, Renderer))
{
puts("Nie wczytano mapy");
return 0;
}
if (!Odczyt_z_Pliku("NEW GAME.bmp", StartGry, Renderer))
{
puts("Nie wczytano napisu nowej gry");
return 0;
}
else
{
//Set standard alpha blending
setBlendMode(StartGry, SDL_BLENDMODE_BLEND);
}
if (!Odczyt_z_Pliku("exitgimp.bmp", KoniecGry, Renderer))
{
puts("Nie wczytano napisu koniec gry");
return 0;
}
else
{
//Set standard alpha blending
setBlendMode(StartGry, SDL_BLENDMODE_BLEND);
}
//Main loop flag
bool quit = false;
//Modulation component
Uint8 AlphaStartu = 255;
Uint8 AlphaKonca = 127;
//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
//Handle key presses
else if (e.type == SDL_KEYDOWN)
{
//Increase alpha on w
if (e.key.keysym.sym == SDLK_w)
{
AlphaKonca = 127;
AlphaStartu = 255;
}
//Decrease alpha on s
else if (e.key.keysym.sym == SDLK_s)
{
AlphaKonca = 256;
AlphaStartu = 127;
}
}
}
//Clear screen
SDL_SetRenderDrawColor(Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(Renderer);
//Render background
render(0, 0, TloMenu, Renderer);
//Render front blended
setAlpha(KoniecGry,AlphaKonca);
setAlpha(StartGry, AlphaStartu);
render(0, 0,StartGry,Renderer);
render(0, 0,KoniecGry,Renderer);
//Update screen
SDL_RenderPresent(Renderer);
}
}
//Free resources and close SDL
close();
return 0;
}
When you get to Odczyt_z_Pliku, Renderer is still a NULL pointer.
As it stands, in your main() function you have a variable Renderer of type SDL_Renderer* (initialized to NULL). You then pass that value NULL into SDL_Renderer* which also takes an argument of type SDL_Renderer*.
However, in C this is just a pass by copy of the value of the pointer itself (not the value pointed to by the pointer). In other words, the argument Renderer to your function just creates a local variable in that function. So in Odczyt_z_Pliku when you do Renderer = SDL_CreateRenderer(...); that may return a new pointer but it's only assigning it to the local variable Renderer, but this has no effect on the Renderer variable in your main() function.
In C, the way to write a function that sets the value of a pointer that is a local variable in the calling function is to use a double pointer. That is, change the signature of Inicjalizacja to
bool Inicjalizacja(SDL_Window **Okno, SDL_Renderer **Renderer)
then in main() (or wherever else) call it like:
SDL_Window * Okno = NULL;
SDL_Renderer* Renderer = NULL;
...
if (!Inicjalizacja(&Okno, &Renderer)) {
...
}
and so on. (Note: You made the same mistake with the SDL_Window Okno as well, and possibly elsewhere--I haven't read the full code).
The syntax &Okno means pass the address of (i.e. a pointer to) the variable Okno. Since Okno is itself a pointer, the address of the pointer is a double pointer.
Then in Inicjalizacja write:
*Renderer = SDL_CreateRenderer(...);
and similarly with Okno. The *Renderer syntax (which I find somewhat confusing) means the value pointed to by a pointer. Since Renderer here is a double pointer, this means assign the single pointer (of type Renderer*) into the pointer pointed to by Renderer. Now the Renderer* pointer in your main() function will be properly initialized.
Note, similarly you should change the following check to:
if (*Renderer == NULL) {...}
and so on. We know Renderer != NULL since it's a pointer to a local variable allocated in our main() function. The interesting question is what value SDL_CreateRenderer returned, so we want to look at *Renderer.