C - SDL2 window crash from simple animation loop - c

I am currently learning to use SDL2 in C and encountered a problem from which I couldn't find a solution so far
I am trying to run a simple 2 frames animation loop in the middle of the screen, but after a seemingly set amount of loops the window stops responding
while (1)
{
SDL_RenderClear(window->renderer);
test->o_update(sheet, test);
SDL_RenderCopy(window->renderer, sheet->texture, &test->frame, &test->pos);
SDL_RenderPresent(window->renderer);
SDL_Delay(16);
}
The update function updates the coordinates on the sheet of the SDL_rect named "frame" in the test structure, so that it switches to the next frame every 30 frame. Every frame I SDL_RenderCopy, and SDL_RenderPresent to update the screen. Is there something blatantly wrong in my way of doing things ?

The issue came from the lack of wait/poll on SDL events, the process eventually stops responding in those cases.

Related

Is there a way to render my Termbox game and handle keyboard events in the same loop?

I'm having issues with my termbox program rendering the screen and handling keyboard events. Recently, I've finished a C and C++ class at my university. I wanted to demonstrate my knowledge by creating a basic Snake game. The first steps, I wanted to get a simple render loop going and have a block of text simply move leftward and exit the game upon reaching the 0th x-coordinate. The issue arises when continuing to the next render frame, because the game is running single-threaded the next frame won't be rendered until a new keyboard event is accepted. Ordinarily, I would expect the game to continue rendering regardless of events, new events affecting the new frame.
As for potential solutions, I thought about using multiple threads to run the game loop and handle keyboard events. But, I think this would be overkill for such a small problem, there are likely easier alternatives than having to manage multiple threads for a simple snake game.
As for the code, it's as simple as:
while (1)
{
tb_clear();
draw(gameState);
tb_present();
struct tb_event event;
tb_poll_event(&event);
if (event.ch == 'q')
break;
}
After digging through the header file a bit more I found a method which doesn't wait forever.
/* Wait for an event up to 'timeout' milliseconds and fill the 'event'
* structure with it, when the event is available. Returns the type of the
* event (one of TB_EVENT_* constants) or -1 if there was an error or 0 in case
* there were no event during 'timeout' period.
*/
SO_IMPORT int tb_peek_event(struct tb_event *event, int timeout);

Why doesn't cairo draw on first iteration of loop?

I'm working on a library that creates transparent X windows and uses cairo to draw on them. There is an event loop implemented in the main thread, while the drawing operations take place in a separate thread within a loop. The latter looks like this
while (self->_running) {
PyGILState_Release(gstate);
usleep(1000); // Sleep 1 ms
gstate = PyGILState_Ensure();
if (self->_expiry <= gettime()) {
draw(self, args_tuple); // All the cairo code is in here
self->_expiry += interval;
interval = self->interval;
}
}
The event loop calls XNextEvent periodically to trap key/button presses only. The window is mapped before the new UI thread is started from the main thread.
When the interval between iterations on the UI thread (the self->inteval value above) is large (order of seconds), the window stays transparent on the first iteration of the loop, and it only gets painted on from the second iteration onward. Calling draw right before the while loop doesn't help, unless there is a pause of some milliseconds in between calls to draw. For example, if I put interval = 25 right before the while loop, then the second call to draw paints on the window in most of the executions of the application implementing this code.
Things that I have tried:
cairo_surface_flush and XFlush right after draw don't seem to work
Sending an Expose event doesn't seem to help either.
How can I make sure that my loop starts painting on the window from the first iteration?
What I'm missing is the ExposureMask flag in the call to XSelectInput. With this flag set, one then has to look for Expose events in the event loop with the following pattern:
switch (e.type) {
case Expose:
if (e.xexpose.count == 0) {
BaseCanvas__redraw(canvas);
}
return;
}
The redraw operation doesn't need to be the full set of draw operations. Having modified the cairo context, it is enough to repaint it on the destination with no more than this
void
BaseCanvas__redraw(BaseCanvas * self) {
cairo_save(self->context);
cairo_set_operator(self->context, CAIRO_OPERATOR_SOURCE);
cairo_paint(self->context);
cairo_restore(self->context);
}
To me it looks like you are mapping the window and then immediately starting a thread that tries to draw to the window. Thus, if you try to draw before the window manager actually made the window visible, your drawing goes nowhere. If the window manager wins the race and the window actually becomes visible before your draw, the drawing actually works.
Your own answer is not an answer to your question. The question is "why does it stay transparent in the first iteration?" while your answer is (basically) "Don't use threads, just do all drawing in the main loop".
(Of course, handling Expose events is the right thing to do, but that's not what the question asked.)

How to avoid timer stacking

I'm sorry if his question has already been asked in some way.
I'm currently re-writing a vibration driver in a Linux kernel. The reason why I changed it was due to overly strong vibrations caused by gaining a specific velocity of the vibration motor. To work that around I've implemented a PWM like controller that simply stops the motor at a specific time before reaching it's max acceleration, finally it keeps repeating this action.
There is one big issue that is mainly noticeable when using the keyboard. If the vibrator gets toggled too often in a very short time, the timer tends to stack up times, causing lag and vibration delays. This flaw can be easily achieved when typing multiple keys at once.
To demonstrate you this event visually I created a small graph.
The red area indicates timer overlap. The overlap between vibration 1 and 2 causes a delay for the second vibration, moving it out of place.
My main idea to prevent this issue is to merge vibrations into one if the previous vibration hasn't finished yet. For instance vibration 2 would simply join vibration 1.
Another way would be to simply use a single vibration for stacked vibrations, for instance, vibration 2 could simply use the last remaining bit of vibration 1. Why would this work? Well because the vibration controller that I've implemented only applies to times under 100ms, meaning vibration time differences would not be noticeable if one was to spam to keystrokes at once, instead both keystrokes should form and share single vibration.
Finally to my question, how could I make a function check itself it it's being called again. Or at least add a time for the function to check if keystrokes are being spammed multiple times in a short period?
int foo ()
{
static foo_counter;
if(foo_counter)
{
// If function has been called again
}
return(0);
foo_counter++;
}

Camera will not move in OpenGL

I am having problems with using a camera in OpenGL/freeGLUT. Here is my code:
http://pastebin.com/VCi3Bjq5
(For some reason, when I paste the code into the code feature on this site, it gives extremely weird output.)
As far as I can tell this should rotate the camera when arrow keys are pressed - but it does nothing. It also seems that even the initial camera position is wrong. Any clue why this is?
The display function is only called once. You need to either set an idle function with glutIdleFunc() or tell GLUT that the display function must be called again with glutPostRedisplay().

Implementing pacman in c, ghost movement

I am creating a pacman in c and currently I am usisng a single thread for each ghost and each ghost represents a '#' but when I run it all the screen gets full of ghosts and not all the ghosts move just one or two.
Im using this logic
create a struct of 5 ghost, each ghost contains the x,y position.
create an array of 5 threads and each thread implements one ghost
each ghost moves randomly on the screen, for each space that it moves I print
a space in the old position and then I print a '#' in the new position.
Could you provide me please an example of how to implement the movement of the ghost,
or the implementation Im doing is the correct way?
Thank you
One thread per agent is not a very common approach to building games. It quickly becomes unworkable for large scenes. The conventional solution is to define a state machine representing a ghost, with some kind of "advance" method that gives it a chance to adjust its internal state to the next time quantum. Create multiple instances of this state machine, and call all their "advance" methods on each iteration of the game loop. All of this can happen in a single thread.
There's quite a bit more to it than this, but it'll get you started.
Trying to update the screen simultaneously from several threads requires a mutex around the screen update code.

Resources