Jitter/catchup correction?

Discussion in 'Supercard SDK' started by spinal_cord, Apr 11, 2011.

Apr 11, 2011

Jitter/catchup correction? by spinal_cord at 1:12 PM (3,507 Views / 0 Likes) 11 replies

  1. spinal_cord
    OP

    Member spinal_cord Knows his stuff

    Joined:
    Jul 21, 2007
    Messages:
    2,871
    Location:
    somewhere
    Country:
    United Kingdom
    I was talking a little while ago to Bass about this, surely some other people have noticed also. Sometimes, depending on what you're trying to do with the DSTwo, it seems as though it just can't keep up. Even trying different speed settings makes no difference, it's as though something is stopping the DSTwo from working, then suddenly it will speed up to get back to where it should be.
    Bass mentioned one way to remedy this situation was to use, um, I can't remember, a timer/delay of some sort (could you post that little hint here Bass?) to keep everything moving along.

    Does anyone have any other (or even the same [​IMG]) hints to prevent this sort of thing from happening?
     
  2. CannonFoddr

    Member CannonFoddr Regular GBATemp Lurker

    Joined:
    Sep 23, 2006
    Messages:
    4,106
    Location:
    Sitting by computer
    Country:
    United Kingdom
    Actually I did notice this on iMenu 'page flipping' - but just thought it was part of your programming [​IMG] (it's something I could live with though so never mentioned it)

    I would guess it depends on WHAT is causing the jitter/catchup problem
    > IF the problem is happening with key presses - then the idea of a 'keypress delay' seems like a good idea

    > However, If the jitter is because of some kind of 'buffer overflow' (I'm going way back on this idea - I think it was originally something to do with 'Serial Printer buffers' or something like that) & the DS2 has to do all in the buffer before clearing it to accept any more key-presses
    - then the problem is with the buffer & may have to be reduced (so that it's cleared quicker) or made bigger (to allow more key-presses to be stored) somehow...
    ... thinking about this - It might even be a 'buffer UNDER-flow' - the buffer is too small & can't store all the inputs it's getting at once.

    > If it's the CPU just can't keep up with the Input's it's getting - then somehow the CPU need speeding up (unlikely) OR the input need slowing down somehow (which seems to point toward a delay needed inserted somehow)

    As you know, Spinal, I don't class myself as a programmer (although I did dabble many years ago) so what I've said could be total b***s*** - a lot has changed since I last did any type of programming [​IMG]
     
  3. BassAceGold

    Member BassAceGold Testicles

    Joined:
    Aug 14, 2006
    Messages:
    494
    Country:
    Canada
    I believe the Jitter/catchup might be caused by the low bandwidth in the slot 1 itself when sending frames to the DS to be drawn.
    -If you are using flip method 1 or 2 with ds2_flipsScreen, the whole system will wait until the frame is rendered before continuing (2 is slower than 1 due to duplicates of the frame being sent with method 2 to fill up both buffers).
    -If you use method 0, the system will initiate the transfer and allow your program to continue whether the frame is drawn or not. Method 0 may cause screen tearing though.

    A possible way to get a quick response would be to add a frame limiter while using method 0 for ds2_flipScreen. That way, while a frame isn't needed to draw, the transfer can fully complete 1 frame before another frame is called without too much tearing.

    BAGplug switches between rendering methods in various portions of the program and uses a frame limiter for updating the screens which seems to achieve somewhat decent performance.

    *Note*Updating both screens at once will instantly cut your fps in half, so try to avoid doing that if possible.
     
  4. Rydian

    Member Rydian Resident Furvert™

    Joined:
    Feb 4, 2010
    Messages:
    27,883
    Location:
    Cave Entrance, Watching Cyan Write Letters
    Country:
    United States
  5. spinal_cord
    OP

    Member spinal_cord Knows his stuff

    Joined:
    Jul 21, 2007
    Messages:
    2,871
    Location:
    somewhere
    Country:
    United Kingdom
    The only reliable way I have managed to prevent the slow down/stuttering is to use method 2 to update the screen and a much higher cpu rate [​IMG] It's a shame for such a simple game to suck up the power like that, but oh well...
     
  6. Pate

    Member Pate GBAtemp Regular

    Joined:
    Dec 23, 2010
    Messages:
    108
    Country:
    Finland
    Sorry I haven't been following this subforum for a while.. Yeah, I have been fighting with the key reading (or "stuck key") problem on and off, but I haven't had problems with the screen updating speed. I have been using a screen update method somewhat similar to the method 2, I am calling the update_buf() method directly and skipping the whole ds2_flipscreen() method call.

    Btw, I got some code snippets a while ago from the SC SDK people, which I'm not sure if I have posted them here.. Here is what the update_buf and ds2_flipScreen routines look like, in case you are wondering.

    Code:
    int update_buf(int bufnum)
    {
    ÂÂÂÂint ret = -1;
    ÂÂÂÂif (pmain_buf->buf_st_list[bufnum].isused == 0)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂioctl(MP4_fd, 0xb, bufnum);
    ÂÂÂÂÂÂÂÂret = 0;
    ÂÂÂÂ}
    
    ÂÂÂÂreturn ret;
    }
    
    /*
    *ÂÂ Flush data of video buffer to screen
    */
    void ds2_flipScreen(enum SCREEN_ID screen_num, int done)
    {
    ÂÂÂÂunsigned int i;
    ÂÂÂÂint buf_handle;
    
    ÂÂÂÂif(UP_SCREEN == screen_num || DUAL == screen_num)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂupdate_buf(up_screen_handle);
    
    _do_up:
    ÂÂÂÂÂÂÂÂbuf_handle = get_video_up_buf();
    ÂÂÂÂÂÂÂÂif(buf_handle >= 0)
    ÂÂÂÂÂÂÂÂ{
    ÂÂÂÂÂÂÂÂÂÂÂÂif(2 == done) {
    ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂwhile(check_video_up_buf());
    ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturn;ÂÂÂÂ//Not switch, for GUI convenience
    ÂÂÂÂÂÂÂÂÂÂÂÂ}
    
    ÂÂÂÂÂÂÂÂÂÂÂÂup_screen_handle = buf_handle;
    ÂÂÂÂÂÂÂÂÂÂÂÂup_screen_addr = (void*)get_buf_from_bufnum(buf_handle);
    ÂÂÂÂÂÂÂÂ} else if (done)
    ÂÂÂÂÂÂÂÂ{
    ÂÂÂÂÂÂÂÂÂÂÂÂgoto _do_up;
    ÂÂÂÂÂÂÂÂ}
    ÂÂÂÂ}
    
    ÂÂÂÂif(DOWN_SCREEN == screen_num || DUAL_SCREEN == screen_num)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂupdate_buf(down_screen_handle);
    
    _do_down:
    ÂÂÂÂÂÂÂÂbuf_handle = get_video_down_buf();
    ÂÂÂÂÂÂÂÂif(buf_handle >= 0)
    ÂÂÂÂÂÂÂÂ{
    ÂÂÂÂÂÂÂÂÂÂÂÂif(2 == done) {
    ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂwhile(check_video_down_buf());
    ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturn;ÂÂÂÂ//Not switch, for GUI convenience
    ÂÂÂÂÂÂÂÂÂÂÂÂ}
    
    ÂÂÂÂÂÂÂÂÂÂÂÂdown_screen_handle = buf_handle;
    ÂÂÂÂÂÂÂÂÂÂÂÂdown_screen_addr = (void*)get_buf_from_bufnum(buf_handle);
    ÂÂÂÂÂÂÂÂ} else if (done)
    ÂÂÂÂÂÂÂÂ{
    ÂÂÂÂÂÂÂÂÂÂÂÂgoto _do_down;
    ÂÂÂÂÂÂÂÂ}
    ÂÂÂÂ}
    }
    The ds2_flipScreen is just a stupid wrapper over the update_buf() (especially in a situation where you want to update the same buffer over and over).

    Pate
     
  7. Coto

    Member Coto GBAtemp Addict

    Joined:
    Jun 4, 2010
    Messages:
    2,278
    Country:
    Chile
    You mean ds2_flipscreen() wastes cpu cycles ? update_buff() seem to handle buf_handle() activity per cycle, at least once buf_handle() refreshes, hence ds2_flipscreen() checks for available data inside vram everytime it is being called? just a guess...
     
  8. Pate

    Member Pate GBAtemp Regular

    Joined:
    Dec 23, 2010
    Messages:
    108
    Country:
    Finland
    Well, the problem (at least for my purposes) with the ds2_flipScreen is that there is no option to update the same buffer WITHOUT waiting for the buffer to get refreshed. In DS2x86 I first check whether the buffer is free (and skip the update for this frame if not), then write the data to the buffer, and then call update_buf(), so that I don't waste CPU cycles spinlooping on "while(check_video_up_buf());".

    Here are the struct definitions, by the way. I am calling the routines and checking the pmain_buf from ASM code, so I haven't actually used these, but these would be needed in C code (in case you want to bypass the ds2_flipScreen() function in your own code).

    Code:
    enum {
    ÂÂÂÂbuf_video_up_0= 0,
    ÂÂÂÂbuf_video_up_1,
    ÂÂÂÂbuf_video_down_0,
    ÂÂÂÂbuf_video_down_1,
    ÂÂÂÂbuf_audio_0,
    ÂÂÂÂbuf_audio_1,
    ÂÂÂÂbuf_c0_set,
    ÂÂÂÂbuf_max_num
    };
    
    struct buf_st 
    {
    ÂÂÂÂunsigned int isused;
    ÂÂÂÂunsigned int offset;
    ÂÂÂÂunsigned int len;
    ÂÂÂÂunsigned int use_len;
    ÂÂÂÂunsigned int nds_max_len;
    ÂÂÂÂunsigned int nds_cmd;
    ÂÂÂÂunsigned int type;
    ÂÂÂÂ
    //ÂÂÂÂunsigned int cpuaddr;//added in ds2sdk_v0.13beta
    }; 
    
    struct _rtc{
    ÂÂÂÂvolatile unsigned char year;ÂÂÂÂÂÂÂÂ//add 2000 to get 4 digit year
    ÂÂÂÂvolatile unsigned char month;ÂÂÂÂÂÂÂÂ//1 to 12
    ÂÂÂÂvolatile unsigned char day;ÂÂÂÂÂÂÂÂ//1 to (days in month)
    
    ÂÂÂÂvolatile unsigned char weekday;ÂÂÂÂ// day of week
    ÂÂÂÂvolatile unsigned char hours;ÂÂÂÂÂÂÂÂ//0 to 11 for AM, 52 to 63 for PM
    ÂÂÂÂvolatile unsigned char minutes;ÂÂÂÂ//0 to 59
    ÂÂÂÂvolatile unsigned char seconds;ÂÂÂÂ//0 to 59
    };
    
    struct _key_buf 
    {
    ÂÂÂÂunsigned short int key;
    ÂÂÂÂunsigned short int x;
    ÂÂÂÂunsigned short int y;
    };
    
    struct main_buf
    {
    ÂÂÂÂunsigned int key_buf_offset;ÂÂ
    ÂÂÂÂunsigned int key_buf_len;
    ÂÂÂÂunsigned int key_write_num;
    ÂÂÂÂunsigned int key_read_num;
    
    ÂÂÂÂstruct buf_st buf_st_list[0x10];
    ÂÂÂÂunsigned int tempbuff;
    ÂÂÂÂunsigned int tempbuff_len;
    
    ÂÂÂÂunsigned int nds_video_up_w;
    ÂÂÂÂunsigned int nds_video_up_r;
    ÂÂÂÂunsigned int nds_video_down_w;
    ÂÂÂÂunsigned int nds_video_down_r;
    ÂÂÂÂunsigned int nds_audio_w;
    ÂÂÂÂunsigned int nds_audio_r;
    ÂÂÂÂstruct _rtc nds_rtc;
    
    ÂÂÂÂunsigned int nds_iqe_list_c0[0x10][512/4];
    };
     
  9. Coto

    Member Coto GBAtemp Addict

    Joined:
    Jun 4, 2010
    Messages:
    2,278
    Country:
    Chile
    Pate, thank you =). I´m actually doing some test on DS. I have experience with C/++ but not on DS ARM architecture. If i ever have some troubles coding C i´ll get in contact with you haha
     
  10. alekmaul

    Member alekmaul GBAtemp Regular

    Joined:
    Nov 5, 2002
    Messages:
    104
    Location:
    Blois
    Country:
    France
    He Pate, do you have other code example from SDK that can help us to do some things for DSTWo [​IMG] ?
    Currently, i have lot's of issues with vecx porting, it seems that gcc compilation does not work like for DS native SDK (same code works fine for DS/Wii, not for DSTWO [​IMG] ) ...
    For example, what are the options you're using for GCC in your makefiles ?
    And thanks for dsupdate code sharing, will help me to improve Mame4All DSTWO !
     
  11. Pate

    Member Pate GBAtemp Regular

    Joined:
    Dec 23, 2010
    Messages:
    108
    Country:
    Finland
    Hello alekmaul! [​IMG]

    This is the remainder of the code snippet I got from the SDK, this is not all that interesting, but here it is for completeness's sake:

    Code:
    extern int MP4_fd;
    extern int MP4_buf;
    
    u32 get_buf_from_bufnum(int num)
    {
    ÂÂÂÂreturn (pmain_buf->buf_st_list[num].offset + MP4_buf);
    }
    
    int check_video_up_buf(void)
    {
    ÂÂÂÂint i = 0;
    
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_up_0].isused != 0) i += 1;
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_up_1].isused != 0) i += 1;
    
    ÂÂÂÂreturn i;
    }
    
    int get_video_up_buf(void)
    {
    ÂÂÂÂint ret = -1;
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_up_0].isused == 0)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂret= buf_video_up_0;
    ÂÂÂÂ}
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_up_1].isused == 0)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂret= buf_video_up_1;
    ÂÂÂÂ}
    
    ÂÂÂÂreturn ret;
    }
    
    int check_video_down_buf(void)
    {
    ÂÂÂÂint i= 0;
    
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_down_0].isused != 0) i += 1;
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_down_1].isused != 0) i += 1;
    
    ÂÂÂÂreturn i;
    }
    
    int get_video_down_buf(void)
    {
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_down_0].isused == 0)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂreturn buf_video_down_0;
    ÂÂÂÂ}
    ÂÂÂÂif (pmain_buf->buf_st_list[buf_video_down_1].isused == 0)
    ÂÂÂÂ{
    ÂÂÂÂÂÂÂÂreturn buf_video_down_1;
    ÂÂÂÂ}
    ÂÂÂÂreturn -1;
    }
    As for the GCC options, here's what I use for DS2x86:

    CODECFLAGS := -mips32 -O3 -mno-abicalls -fno-pic -fno-builtin \
    ÂÂÂÂÂÂ -fno-exceptions -ffunction-sections -mlong-calls\
    ÂÂÂÂÂÂ -fomit-frame-pointer -msoft-float -G 4

    .c.o:
    ÂÂÂÂ$(CC) $(CFLAGS) $(INC) -MD -o $@ -c $<
    ÂÂÂÂ@cp $*.d $*.P; \
    ÂÂÂÂsed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
    ÂÂÂÂÂÂÂÂÂÂ-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
    ÂÂÂÂrm -f $*.d

    .cpp.o:
    ÂÂÂÂ$(CC) $(CFLAGS) $(INC) -MD -fno-rtti -o $@ -c $<
    ÂÂÂÂ@cp $*.d $*.P; \
    ÂÂÂÂsed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
    ÂÂÂÂÂÂÂÂÂÂ-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
    ÂÂÂÂrm -f $*.d

    I don't have any object-oriented features in my cpp modules (as in no classes), I use them just for some of the nice cpp features like being able to declare variables on the fly. I mostly code in ASM, so the C and cpp modules are there just as an interface to the SDK.

    I can post my whole Makefile if you think it will be useful, though I have to admit I am no Makefile guru, so much of the stuff in my Makefile I have only a vague idea of what it does. [​IMG]

    Pate
     
  12. alekmaul

    Member alekmaul GBAtemp Regular

    Joined:
    Nov 5, 2002
    Messages:
    104
    Location:
    Blois
    Country:
    France
    Hi Pate,
    Thanks a lot, I'm using same thing in my makefile for my Vectrex / A2600 emulators.
    Strange that i do not have same result for DSTWO SDK and WII devkitpro version with same source code ... Need to investigate more ...
    And thanks for code sharing.
     

Share This Page