I am trying to make a program that will be able to detect key-presses with SDL.
My current code is a modified version of somebody elses (trying to get it to work before making my own version).
#include "SDL/SDL.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
//Start SDL
if(0 != SDL_Init(SDL_INIT_EVERYTHING)) {
std::cout << "Well I'm screwed\n";
return EXIT_FAILURE;
}
SDL_Surface* display;
display = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_Event event;
bool running = true;
std::cout << "Cake"; //Testing output (doesn't work)
while(running) {
std::cout << "Pie"; //Again, testing output and again doesn't work
if(SDL_PollEvent(&event)) { //I have tried this is a while statement
switch(event.type) {
case SDL_KEYDOWN:
std::cout << "Down\n"; // Have tried "<< std::endl" instead of "\n"
break;
case SDL_KEYUP:
std::cout << "Up\n";
break;
case SDL_QUIT:
running = false;
break;
default:
break;
}
}
}
//Quit SDL
SDL_Quit();
return 0;
}
This code is supposed to detect any key-down/up and output it, but it doesn't output anything.
My ultimate goal is to make it detect the konami code and then do something.
I constantly update the code above making it identical to the one I am using (except with added comments of what people have suggested).
Also if it helps: g++ -o myprogram.exe mysource.cpp -lmingw32 -lSDLmain -lSDL is the command I am using to compile. (If you didn't figure it out from the command, I am running windows (7).)
No errors occur when compiling
I am getting now output whatsoever, which leads me to believe that my probs has nothing to do with the key-checking; however there is a chance that is incorrect.
SDL needs a window to receive events.
Uncomment your SDL_SetVideoMode() call:
#include <SDL/SDL.h>
#include <iostream>
using namespace std;
int main( int argc, char* argv[] )
{
if( 0 != SDL_Init(SDL_INIT_EVERYTHING) )
{
std::cout << "Well I'm screwed\n";
return EXIT_FAILURE;
}
SDL_Surface* display;
display = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_Event event;
bool running = true;
while(running)
{
if(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
std::cout << "Down" << endl;
break;
case SDL_KEYUP:
std::cout << "Up" << endl;
break;
case SDL_QUIT:
running = false;
break;
default:
break;
}
}
}
SDL_Quit();
return 0;
}
SDL By default redirects output to stdout.txt
You should query for all the SDL events in the loop, not just the first one. Try this one to check all the events:
while( SDL_PollEvent( &event ) ){
...
}
also you can try to update the screen in the loop with:
SDL_Flip( display );
hey there i think you should go to your "project properties" then "linker settings" and "Subsystem" then choose "Console (/SUBSYSTEM:CONSOLE)" Otherwise you can't see what you typed in cout and in visual studio you cant use
#include"SDL/SDL.h" you should type #include<SDL.h>
Related
I'm working on a small project in CLion with SDL2 on Windows.
When I compile and run (Shift+F10) my program in CLion, it does not show any console output. However, when I run it using the debugger (Shift+F9), it does show console output..
I have no idea what is causing this.
To make sure my project or CLion isn't corrupting something, I've copied the sources over to a new project and set it up using the same CMakeList.txt file, and it still does not work.
My CMakeList.txt:
CMakeList.txt
cmake_minimum_required(VERSION 3.6)
project(SDL_Project)
set(CMAKE_CXX_STANDARD 14)
# FindSDL2.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
#find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})
include_directories(${SDL2_IMAGE_INCLUDE_DIR})
#include_directories(${SDL2_TTF_INCLUDE_DIR})
add_executable(SDL_Project src/main.cpp src/Game.cpp src/Game.h)
set_target_properties(SDL_Project PROPERTIES WIN32_EXECUTABLE FALSE)
target_link_libraries(SDL_Project ${SDL2_LIBRARY})
target_link_libraries(SDL_Project ${SDL2_IMAGE_LIBRARIES})
#target_link_libraries(SDL_Project ${SDL2_TTF_LIBRARIES})
I also tried compiling the following code (without SDL2, but using the same CMakeList.txt):
#include <iostream>
int main(int argv, char* args[]) {
std::cout << "Hello World!" << std::endl;
return 0;
}
This has the same issue; no console output.
Compiling the above code without the find_package, include_directories and target_link_libraries in CMakeList.txt shows console output! So it is related to SDL2, I think..?
Does anyone know what is causing this, and how to fix it?
Though I believe the problem lies in CMakeList.txt, here is the remaining code:
main.cpp
#include <SDL.h>
#include <iostream>
#include "Game.h"
int main(int argv, char* args[]) {
const int FPS = 60;
const uint32_t frameDelay = 1000 / FPS;
const WindowSettings settings = {SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720};
Game game;
Uint32 frameStart;
Uint32 frameTime;
game.init("Game", settings);
while (game.isRunning()) {
frameStart = SDL_GetTicks();
game.handleEvents();
game.tick();
game.render();
frameTime = SDL_GetTicks() - frameStart;
std::cout << "Frame time: " << frameTime << " / " << frameDelay << std::endl;
if (frameTime < frameDelay) {
std::cout << "Frame delay: " << (frameDelay - frameTime) << std::endl;
SDL_Delay(frameDelay - frameTime);
}
}
game.cleanup();
return 0;
}
Game.h
#ifndef SDL_PROJECT_GAME_H
#define SDL_PROJECT_GAME_H
#include <SDL.h>
struct WindowSettings {
int x;
int y;
int width;
int height;
};
class Game {
private:
bool running;
SDL_Window* window;
SDL_Renderer* renderer;
public:
Game();
~Game();
void init(const char* title, const WindowSettings &settings);
void tick();
void render();
void cleanup();
void handleEvents();
bool isRunning() { return running; }
};
#endif //SDL_PROJECT_GAME_H
Game.cpp
#include <iostream>
#include "Game.h"
Game::Game():
running(false),
window(nullptr),
renderer(nullptr) {
}
Game::~Game() = default;
void Game::init(const char *title, const WindowSettings &settings) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL initialization failed: " << SDL_GetError() << std::endl;
return;
};
window = SDL_CreateWindow(title, settings.x, settings.y, settings.width, settings.height, SDL_WINDOW_SHOWN);
if (window == nullptr) {
std::cout << "Unable to create window: " << SDL_GetError() << std::endl;
return;
}
renderer = SDL_CreateRenderer(window, -1 , 0);
if (renderer == nullptr) {
std::cout << "Unable to create renderer: " << SDL_GetError() << std::endl;
return;
}
running = true;
}
void Game::tick() {
}
void Game::render() {
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void Game::cleanup() {
if (renderer) {
SDL_DestroyRenderer(renderer);
}
if (window) {
SDL_DestroyWindow(window);
}
SDL_Quit();
std::cout << "Game clean exit" << std::endl;
}
void Game::handleEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
}
I can think of 1 issue. Are you sure your run configuration is correct CLION? The debug build could be running a different executable than you think. CLION does a lot of stuff behind the scenes. Click the run arrow drop down and look at edit configurations or something to that effect.
Alright, I figured it out..
Apparently, compiling on Windows redirects stdout and stderr to null (?). I was unable to locate/remove the compiler flag that influences this, however, SDL provides SDL_Log, which does in fact output to the console (and presumably stdout?).
Since I'm using SDL2 anyway, I might as well use the logger. It supports printf-style formatting, which is a nice bonus. And it allows me to set up a custom logging function if I want to redirect log messages.
Here is a small code and when we press "é" key or special characters with for instance french keyboards, we get in the console weird characters such as "├®".
#include <iostream>
#include "SDL.h"
using namespace std;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_CreateWindow("test", 100, 100, 1920, 1080, SDL_WINDOW_RESIZABLE);
bool opened = true;
SDL_Event event;
while(opened)
{
SDL_StartTextInput();
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
{
opened = 0;
break;
}
case SDL_TEXTINPUT:
{
cout << event.text.text << endl;
break;
}
}
}
return EXIT_SUCCESS;
}
PS: I am using SDL 2
Just have to use TTF_RenderUTF8_Blended for render (output in file was fine).
I am experimenting with keyboard input in SDL and I have encountered a strange problem. Whenever I get input it only outputs the appropriate response sometimes (Clicking X only sometimes closes the program, pressing 1 only sometimes outputs "you pressed 1". Here is my main code:
#include <iostream>
#include <SDL.h>
#include "Screen.h"
#include "Input.h"
using namespace std;
int main(int argc, char *argv[]) {
Screen screen;
Input input;
if (screen.init() == false) {
cout << "Failure initializing SDL" << endl;
}
while (true) {
if (input.check_event() == "1") {
cout << "You pressed 1" << endl;
} else if (input.check_event() == "quit") {
break;
}
}
SDL_Quit();
return 0;
and here is my Input class:
#include <iostream>
#include <SDL.h>
#include "Input.h"
using namespace std;
string Input::check_event() {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
return "quit";
}
else if(event.type == SDL_KEYDOWN){
switch(event.key.keysym.sym){
case SDLK_1:
return "1";
}
}
}
return "null";
}
Any help would be appreciated!
From the documentation of SDL_PollEvent():
If event is not NULL, the next event is removed from the queue and
stored in the SDL_Event structure pointed to by event.
Analyzing your code:
if (input.check_event() == "1") {
This removes the event, whatever it is, from the queue.
} else if (input.check_event() == "quit") {
Say the return value of the 1st call to check_event() was "quit", then this call won't return "quit" again, because this information is now lost.
To fix that, call check_event() only once per loop iteration and store the result in a temporary variable. Then use only that variable in the conditions:
while (true) {
string event = input.check_event();
if (event == "1") {
cout << "You pressed 1" << endl;
} else if (event == "quit") {
break;
}
}
I have been trying for hours to get a test SDL program up and running, but no matter what I try, it instantly terminates upon launching.
My code:
#include <iostream>
#include <SDL.h>
#undef main
using namespace std;
int main(int argc, char *argv[]) {
const int WIDTH = 800, HEIGHT = 600, SDLWP = SDL_WINDOWPOS_UNDEFINED;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL not working." << endl;
}
cout << "SDL working properly." << endl;
SDL_Window *window = SDL_CreateWindow("Test", SDLWP, SDLWP, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL) {
SDL_Quit();
}
bool quit = false;
SDL_Event event;
while(!quit) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I have gotten the program to actually do something by having this code:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
cout << "SDL working properly." << endl;
}
Also, about the #undef main part, I need that because otherwise, the program will think that I am calling SDL_main.
Here is the library search path if that helps:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\i686-w64-mingw32\lib
And the libraries themselves, written in order from top to bottom:
mingw32
SDL2main
SDL2
No other library path will give me no compiler errors except:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\lib\x86
So it seems that the root of problem is:
#include <SDL.h>
I'm trying to add a simple text to render it in a window. But I have a problem...
Everytime the console shows me the following answer :
"Couldn't load font file"
I don't know what is the origin of this problem. Maybe the mistake is in the .pro file :
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += /usr/include
LIBS += -L/usr/lib -lSDL2 -lSDL2_image -lSDL_ttf
SOURCES += main.cpp
There is the other part in main.cpp :
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
using namespace std;
void loop();
int main()
{
SDL_Init(SDL_INIT_VIDEO);
SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" );
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" );
if( TTF_Init() == -1 )
{
cout << TTF_GetError() << endl;
}
else {
TTF_Font* font = TTF_OpenFont("lazy.ttf", 10);
if( font == NULL ) {
cout << TTF_GetError() << endl;
}
else {
cout << "Font loaded" << endl;
}
}
loop();
return 0;
}
void loop() {
bool quit(false);
SDL_Event e;
while( !quit ) {
SDL_PollEvent(&e);
switch( e.type ) {
case SDL_QUIT:
quit = true;
break;
}
}
}
Further informations:
Fedora 20
Qt Creator
All the SDL packages installed with yum
The ttf font in the same directory as the executable
Thank you in advance !
To put the comments into an official answer:
This can happen if you link with SDL_ttf instead of SDL2_ttf on accident. The functions have identical names, so the call is made successfully, but the actions fail.
Make sure you linke with SDL2_ttf if using SDL 2.