Question

I am not a programmer or any of such, I am only someone interested in this stuff.

I have been trying to make myself an Xbox 360 Controller Mapper, translating controller key presses into simulated keyboard key presses. Reason is that I sincerely dislike the ones out there and one has to pay to get most of them. Promise, if I ever make it good enough that I like what I've produced, I will distribute it for everyone's use for free.

Anyway, I already have made a working command-line version, yet to be as friendly as I want it to be, but still does better what most would want from it even like this. One thing I have to ask though...

As I am not a programmer or any of sorts, I lack the teachings of the experienced, except for the ones that I had from the internet. But this one thing that I couldn't find: How to make proper breathing gaps for the programme during a loop? Maybe I should first ask, is it even right to make...

...
while ( 1 ) {
    if ( ( GetAsyncKeyState( keyID ) & 0x8000 ) == 0x8000 ) {
        /* do this, do that */
        break;
    }
    /* breathing */
}
...

... a structure like the one above?

I assumed and still assume that it is, since I have no idea how else would it be possible to catch the input from the user with this C language. It would be nice to know than to assume.

If so, then my main question is; how to give the programme the room for breathing, so that it won't stress the CPU much? In other words, how should I replace the /* breathing */ part above? I have been using Sleep( 20~25 );s all around, and my Task Manager simply displays 0% CPU usage all the time with that, even with Sleep( 5 )s actually...

Is it any bad to use Sleep? Is there any better option?

Was it helpful?

Solution

Here is a rather simple program demonstrating a game event loop using SDL2:

#include <SDL.h>
#include <stdio.h>

void on_render(SDL_Window* window, SDL_Renderer* renderer);

int main(int argc, char** argv)
{
    SDL_Window      *mainwindow = NULL;
    SDL_Renderer    *renderer = NULL;
    SDL_Event       event = { 0 };
    int             exit = 0;   // If 1, the event loop will break.

    // INITIALIZE SDL (VIDEO ONLY):
    if(SDL_Init(SDL_INIT_VIDEO) == -1) {
        printf("SDL_Init() failed with \"%s.\"", SDL_GetError());
        return 1;
    }

    // CREATE WINDOW:
    mainwindow = SDL_CreateWindow("SDL2 Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
    if(!mainwindow) {
        printf("SDL_CreateWindow() failed with \"%s.\"", SDL_GetError());
        return -1;
    }

    // CREATE RENDERER:
    renderer = SDL_CreateRenderer(mainwindow, -1, SDL_RENDERER_ACCELERATED);
    if(!renderer) {
        printf("SDL_CreateRenderer() failed with \"%s.\"", SDL_GetError());
        return -1;
    }

    // MAIN LOOP:
    while(!exit) {

        // EVENT LOOP:
        if(SDL_WaitEvent(&event)) {
            switch(event.type) {
            case SDL_QUIT:
                exit = 1;
                break;
            case SDL_KEYDOWN:
                if(event.key.keysym.sym == SDLK_ESCAPE) exit = 1;
                break;
            case SDL_WINDOWEVENT:
                switch(event.window.event) {
                case SDL_WINDOWEVENT_CLOSE:
                    exit = 1;
                    break;
                }
                break;
            default: break;
            }
        }

        // RENDER SCREEN:
        on_render(mainwindow, renderer);

        // SWAP BUFFERS TO DISPLAY:
        SDL_RenderPresent(renderer);
    }

    // CLEAN-UP:
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

    return 0;
}

void on_render(SDL_Window* window, SDL_Renderer* renderer)
{
    int rect_width = 300, rect_height = 300;
    SDL_Rect window_rect = { 0 };

    // CLEAR THE SCREEN WITH A BLUE COLOR:
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    SDL_RenderClear(renderer);

    // DRAW A RECTANGLE:
    SDL_GetWindowSize(window, &window_rect.w, &window_rect.h);

    SDL_Rect draw_rect = {
        (window_rect.x + (window_rect.w / 2) - (rect_width / 2)) - 1,
        (window_rect.y + (window_rect.h / 2) - (rect_height / 2)) - 1,
        rect_width + 2,
        rect_height + 2
    };

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &draw_rect);
}

Credit: Xeek on freenode wrote this for me when I went over to ask about event loops.

Now, if you aren't writing a game, perhaps you do not want to consume all of the CPU time, in which case a simple

usleep (1);

right before the end of the outermost while loop should cut it.

Using your code, here is an example (which happens to depend on having a POSIXy system (Linux, OSX, etc.):

// includes and defines
#include <unistd.h>     // usleep() is defined here
...

int main (int argc, char **argv) {
    // setup and stuff
    ...

    int exit = 0;
    while (!exit) {
        if ((GetAsyncKeyState(keyID) & 0x8000) == 0x8000) {
            // handle the input or whatever
            ...
        }

        // check if it is time to exit yet
        if (some exit condition) {
            exit = 1;
        }

        usleep (100);   // sleep for 100 us
    }

    // cleanup
    ...

    return 0;
}

EDIT:

us is microseconds, not milliseconds. Silly me :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top