Why the game window closes after specific time? - c++

Why the window that created by SDL Game Library are automatically closed after specific time.
I know the reason is SDL_Delay() function, but if not used that function, the game will appear runtime error.
How can I create a window that continuously work without appear in specific period time ?
My code(Simplest code):
SDL_Window *window;
SDL_Renderer *render;
int main(int argc, char* args[]){
if(SDL_Init(SDL_INIT_EVERYTHING) >= 0){
window = SDL_CreateWindow("Simple game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
if(window != 0){
render = SDL_CreateRenderer(window, -1, 0);
}
}else{
return 1;
}
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
SDL_RenderPresent(render);
SDL_Delay(3000);
SDL_Quit();
return 0
}

You need to loop forever and call SDL update screen functions. Read LazyFoo tutorials found here: http://lazyfoo.net/SDL_tutorials
Or here a short code to get you started:
#include <iostream>
#include "SDL/SDL.h" // basic SDL
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BBP = 32; // bits per-pixel
SDL_Surface* screen = NULL; // display screen
SDL_Event event; // grab events
using namespace std;
bool init() {
// initialize SDL
if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
return false;
//the screen image
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
SCREEN_BBP, SDL_SWSURFACE );
if(!screen) {
cout << "error creating screen" << endl;
return false;
}
//Set the window caption
SDL_WM_SetCaption("Event Test", NULL );
return true;
}
int main(int argc, char* argv[])
{
try
{
// make sure the program waits for a quit
bool quit = false;
cout << "Starting SDL..." << endl;
// Start SDL
if(!init()) {
cout << "initialize error" << endl;
return false;
}
// main loop
while( quit == false )
{
if (SDL_PollEvent(&event))
{
// The x button click
if(event.type == SDL_QUIT)
{
//quit the program
quit = true;
}
}
// Fill the screen white
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB(
screen->format, 0xFF, 0xFF, 0xFF ) );
//Update screen
if(SDL_Flip(screen) == -1)
return -1;
}
}
catch (exception& e)
{
cerr << "exception caught: " << e.what() << endl;
return -1;
}
return 0;
}

Related

window doesnt show image SDL

