I am trying to create a game in C using SDL. After some time of debugging I found an error at SDL_Init:
#include <SDL2/SDL_ttf.h>
int main(void) {
printf("Init attempt\n");
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
fprintf(stderr, "Failed at SDL init: %s\n", SDL_GetError());
fflush(stderr);
fflush(stdout);
exit(EXIT_FAILURE);
}
printf("Init success\n");
return EXIT_SUCCESS;
}
The output is the following:
Init attempt
Somehow the fprintf inside the write function is getting executed.
The gcc command I used is:
gcc -Wextra -Wall -pedantic program.c -lpthread -lSDL2 -lSDL2_ttf
Note: If I use g++, everything works fine. However, I must use gcc.
Is there a way to fix the error?
using the official doc (https://wiki.libsdl.org/SDL_Init) there's a flag that might conflict with your setup: SDL_INIT_HAPTIC
i didn't get any error or crash so im not sure, but it is possible that this flag might be included in the EVERYTHING one, and if so:
It’s disabled by default if you don’t use ./configure; make style builds.
Otherwise it’ll happily build if your headers are new enough.
(https://discourse.libsdl.org/t/sdl2-sdl-init-sdl-init-everything-failing/19250)
did you try setting up by flags you only need, like SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO and see if this works?
Related
I am trying to figure out how to properly handle game controller inputs in an SDL2 program. I have written a program which is able to handle inputs from my game controller on my Mac, but not on my Linux machine. However, the game controller does work with other programs on the Linux machine. My program uses a library called Simple2D, which wraps SDL2 to provide an easier interface.
I'm trying to determine if the problem is with the controller input handling or some missing dependency/configuration on the Linux side. I have not found any examples of using SDL2 to handle game controller inputs to determine if the code is working correctly.
Here is the code that Simple2D uses for handling game controller inputs. Do you see anything that could cause my controller to not work on my Linux machine?
https://github.com/simple2d/simple2d/blob/master/src/simple2d.c#L642-L689
// Variables for controllers and joysticks
SDL_GameController *controller = NULL;
SDL_Joystick *joy = NULL;
// Enumerate joysticks
for (int i = 0; i < SDL_NumJoysticks(); ++i) {
// Check to see if joystick supports SDL's game controller interface
if (SDL_IsGameController(i)) {
controller = SDL_GameControllerOpen(i);
if (controller) {
sprintf(S2D_msg, "Found a valid controller, named: %s\n",
SDL_GameControllerName(controller));
S2D_Log(S2D_msg, S2D_INFO);
break; // Break after first available controller
} else {
sprintf(S2D_msg, "Could not open game controller %i: %s\n", i, SDL_GetError());
S2D_Log(S2D_msg, S2D_ERROR);
}
// Controller interface not supported, try to open as joystick
} else {
sprintf(S2D_msg, "Joystick %i is not supported by the game controller interface", i);
S2D_Log(S2D_msg, S2D_WARN);
joy = SDL_JoystickOpen(i);
// Joystick is valid
if (joy) {
sprintf(S2D_msg,
"Opened Joystick %i\n"
"Name: %s\n"
"Axes: %d\n"
"Buttons: %d\n"
"Balls: %d\n",
i, SDL_JoystickName(joy), SDL_JoystickNumAxes(joy),
SDL_JoystickNumButtons(joy), SDL_JoystickNumBalls(joy)
);
S2D_Log(S2D_msg, S2D_INFO);
// Joystick not valid
} else {
sprintf(S2D_msg, "Could not open Joystick %i", i);
S2D_Log(S2D_msg, S2D_ERROR);
}
break; // Break after first available joystick
}
}
https://github.com/simple2d/simple2d/blob/master/src/simple2d.c#L782-L806
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_JOYAXISMOTION:
if (window->on_controller)
window->on_controller(true, e.jaxis.axis, e.jaxis.value, false, 0);
break;
case SDL_JOYBUTTONDOWN:
if (window->on_controller)
window->on_controller(false, 0, 0, true, e.jbutton.button);
break;
Update: Thanks to #genpfault, I found out that the SDL codebase comes with a test script. I am working on compiling and running this. After downloading the source code, on my Mac, I was able to successfully compile and run the test script like this:
$ cd SDL2-2.0.4/test
$ gcc testgamecontroller.c `sdl2-config --cflags --libs`
$ ./a.out
However, when I tried the same thing on my Linux machine, it failed to compile:
$ gcc testgamecontroller.c `sdl2-config --cflags --libs`
In file included from /usr/include/SDL2/SDL.h:69:0,
from testgamecontroller.c:19:
testgamecontroller.c: In function 'main':
testgamecontroller.c:296:132: warning: comparison between pointer and integer
SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
^
/usr/include/SDL2/SDL_assert.h:143:19: note: in definition of macro 'SDL_enabled_assert'
while ( !(condition) ) { \
^
testgamecontroller.c:296:17: note: in expansion of macro 'SDL_assert'
SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
^
testgamecontroller.c:325:144: warning: comparison between pointer and integer
SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
^
/usr/include/SDL2/SDL_assert.h:143:19: note: in definition of macro 'SDL_enabled_assert'
while ( !(condition) ) { \
^
testgamecontroller.c:325:29: note: in expansion of macro 'SDL_assert'
SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
^
/tmp/ccipRq1s.o: In function `main':
testgamecontroller.c:(.text+0x8ea): undefined reference to `SDL_GameControllerFromInstanceID'
testgamecontroller.c:(.text+0xa0e): undefined reference to `SDL_GameControllerFromInstanceID'
collect2: error: ld returned 1 exit status
So then I tried to run ./configure && make instead:
$ ./configure
checking build system type... armv7l-unknown-linux-gnueabihf
checking host system type... armv7l-unknown-linux-gnueabihf
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for an ANSI C-conforming const... yes
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for SDL... yes
checking how to run the C preprocessor... gcc -E
checking for X... libraries , headers
checking for OpenGL support... yes
checking for OpenGL ES support... no
checking for OpenGL ES2 support... yes
checking for TTF_Init in -lSDL2_ttf... yes
configure: creating ./config.status
config.status: creating Makefile
$ make
gcc -o checkkeys checkkeys.c -g -O2 -D_REENTRANT -I/usr/include/SDL2 -DHAVE_OPENGLES2 -DHAVE_OPENGL -DHAVE_SDL_TTF -g -lSDL2_test -lSDL2
gcc -o loopwave loopwave.c -g -O2 -D_REENTRANT -I/usr/include/SDL2 -DHAVE_OPENGLES2 -DHAVE_OPENGL -DHAVE_SDL_TTF -g -lSDL2_test -lSDL2
gcc -o loopwavequeue loopwavequeue.c -g -O2 -D_REENTRANT -I/usr/include/SDL2 -DHAVE_OPENGLES2 -DHAVE_OPENGL -DHAVE_SDL_TTF -g -lSDL2_test -lSDL2
/tmp/ccdYXqs4.o: In function `loop':
/home/chip/stash/SDL2-2.0.4/test/loopwavequeue.c:63: undefined reference to `SDL_GetQueuedAudioSize'
/home/chip/stash/SDL2-2.0.4/test/loopwavequeue.c:66: undefined reference to `SDL_QueueAudio'
collect2: error: ld returned 1 exit status
Makefile:78: recipe for target 'loopwavequeue' failed
make: *** [loopwavequeue] Error 1
I'm not sure why it is failing to compile and how to move past these errors.
Update: Thanks again to #genpfault, installing the latest version of SDL (2.0.4) from source, instead of using version 2.0.2 that was available as a package, fixed my compiling issues.
Now when I run the controller test script, on my Linux machine, I see this:
2016-06-29 12:59:05.588 a.out[64297:8754739] INFO: There are 0 game controller(s) attached (0 joystick(s))
However, when I run it on my Mac I see this:
2016-06-29 12:59:25.688 a.out[64303:8755040] INFO: Joystick 0: USB,2-axis 8-button gamepad (guid 83050000000000006020000000000000)
2016-06-29 12:59:25.690 a.out[64303:8755040] INFO: There are 0 game controller(s) attached (1 joystick(s))
What could be different about the Linux environment? Again, the same controller works in other programs on this same Linux machine.
Update: I found that the device is detected:
$ cat /proc/bus/input/devices
...
I: Bus=0003 Vendor=0583 Product=2060 Version=0110
N: Name="USB,2-axis 8-button gamepad "
P: Phys=usb-1c14400.usb-1/input0
S: Sysfs=/devices/platform/soc#01c00000/1c14400.usb/usb2/2-1/2-1:1.0/0003:0583:2060.0003/input/input5
U: Uniq=
H: Handlers=js0 event2
B: PROP=0
B: EV=1b
B: KEY=ff 0 0 0 0 0 0 0 0 0
B: ABS=3
B: MSC=10
However, I'm not sure why SDL is not detecting it.
I'm getting started with SDL -- that is, I have no experience and am basically just trying to get something to compile at this point.
I have a basic program:
#include "sdl/SDL.h"
int main(){
// Fire up SDL, this starts all subsystems; audio video etc.
if ( SDL_Init(SDL_INIT_EVERYTHING) < 0 ) {
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
// Now Shut it down
atexit(SDL_Quit);
return 0;
}
And I have this which I'm typing into the terminal:
g++ 'sdl-config --cflags --libs' -o sdltest sdltest.cpp
where sdltest.cpp is the name of the file.
This gives me the error:
g++: error: stl-config --cflags --libs: No such file or directory
Now, previously I have (I think) installed SDL like so:
sudo apt-get install libsdl2-dev
The issue might have to do with a faulty installation -- this might not be the package I was supposed to install, or I might be completely forgetting a step here.
I'm using Ubuntu, and compiling using g++, if it wasn't apparent from context.
When I try compiling the file
#include "SDL2\SDL.h"
int main( int argc, char* argv[] )
{
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Quit SDL
SDL_Quit();
return 0;
}
--an example from the SDL wiki--on the command line with
g++ -o SDL_Test.exe SDL_Test.cpp -lmingw32 -lSDLmain -lSDL
I get an error that says my computer cannot find -lSDLmain and -lSDL. Without the library things, it has trouble interpreting the functions.
I think the problem has something to do with the -l things, but I have no idea what they do....
My computer is 64-bit, if that makes a difference. I copied the x84_64-mingw32 bin, include, and lib into the C:\MinGW versions.
I would mostly just like an explicite solution to my problem, but if you could try explaining the -l things and other - things, that would be awesome.
-::- Answered by greatwolf in chat: turns out I was using 32-bit MinGW with 64-bit SDL files; I just needed to replace the 64-bit files with the 32-bit versions. Also, I had to direct the compiler to my SDL2.dll file. End compile command was g++ -o SDL_Test.exe SDL_Test.cpp -LC:\MinGW\lib -lmingw32 -lSDL2main C:\MinGW\bin\SDL2.dll.
You've got to make sure that you specify the appropriate search path for libraries using the -L compiler flag. Otherwise it won't know where to look for linking.
I'm trying to compile this code:
#include "SDL/SDL.h"
int main(void) {
SDL_Surface *Hello = NULL;
SDL_Surface *Screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
return 0;
}
But it happens that the compiler says that:
undefined reference to SDL_Init
I dont know why this is happening. I'm using Debian Mint and Code::Blocks. Could you Help me?
It looks like you haven't got -lSDL on your link line.
sdl-config returns the compile and link flags for your installation of SDL.
Assuming the program is sdl.cpp
g++ -o sdl `sdl-config --cflags` sdl.cpp `sdl-config --libs`
Should give you the correct flags.
Go to project and then build options and select your project name.
Now go to the linker setting and type the following lines in the Other Linker options textbox:
-lSDLmain
-lSDL
SDL also requires command line arguments in the main function so you should change
int main(void)
to
int main(int argc, char **argv)
Now compile your project and it should work.
What flags do I need to add to g++ in order to compile code using allegro 5? I tried
g++ allegro5test.cpp -o allegro5test `allegro-config --libs`
but that is not working. I'm using ubuntu 11.04. I installed allegro 5 using the instructions at http://wiki.allegro.cc/index.php?title=Install_Allegro5_From_SVN/Linux/Debian
I tried:
g++ allegro5test.cpp -o allegro5test `allegro-config --cflags --libs`
And it also gives a bunch of undefined errors, like: undefined reference to `al_install_system'
allegro-config --cflags --libs outputs:
-I/usr/local/include
-L/usr/local/lib -lalleg
So you successfully installed allegro5 on your system from the SVN. One thing you should know is that this build doesn't come with allegro-config. If you have it on your system it means you have previously installed allegro4.
allegro5 brings many changes, including different initialization procedures, library and function names.
Here's a hello world application for new version:
#include <stdio.h>
#include <allegro5/allegro.h>
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}
Notice how the command to compile this application refers to another include directory and library names, which are different from the previous version of allegro:
g++ hello.cpp -o hello -I/usr/include/allegro5 -L/usr/lib -lallegro
Allegro 5 uses pkg-config.
pkg-config --libs allegro-5.0 allegro_image-5.0
And so on for each library you are using.