libctru/citro3d - Is there an optimal way to make my code wait?

Discussion in '3DS - Homebrew Development and Emulators' started by titoEarly, Oct 22, 2018.

  1. titoEarly
    OP

    titoEarly Member

    Newcomer
    1
    Jan 12, 2016
    Hey there! I'm making my own game and I'm using citro3d/citro2d. I'm using hidKeysHeld() in order to update some graphics depending on which button the user is holding. The thing is, it's too fast and I want to slow it down a bit. I would like to make sure the buttons are being held for like 500 ms and then proceed with the code. I haven't figured a nice way to do so, though. What I'm doing at the moment is using svcSleepThread(500000000) but I'm also monitoring the CPU usage with C3D_GetProcessingTime() and it increases dramatically from 4% to 300%. Do you know any workaround that would do better than what I'm currently doing? Thanks a lot!
     
  2. StuntHacks

    StuntHacks Member

    Newcomer
    2
    Jan 19, 2017
    Austria
    Vienna
    For what you're doing, a frame-counter (or, if you need to be more precise, a tick-counter), would be the best option. You can check for when the button is pressed with `hidKeysDown` and if that's the case, check whether they are still held with `hidKeysHeld`. If they are still held, increase the frame counter by 1 and execute the action once the frame-counter reaches 30 (i.e., 500ms).
     
    titoEarly likes this.
  3. titoEarly
    OP

    titoEarly Member

    Newcomer
    1
    Jan 12, 2016
    Thanks! That really helped. So this is what I am doing:

    Code:
    int frame = 0;
    
    while (aptMainLoop()) {
        hidScanInput();
        u32 kHeld = hidKeysHeld();
    
        if (kHeld & KEY_UP) {
            if (frame >= MAX_FRAME) {
                // do something ...
                frame = 0;
            }
            else frame++;
        }
    
        // ...
    }
    It works the way I want it to work and CPU seems to be doing fine, but I'm not too sure if it's safe to assume it'll always behave the same way. I mean, does it always take the same time to count up to MAX_FRAME? :unsure:
     
  4. catlover007

    catlover007 GBAtemp Regular

    Member
    6
    Oct 23, 2015
    Germany
    yes and no. As long you have vsync enabled or any other kind of frame cap, this approach works. But e.g. if you miss your 60 FPS target, everything is going to slow down. That's why you're better off by not counting frames but the durations of frames. You can use these functions to accomplish this: https://github.com/smealum/ctrulib/blob/master/libctru/include/3ds/os.h#L147-L168

    This article is also a classic read on this subject:
    https://gafferongames.com/post/fix_your_timestep/
     
    Last edited by catlover007, Oct 23, 2018
    titoEarly likes this.
  5. titoEarly
    OP

    titoEarly Member

    Newcomer
    1
    Jan 12, 2016
    Thank you guys, got it working using the tick counter!
     
    catlover007 likes this.
Loading...