The program doesnt show the image in the window i have created , also i dont get any of the fail messages that i have set , which means the values are not null.
What is the problem?
Here is the code:
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
int main(int argc,char* argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Event event;
bool quit = false;
SDL_Surface *tmpsur = NULL;
SDL_Texture *tex = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("First window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
tmpsur = IMG_Load("assets/player.png");
if (tmpsur == NULL)
{
std::cout << "fail" << std::endl;
}
tex = SDL_CreateTextureFromSurface(renderer,tmpsur);
if (tex == NULL)
{
std::cout << "fail 2" << std::endl;
}
SDL_FreeSurface(tmpsur);
SDL_RenderPresent(renderer);
while (!quit)
{
while (SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
You need to copy your texture onto the render target. Before presenting your renderer you need to call SDL_RenderCopy like this:
SDL_RenderCopy(renderer, text, nullptr, nullptr);
SDL_RenderPresent(renderer);
The nullptrs in the argument will make it copy the texture over all your target (the window).

Error to pixel manipulation SDL2 c++

i'm trying to create a manual color key with pixel manipulation in SDL2, but when i execute the program, the color key doesn't work, these pixels become white, but not transparent.
I tried to Lock the surface and set the surface blendmode, but doesn't work too.
Code:
// IO includes
#include <iostream>
// String includes
#include <string>
// SDL includes
#include <SDL.h>
#include <SDL_image.h>
// Screen constants
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
using namespace std;
// Window variables
SDL_Window *window = NULL;
SDL_Surface *windowSurface = NULL;
// Image surfaces
SDL_Surface *background = NULL;
SDL_Surface *image = NULL;
// Functions
bool initializeSDL();
SDL_Surface *loadSurfaceFromFile(string path);
void SetColorKey(SDL_Surface *surface, Uint32 color);
bool LoadFiles();
void FreeMemory();
// SDL_main
int main(int argc, char* argv[]){
// Try to initialize and load files
if(initializeSDL() == false){
FreeMemory();
return -1;
}
if(LoadFiles() == false){
FreeMemory();
return -1;
}
// Blit images
SDL_BlitSurface(background, NULL, windowSurface, NULL);
SDL_BlitSurface(image, NULL, windowSurface, new SDL_Rect(70, 277, image->w, image->h));
// Update screen
SDL_UpdateWindowSurface(window);
// Loop
SDL_Event ev;
while(true){
if(SDL_PollEvent(&ev) && ev.type == SDL_QUIT) break;
}
return 0;
}
bool initializeSDL(){
// Try to initialize the video
if( SDL_Init(SDL_INIT_VIDEO) < 0 ){
// Print error
cout << "Error to initialize the video: " << SDL_GetError() << endl;
return false;
}
// Try to create the window
window = SDL_CreateWindow("Surface", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL){
// Print error
cout << "Error to create the window: " << SDL_GetError() << endl;
return false;
}
// Try to initialize PNG format
int imgFlags = IMG_INIT_PNG;
if(! (IMG_Init(imgFlags) &imgFlags) ) return false;
// Get the window surface
windowSurface = SDL_GetWindowSurface(window);
// If everything is fine, return true
return true;
}
SDL_Surface* loadSurfaceFromFile(string path){
// Create a temporary surface
SDL_Surface *tmpSurface = NULL;
// Create an optimized surface
SDL_Surface *optimizedSurface = NULL;
// Try to load the tmpSurface
tmpSurface = IMG_Load(path.c_str());
if(tmpSurface == NULL){
// Print error
cout << "Error to load the image: " << SDL_GetError() << endl;
return NULL;
}
// Try to optimize the surface
optimizedSurface = SDL_ConvertSurface(tmpSurface, windowSurface->format, NULL);
SDL_FreeSurface(tmpSurface); // Free tmpSurface memory
delete tmpSurface; // Delete the tmpSurface
if(optimizedSurface == NULL){
// Print error
cout << "Error to optimize the image: " << SDL_GetError() << endl;
}
return optimizedSurface;
}
void SetColorKey(SDL_Surface *surface, Uint32 color){
Uint32 *pixels = (Uint32*)surface->pixels;
int pixelCount = (surface->pitch/4) * surface->h;
Uint32 transparent = SDL_MapRGBA(image->format, 255, 255, 255, 0);
for(int i=0;i<pixelCount;i++){
if(pixels[i] == color){
pixels[i] = transparent;
}
}
}
bool LoadFiles(){
// Try to load the background
background = loadSurfaceFromFile("background.bmp");
if(background == NULL) return false;
// Try to load the image
image = loadSurfaceFromFile("image.png");
if(image == NULL) return false;
// Set manual color key to image
SetColorKey(image, SDL_MapRGB(image->format, 0, 255, 255));
return true;
}
void FreeMemory(){
SDL_FreeSurface(background);
SDL_FreeSurface(image);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
}

SDL window not showing?

I have this simple code for SDL.
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
using namespace std;
int main(int argc, char * argv[]){
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
return 1;
}
SDL_Window * win = SDL_CreateWindow("Window", 0, 0, 1920, 1080, SDL_WINDOW_FULLSCREEN_DESKTOP);
if(win == nullptr){
return 1;
}
SDL_Quit();
return 0;
}
None of this shows a window, I have error checked everything. It was working previously, but now it just opens and closes. I'm running on Xcode, if that helps.
Like the others state, your program terminates immediately so the window should "flash" momentarily. You can have the window appear for a few seconds by using SDL_Delay:
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win == nullptr){
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Delay(2000);
SDL_DestroyWindow(win);
SDL_Quit();
And remember to call SDL_DestroyWindow.
A while(true) {} loop will just cause your program to freeze. You probably want something like the following so that it listens for events, and you can close the window at your leisure.
SDL_Event e;
bool quit = false;
while (!quit){
while (SDL_PollEvent(&e)){
if (e.type == SDL_QUIT){
quit = true;
}
if (e.type == SDL_KEYDOWN){
quit = true;
}
if (e.type == SDL_MOUSEBUTTONDOWN){
quit = true;
}
}
}

SDL not responding after running for a few seconds on linux

I was following the SDL Game development book and I cant even get the first file to work right. Upon the application starting it renders the window and then after a few seconds Linux says the game is not responding and ask me to force quit. This repeats every few seconds if I click wait. One thing I have noticed is that SDL_PollEvent never returns true.I am not sure why things are not working. Here is my code.
Main.cpp
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include "Game.h"
// our Game object
Game* g_game = 0;
int main(int argc, char* argv[]) {
g_game = new Game();
g_game->init("Chapter 1", 100, 100, 640, 480, 0);
while(g_game->running()) {
g_game->handleEvents();
//g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}
Game.h
#ifndef __Game__
#define __Game__
#if !WINDOWS
#include <SDL2/SDL.h>
#else
#include <SDL.h>
#endif
class Game {
public:
Game() {}
~Game() {}
// simply set the running variable to true
bool init(const char* title, int xpos, int ypos, int width, int
height, bool fullscreen);
void render();
void update();
void handleEvents();
void clean();
// a function to access the private running variable
bool running() {
return m_bRunning;
}
private:
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
bool m_bRunning;
};
#endif /* defined(__Game__) */
Game.cpp
#include "Game.h"
#include <iostream>
bool Game::init(const char* title, int xpos, int ypos, int width,
int height, bool fullscreen) {
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0) {
std::cout << "SDL init success\n";
// init the window
int flags = 0;
if(fullscreen) {
flags = SDL_WINDOW_FULLSCREEN;
}
m_pWindow = SDL_CreateWindow(title, xpos, ypos,
width, height, flags);
if(m_pWindow != 0) { // window init success
std::cout << "window creation success\n";
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
if(m_pRenderer != 0) { // renderer init success
std::cout << "renderer creation success\n";
SDL_SetRenderDrawColor(m_pRenderer,
255,0,255,255);
} else {
std::cout << "renderer init fail\n";
return false; // renderer init fail
}
} else {
std::cout << "window init fail\n";
return false; // window init fail
}
} else {
std::cout << "SDL init fail\n";
return false; // SDL init fail
}
std::cout << "init success\n";
m_bRunning = true; // everything inited successfully, start the main loop
return true;
}
void Game::render() {
SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean() {
std::cout << "cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}
void Game::handleEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
std::cout << "Checking Events";
switch(event.type) {
case SDL_QUIT:
std::cout << "Quiting";
m_bRunning = false;
break;
default:
break;
}
}
}
Edit:
so I made a minamal version of the code and now i get a new error. The error says "Segmentation Fault (core dumped)". Based on running it to a specific line in debug the error seems to appear at the line that says "SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);" I am not sure what the error is though
Here is the minial code:
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, char** argv) {
if(SDL_Init(SDL_INIT_EVERYTHING) != 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if(win == NULL) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(ren == NULL) {
SDL_DestroyWindow(win);
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
std::string imagePath = "cb.bmp";
SDL_Surface *bmp = SDL_LoadBMP(imagePath.c_str());
if(bmp == NULL) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
if(tex == NULL) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_FreeSurface(bmp);
SDL_Event e;
bool quit = false;
while(!quit) {
while(SDL_PollEvent(&e)) {
//If user closes the window
if(e.type == SDL_QUIT) {
quit = true;
}
//If user presses any key
if(e.type == SDL_KEYDOWN) {
quit = true;
}
//If user clicks the mouse
if(e.type == SDL_MOUSEBUTTONDOWN) {
quit = true;
}
}
SDL_RenderClear(ren);
SDL_RenderPresent(ren);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
I have compiled and run your minimal code successfully under Linux with SDL 2.0.4. I used a simple image as "cb.bmp".
Try the following :
compile like this : g++ -Wall -ggdb $(sdl2-config --cflags) -o program main.cpp -lSDL2
gdb ./program, then type 'run'
when it crashes, type 'bt' (for backtrace)
copy the output here
My guess is : either the "bmp" file format is not supported or the rendering driver is not supported. try to use :
SDL_CreateRenderer(win, -1, 0);

C++ game loop example

Can someone write up a source for a program that just has a "game loop", which just keeps looping until you press Esc, and the program shows a basic image. Heres the source I have right now but I have to use SDL_Delay(2000); to keep the program alive for 2 seconds, during which the program is frozen.
#include "SDL.h"
int main(int argc, char* args[]) {
SDL_Surface* hello = NULL;
SDL_Surface* screen = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
hello = SDL_LoadBMP("hello.bmp");
SDL_BlitSurface(hello, NULL, screen, NULL);
SDL_Flip(screen);
SDL_Delay(2000);
SDL_FreeSurface(hello);
SDL_Quit();
return 0;
}
I just want the program to be open until I press Esc. I know how the loop works, I just don't know if I implement inside the main() function, or outside of it. I've tried both, and both times it failed. If you could help me out that would be great :P
Here is a complete and working example. Instead of using a frame-time regulation you can also use SDL_WaitEvent.
#include <SDL/SDL.h>
#include <cstdlib>
#include <iostream>
using namespace std;
const Uint32 fps = 40;
const Uint32 minframetime = 1000 / fps;
int main (int argc, char *argv[])
{
if (SDL_Init (SDL_INIT_VIDEO) != 0)
{
cout << "Error initializing SDL: " << SDL_GetError () << endl;
return 1;
}
atexit (&SDL_Quit);
SDL_Surface *screen = SDL_SetVideoMode (640, 480, 32, SDL_DOUBLEBUF);
if (screen == NULL)
{
cout << "Error setting video mode: " << SDL_GetError () << endl;
return 1;
}
SDL_Surface *pic = SDL_LoadBMP ("hello.bmp");
if (pic == NULL)
{
cout << "Error loading image: " << SDL_GetError () << endl;
return 1;
}
bool running = true;
SDL_Event event;
Uint32 frametime;
while (running)
{
frametime = SDL_GetTicks ();
while (SDL_PollEvent (&event) != 0)
{
switch (event.type)
{
case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE)
running = false;
break;
}
}
if (SDL_GetTicks () - frametime < minframetime)
SDL_Delay (minframetime - (SDL_GetTicks () - frametime));
}
SDL_BlitSurface (pic, NULL, screen, NULL);
SDL_Flip (screen);
SDL_FreeSurface (pic);
SDL_Delay (2000);
return 0;
}
Tried with something like
SDL_Event e;
while( SDL_WaitEvent(&e) )
{
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) break;
}
? You can find many tutorials and example out there; just a fast-search example.
Added note: WaitEvent "freezes" the program so you can't do anything .. you just wait; other waiting technics can be desired (as PollEvent, or WaitEvent again after the initializtion of a timer).
Since you're already using SDL, you could use the SDL_PollEvent function to run an event loop, checking to see if the key press event was ESC. Looks like this would be along the lines of mySDL_Event.key.keysym.sym == SDLK_ESCAPE.
#include <conio.h>
...
while (!kbhit())
{
hello = SDL_LoadBMP("hello.bmp");
SDL_BlitSurface(hello, NULL, screen, NULL);
SDL_Flip(screen);
}
...