Timing is incorrect when using compat/unix

Help
2012-08-15
2013-01-01
  • Zoltán Böszörményi

    Hi,

    I am using the distro-packaged FUSE emulator in Fedora 17.
    However, when the original 48K Spectrum is selected, the speed
    setting in the General Options is not honored. E.g. 100 or 95%
    is set and after loading a game, like Bruce Lee Last Ninja 2 from
    WOS, the displayed speed rate is jumping between 320-460%
    in the bottom-right corner of the FUSE window and the game
    is (obviously) unplayably fast.

    The situation when selecting the 128K Spectrum is only slightly
    better. Setting the speed rate to 100% shows the same symptom
    as with the 48K Spectrum. But when I select 95%, it behaves very
    a lot better, but some games don't work with the 128K Spectrum.

    I have experimented with other speed rates on the 48K Sinclair
    variant, too. When I set it to 30%, it seemed to honor the setting,
    at least for about a minute while I tried Bruce Lee in slow motion.
    However, when I set it to 80%, eventually the emulation speed
    went up to 280-300%.

    An interesting detail is that after loading the Bruce Lee game itself,
    the loading screen is still shown for a short time before the first
    game credit screen appears. During that time, the speed rating
    shown by FUSE is in the 3000-5000% range.

    My computer has an AMD FX-8120 CPU with very big L2 and L3
    caches and variable speed between 1.4 and 3.1GHz. The machine
    is mainly used for work, I only occasionally play vintage games
    via emulators. Can this CPU explain the strange behaviour?

    I have finally recompiled fuse-emulator using ./configure -with-sdl and
    this appeared during ./configure:

    checking which timer routines to use… SDL

    The timing with the SDL-using Fuse-emulator is now perfect.
    It seems the coding in compat/unix/timer.c  is buggy.

     
  • Fredrick Meunier

    Could you try the following patch and report on the results?

    Index: compat/unix/timer.c
    ===================================================================
    --- compat/unix/timer.c (revision 4729)
    +++ compat/unix/timer.c (working copy)
    @@ -28,6 +28,7 @@
     #include <errno.h>
     #include <string.h>
     #include <sys/time.h>
    +#include <time.h>
     #include <unistd.h>
    
     #include "compat.h"
    @@ -51,5 +53,21 @@
     void
     compat_timer_sleep( int ms )
     {
    -  usleep( ms * 1000 );
    +  struct timespec req, rem;
    +  int err;
    +  req.tv_sec = ms / 1000;
    +  req.tv_nsec = (ms % 1000) * 1000000;
    +  while( (req.tv_sec != 0) || (req.tv_nsec != 0) ) {
    +    if( nanosleep( &req, &rem ) == 0 )
    +      break;
    +    err = errno;
    +    /* Interrupted; continue */
    +    if( err == EINTR ) {
    +      req.tv_sec = rem.tv_sec;
    +      req.tv_nsec = rem.tv_nsec;
    +    }
    +    /* Unhandleable error (EFAULT (bad pointer), EINVAL (bad timeval in
    +       tv_nsec), or ENOSYS (function not supported)) */
    +    break;
    +  }
     }
    
     
  • Sergio Baldoví

    Sergio Baldoví - 2012-08-15

    Hi Zoltán,

    >  Can this CPU explain the strange behaviour?

    I don't think so. Have you tried "fuse -no-sound"?

    I've experimented a similar error while testing new distros. I usually run fuse with alsa sound driver on pulseaudio via "ALSA plug-in". Sometimes works fine, sometimes speeds up the execution. The fastest workaround is disabling pulseaudio.

    If you are interested in knowing what is going wrong, I suggest getting this log:
    https://wiki.ubuntu.com/PulseAudio/Log

     
  • Zoltán Böszörményi

    Unfortunately the patch doesn't help when using the native timer and GTK UI. "fuse -no-sound" on the other hand does help. This patch below was needed on Fedora 17 to compile Fuse using -with-sdl.

    --- fuse-1.0.0.1/screenshot.c~  2011-01-12 22:36:28.000000000 +0100
    +++ fuse-1.0.0.1/screenshot.c   2012-08-15 09:22:47.160269225 +0200
    @@ -29,6 +29,8 @@
     #include <limits.h>
     #include <string.h>
    
    +#include <zlib.h>
    +
     #include <libspectrum.h>
    
     #include "display.h"
    
     
  • Zoltán Böszörményi

    The pulseaudio patch works with and without the previous compat/unix/timer.c change. Although the 4-5000% speed artifact is still present after loading the Buce Lee before the first credits screen appers but the in-game speed strictly sticks to 100%. I haven't noticed any speed problems in other games, I tried Atic Atac, Last Ninja and Rambo. Good work.

     
  • Sergio Baldoví

    Sergio Baldoví - 2012-08-17

    >Although the 4-5000% speed artifact is still present after loading the
    >Buce Lee before the first credits screen

    It seems to me that the fast-loading option is doing its job before stopping the tape. That's something unrelated to the audio system.

    I've tested a VM with a AC97 sound card that show a similar issue. Fuse use the standard ALSA routines. The pulseaudio log show lots of buffer underruns and seems that Fuse gets crazy trying to adjust the machine speed to the audio speed. snd_pcm_dump() show a buffer size of 1913, so I slightly increase the buffer:
    ./fuse -d verbose,buffer=2000

    Now Fuse runs reasonably well. There are no buffer underruns but the latency is noticeable, maybe due to running Fuse in a VM.

     
  • Fredrick Meunier

    I added some extra detail on what latency information I am hoping to see before committing the pulseaudio patch in a comment to https://sourceforge.net/tracker/?func=detail&atid=596651&aid=3144253&group_id=91293

    We really need someone with non-VM Linux and pulseaudio to give this a try so we can determine how well Fuse works with the patch to understand if it is good enough to commit (given it would probably quickly become the most used sound API for Fuse Linux installs).

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks