I've written small sdl application. Problem is that is crashes almost everything when I launch it. Every window loses title bar. Application sometimes pops up, sometimes doesn't. If it does, pressing q (key for quitting) closes it but other windows remains 'broken'. Only way to get rid of this is to logout and then log in again.
Here's code:
#include <bits/stdc++.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
const int screen_x = 800;
const int screen_y = 600;
SDL_Window* window = nullptr;
SDL_Texture* textures[3];
SDL_Texture* currentTexture = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;
bool running = true;
SDL_Texture* loadTexture(const char* path)
{
SDL_Texture* texture = nullptr;
SDL_Surface* load = IMG_Load(path);
if (!load)
{
printf("Failed to load image %s. Error: %s\n", path, IMG_GetError());
}
else
{
texture = SDL_CreateTextureFromSurface(renderer, load);
if (!texture)
{
printf("Failed to convert surface from %s. Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(load);
}
return texture;
}
bool loadMedia()
{
bool success = true;
currentTexture = textures[0] = loadTexture("./img/1.png");
if (!textures[0])
{
printf("Failed to load texture\n");
success = false;
}
textures[1] = loadTexture("./img/2.png");
if (!textures[1])
{
printf("Failed to load texture\n");
success = false;
}
textures[2] = loadTexture("./img/3.png");
if (!textures[2])
{
printf("Failed to load texture\n");
success = false;
}
return success;
}
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
window = SDL_CreateWindow("SDL with linux", 0, 0, screen_x, screen_y, SDL_WINDOW_SHOWN);
if (!window)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if ((IMG_Init(imgFlags) & imgFlags) != imgFlags)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
}
}
}
return true;
}
void close()
{
for (unsigned i = 0; i < 3; i++)
{
SDL_DestroyTexture(textures[i]);
textures[i] = nullptr;
}
SDL_DestroyRenderer(renderer);
renderer = nullptr;
SDL_DestroyWindow(window);
window = nullptr;
IMG_Quit();
SDL_Quit();
}
int main(int argc, char** argv)
{
if (!init())
{
printf("Initialization error\n");
}
else
{
if (!loadMedia())
{
printf("Media loading error\n");
}
else
{
while (running)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_q:
running = false;
break;
case SDLK_1:
currentTexture = textures[0];
break;
case SDLK_2:
currentTexture = textures[1];
break;
case SDLK_3:
currentTexture = textures[2];
break;
}
break;
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, currentTexture, nullptr, nullptr);
SDL_RenderPresent(renderer);
SDL_Delay(80);
}
}
}
close();
return 0;
}
Makefile:
CC = g++
CFlags = -Wall -std=c++11
Input = main.cpp
Output = -o ./bin/prog
Linker = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
all:
$(CC) $(Input) $(CFlags) $(Linker) $(Output)
Screenshot showing behavior of application
Im sorry this is going to be more like a comment but i dont have 50 reputation to comment in questions . Can you provide a screenshot of the window?
If not then try using SDL_WINDOWPOS_CENTERED at the x and y axis then see if the window is showing up. Please share if this worked
Related
I'm currently trying to set up a few C++ libraries for a future project. Namely, SDL2.
Here's my code:
#include <iostream>
#include <fstream>
#include <SDL.h>
int SCREEN_WIDTH = 457;
int SCREEN_HEIGHT = 497;
const char* imgpath = "Sprite.bmp";
std::string errmsg;
SDL_Window* window = NULL;
SDL_Surface* screensurface = NULL;
SDL_Surface* image = NULL;
SDL_Rect rect;
struct {
bool wdown;
bool adown;
bool sdown;
bool ddown;
bool edown;
bool escdown;
} kpresses;
void clearkpresses() {
kpresses.wdown = false;
kpresses.adown = false;
kpresses.sdown = false;
kpresses.ddown = false;
kpresses.edown = false;
kpresses.escdown = false;
}
void setrect() {
rect.x = 0;
rect.y = 0;
rect.w = 457;
rect.h = 497;
}
bool gameinit() {
std::ofstream errfile;
errfile.open("errlog.txt");
clearkpresses();
setrect();
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0 ) {
errmsg = "SDL could not initialize! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( window == NULL ){
errmsg = "Window could not be created! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
image = SDL_LoadBMP(imgpath);
if (image == NULL) {
errmsg = "Media unable to load! IMG Error: ";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
return true;
}
void gamehalt()
{
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
}
int main(int argc, char* args[]) {
if (!gameinit()) {
gamehalt();
return 0;
}
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
switch(event.type) {
case SDLK_w:
kpresses.wdown = true;
case SDLK_a:
kpresses.adown = true;
case SDLK_s:
kpresses.sdown = true;
case SDLK_d:
kpresses.ddown = true;
case SDLK_e:
kpresses.edown = true;
case SDLK_ESCAPE:
kpresses.escdown = true;
}
}
//TODOUpdate
//TODORender
SDL_BlitSurface(image, NULL, screensurface, &rect);
SDL_UpdateWindowSurface(window);
//reset
clearkpresses();
}
gamehalt();
return 0;
}
Compiled, assembled, and linked with this windows cmd command:
g++ Main.cpp -static-libgcc -static-libstdc++ -I..\include\SDL2\include\SDL2 -I..\include\SDL2_image\include\SDL2 -L..\include\SDL2\lib -L..\include\SDL2_image\lib -w -lmingw32 -lSDL2main -lSDL2 -o ../Transcend.exe
It compiles and runs with no errors, but only displays a blank screen.
The problem is that you are trying to get the window surface, but the window isn't already created.
Please swap those two lines:
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
This way:
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
screensurface = SDL_GetWindowSurface(window);
I am following a french tutorial in order to learn C programming, and I am right now facing the exercice of making a timer, which updates every 100 milliseconds. Since the tutorial is for SDL and I am using SDL2, I am mixing it with some knowledge found on Internet.
If anyone here has time and know some SDL2/SDL_TTF, can you try to solve this ?
The function nulos() is a way to find it the initialization worked out.
To resume, my two problems are : the window closes itself at about 2 seconds and I can't click on the close option, and the second one is my text not showing.
Have a Good Day !
int compteur()
{
SDL_Window *pWindow = NULL;
SDL_Renderer *pRenderer = NULL;
SDL_Texture *pTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Surface *pTexte = NULL;
SDL_Event event;
TTF_Font *pFont = NULL;
SDL_Color black = {0, 0, 0};
SDL_Color white = {255, 255, 255};
SDL_Rect position = {200, 200, 0, 0};
int bPlay = 1;
int tempsActuel = 0;
int tempsPrecedent = 0;
int compteur = 0;
char temps[20];
temps[0] = '\0';
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
{
fprintf(stderr, "Erreur SDL_Init : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
TTF_Init();
pWindow = SDL_CreateWindow("COMPTEUR.C", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
pSurface = SDL_GetWindowSurface(pWindow);
if(nulos(pWindow, pRenderer, pSurface) != 0)
exit(EXIT_FAILURE);
pFont = TTF_OpenFont("images/Gabriola.ttf", 40);
if(pFont == NULL)
{
fprintf(stderr, "Error TTF_OpenFont : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
TTF_SetFontStyle(pFont, TTF_STYLE_ITALIC | TTF_STYLE_UNDERLINE);
tempsActuel = SDL_GetTicks();
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
while(bPlay != 0)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
bPlay = 0;
break;
}
SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, black.r, black.g, black.b));
SDL_RenderClear(pRenderer);
tempsActuel = SDL_GetTicks();
if(tempsActuel - tempsPrecedent >= 100)
{
compteur += 100;
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
tempsPrecedent = tempsActuel;
}
SDL_BlitSurface(pTexte, NULL, pSurface, &position);
SDL_FreeSurface(pTexte);
pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
SDL_RenderCopy(pRenderer, pTexture, NULL, NULL);
SDL_RenderClear(pRenderer);
}
SDL_DestroyRenderer(pRenderer);
SDL_FreeSurface(pSurface);
SDL_DestroyRenderer(pRenderer);
SDL_DestroyWindow(pWindow);
TTF_Quit();
SDL_Quit();
return EXIT_SUCCESS;
}
int nulos(SDL_Window *w, SDL_Renderer *r, SDL_Surface *s)
{
if(w == NULL)
{
fprintf(stderr, "Erreur SDL_CreateWindow : %s ", SDL_GetError());
return -1;
}
else if(r == NULL)
{
fprintf(stderr, "Erreur SDL_CreateRenderer : %s ", SDL_GetError());
return -1;
}
else if(s == NULL)
{
fprintf(stderr, "Erreur SDL_GetWindowSurface : %s ", SDL_GetError());
return -1;
}
return 0;
}
Okay I have resolved the first problem, it was just a careless mistake. It should have been :
SDL_RenderPresent(pRenderer);
Instead of
SDL_RenderClear(pRenderer);
However the window still closes by itself...
Okay I did it ! For anyone wondering, here's the "good" programming. I put a SDL_PollEvent and moved pTexte elsewhere :
#include "main.h"
int compteur()
{
SDL_Window *pWindow = NULL;
SDL_Renderer *pRenderer = NULL;
SDL_Texture *pTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Surface *pTexte = NULL;
SDL_Event event;
TTF_Font *pFont = NULL;
SDL_Color black = {0, 0, 0};
SDL_Color white = {255, 255, 255};
SDL_Rect position;
SDL_bool bQuit = SDL_FALSE;
int tempsActuel = 0;
int tempsPrecedent = 0;
int compteur = 0;
char temps[20];
temps[0] = '\0';
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
fprintf(stderr, "Erreur SDL_Init : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
TTF_Init();
pWindow = SDL_CreateWindow("COMPTEUR.C", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(pRenderer);
pSurface = SDL_GetWindowSurface(pWindow);
if(pWindow == NULL || pRenderer == NULL || pSurface == NULL)
{
fprintf(stderr, "Erreur : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
pFont = TTF_OpenFont("images/Gabriola.ttf", 40);
if(pFont == NULL)
{
fprintf(stderr, "Error TTF_OpenFont : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
TTF_SetFontStyle(pFont, TTF_STYLE_ITALIC | TTF_STYLE_UNDERLINE);
tempsActuel = SDL_GetTicks();
sprintf(temps, "Temps : %d", compteur);
pTexte = TTF_RenderText_Shaded(pFont, temps, black, white);
if(pTexte == NULL)
{
fprintf(stderr, "Error TTF_RenderText_Shaded : %s ", TTF_GetError());
exit(EXIT_FAILURE);
}
while(!bQuit) //SDL_FALSE == 0
{
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
bQuit = SDL_TRUE;
break;
}
}
tempsActuel = SDL_GetTicks();
if(tempsActuel - tempsPrecedent >= 100)
{
compteur += 100;
sprintf(temps, "Temps : %d", compteur);
tempsPrecedent = tempsActuel;
}
position.x = 180;
position.y = 210;
pTexte = TTF_RenderText_Shaded(pFont, temps, white, black);
SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, black.r, black.g, black.b));
SDL_BlitSurface(pTexte, NULL, pSurface, &position);
SDL_FreeSurface(pTexte);
pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
if(pTexture == NULL)
{
fprintf(stderr, "Error SDL_CreateTextureFromSurface : %s ", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_RenderCopy(pRenderer, pTexture, NULL, NULL);
SDL_RenderPresent(pRenderer);
}
SDL_Delay(20);
SDL_FreeSurface(pSurface);
if(pTexture != NULL)
SDL_DestroyTexture(pTexture);
if(pRenderer != NULL)
SDL_DestroyRenderer(pRenderer);
if(pWindow != NULL)
SDL_DestroyWindow(pWindow);
TTF_Quit();
SDL_Quit();
return EXIT_SUCCESS;
}
I'm following the Lazy Foo tutorial on C++ and SDL2. I'm trying to learn it using regular C and noticed something interesting when following instructions on adding events to detect a close window event.
Here is the code.
#include <stdio.h>
#include <stdbool.h>
#include "SDL2/SDL.h"
bool init();
bool loadMedia();
void close();
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
SDL_Window *gWindow = NULL;
SDL_Surface *gScreenSurface = NULL;
SDL_Surface *gHelloWorld = NULL;
int main(int argc, char *argv[])
{
if(!init()) {
printf("Failed to initialize!\n");
}
else {
if(!loadMedia()) {
printf("Failed to load media!\n");
}
else {
bool quit = false;
SDL_Event e;
while(!quit) {
printf("%d", SDL_PollEvent(&e));
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
}
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);
}
}
}
close();
return 0;
}
bool init()
{
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else {
gWindow = SDL_CreateWindow("SDL Tutorial 03", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL) {
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else {
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}
bool loadMedia()
{
bool success = true;
gHelloWorld = SDL_LoadBMP("images/hello_world.bmp");
if(gHelloWorld == NULL) {
printf("Unable to load image %s! SDL_Error: %s\n", "images/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void close()
{
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
SDL_DestroyWindow(gWindow);
gWindow = NULL;
SDL_Quit();
}
If I compile this with a ".c" extension, it compiles without errors, but selecting the "X" on the window title bar does nothing. If I change said extension to ".cpp", the "X" works as intended.
I'm using the following command to compile the code.
gcc main.c -w -lSDL2 -o main
Any ideas why this may work with C++, but not with C?
The function SDL_PollEvent will remove the event from the internal event queue if an address of an SDL_event object is passed to it.
The printf call, that also calls the function SDL_PollEvent, before the event loop which will remove the quit event from the queue. This means the event loop won't find this event:
printf("%d", SDL_PollEvent(&e));
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
}
If you only want to check if there are events pending in the queue, then use the function SDL_PollEvent with a NULL argument:
printf("%d", SDL_PollEvent(NULL));
So, I picked up SDL and started writing a simple game. There is some problem I'm very confused about when I try to draw two textures to the screen using SDL_RenderCopy. The important part is inside the while(!quit) where there are two SDL_RenderCopy calls. For some reason only the second one draws something on the screen. Here's my code:
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
enum TEXTURES{
T_GRASS,
T_ALL
};
bool init();
bool loadMedia(const int texture, char* path);
void close();
SDL_Texture* loadTexture(char* path);
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* textures[] = {NULL};
int main(int argc, char* args[]){
if(!init())
printf("Failed to initialize!\n");
else
if(!loadMedia(T_GRASS, "images/tGrass.png"))
printf("Failed to load media!\n");
else{
bool quit = false;
SDL_Event e;
while(!quit){
while(SDL_PollEvent(&e) != 0)
if(e.type == SDL_QUIT)
quit = true;
SDL_RenderClear(renderer);
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos.x = 16;
pos.y = 16;
SDL_RenderCopy(renderer,textures[T_GRASS],NULL,&pos);
SDL_RenderCopy(renderer,textures[T_GRASS],NULL,&pos1);
SDL_RenderPresent(renderer);
}
}
close();
return 0;
}
bool init(){
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("SDL could not initialize! Error: %s\n", SDL_GetError());
success = false;
}else{
if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
printf("WARNING: Linear texture filtering not enabled!\n");
window = SDL_CreateWindow("openZ", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL){
printf("Window could not be created! Error: %s\n", SDL_GetError());
success = false;
}else{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(renderer == NULL){
printf("Render could not be created! Error: %s\n", SDL_GetError());
success = false;
}else{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
printf("SDL Image could not initialize! Error: %s\n", SDL_GetError());
success = false;
}
}
}
}
return success;
}
bool loadMedia(const int texture, char* path){
bool success = true;
textures[texture] = loadTexture(path);
if(textures[texture] == NULL){
printf("Failed to load texture image %s!\n", path);
success = false;
}
return success;
}
void close(){
for(int i = 0; i < T_ALL; i++){
SDL_DestroyTexture(textures[i]);
textures[i] = NULL;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
window = NULL;
renderer = NULL;
IMG_Quit();
SDL_Quit();
}
SDL_Texture* loadTexture(char* path){
SDL_Texture* newTexture = NULL;
SDL_Surface* loadedSurface = IMG_Load(path);
if(loadedSurface == NULL){
printf("Unable to load image %s! Error: %s\n", path, IMG_GetError());
}else{
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if(newTexture == NULL)
printf("Unable to create texture from %s! Error: %s\n", path, SDL_GetError());
SDL_FreeSurface(loadedSurface);
}
return newTexture;
}
Sorry! My bad.. turns out I had 2 typos which made the two textures render over each other. I wrote:
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos.x = 16;
pos.y = 16;
where it should have been:
SDL_Rect pos;
pos.h = 16;
pos.w = 16;
pos.x = 0;
pos.y = 0;
SDL_Rect pos1;
pos1.h = 16;
pos1.w = 16;
pos1.x = 16;
pos1.y = 16;
^^ the last too lines were referencing the wrong rectangle.
So I just started doing some SDL tutorials and I got to one when suddenly I get an error message saying "ld: library not found for -lstring". Says the same thing about stdio.
I tried adding the paths and libraries. I use the MacOS X C++ Linker (MacOSX GCC Tool Chain) but I just can't seem to get it to work. Any ideas?
I'm on Eclipse btw.
/*
* Main.cpp
*
* Created on: 29 jan 2014
* Author: CaptainAwesome
*/
//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>
//Starts up SDL and creates window
bool init();
//Loads media
bool loadMedia();
//Free media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
enum KeyPressSurfaces
{
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image that corresponds to a keypress
SDL_Surface* gKeyPressSurfaces[ KEY_PRESS_SURFACE_TOTAL];
//The image we will load and show on the screen
SDL_Surface* gCurrentSurface = NULL;
bool init()
{
//Init flag
bool success = true;
//Init SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
return success;
}
SDL_Surface* loadSurface(std::string path)
{
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if(loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
return loadedSurface;
}
bool loadMedia()
{
//Load success flag
bool success = true;
//Load default surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] = loadSurface("Assets/maxresdefault.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] == NULL)
{
printf("Unable to load default image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] = loadSurface("Assets/1.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] == NULL)
{
printf("Unable to load up image %s\n!");
success = false;
}
//Load down surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] = loadSurface("Assets/duty_calls");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] == NULL)
{
printf("Unable to load down image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] = loadSurface("Assets/mario-land.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] == NULL)
{
printf("Unable to load left image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] = loadSurface("Assets/ML.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] == NULL)
{
printf("Unable to load right image %s\n!");
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface(gCurrentSurface);
gCurrentSurface = NULL;
//Destroooooy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
int main (int argc, char* args[])
{
//Start up SDL and create window
if(!init())
{
printf("Fail to init!\n");
}
else
{
//Load media
if(!loadMedia())
{
printf("Failed to load media!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set default current surface
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
//While app is running
while(!quit)
{
while(SDL_PollEvent(&e) != 0)
{
//User presses esc
if(e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key (up, down, left, right)
else if(e.type)
{
//Select surfaces based on key pressed
switch(e.key.keysym.sym)
{
case SDLK_UP:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_UP];
break;
case SDLK_DOWN:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN];
break;
case SDLK_LEFT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT];
break;
case SDLK_RIGHT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT];
break;
case SDLK_ESCAPE:
quit = true;
break;
default:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
break;
}
}
//Apply image
SDL_BlitScaled(gCurrentSurface, NULL, gScreenSurface, NULL);
//Update surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
}
//Free resources and close SDL
close();
return 0;
}