fruit-bat / pico-zxspectrum

ZX Spectrum for Raspberry Pico Pi RP2040
475 stars 52 forks source link

Flickering sprites in some games. #70

Open ArnoldUK opened 1 year ago

ArnoldUK commented 1 year ago

I've had some time over the weekend to play around with the emulator and in some games, Ghosts n Goblins for example, display sprite flickering, although the game plays fine. I'm using the VGA out build BTW. Is this a known issue ?

I've noticed in the main.cpp code and the core1_main function that there is a comment in the code at this line:

if (y == 239) { // TODO use a const / get from vmode

Not quite sure what this means for what the 239 means either. I've also played around with changing the loop variable i in this code here: void __not_in_flash_func(main_loop)() if (!showMenu) { for (int i = 1; i < 100; ++i) { if (lastInterruptFrame != _frames) { lastInterruptFrame = _frames; zxSpectrum.interrupt(); } zxSpectrum.step(); } } else if (frames != _frames) { frames = _frames; picoDisplay.refresh(); } }

Didn't make much of a differnece though but setting too high or too low would crash the emulator.

fruit-bat commented 1 year ago

The 239 thing is looking for the last screen line. This increases the frame count which triggers the frame interrupt on the spectrum. It's a bit crude in terms of timing accuracy but very cheap on CPU cycles.

The flickering may be caused by the above but more likely by the frames being drawn at 60hz. There is no frame buffer so the encoder races the raster down the screen. This may not give the CPU enough time to draw the complete frame. I'm interested if changing the CPU speed to 4mhz makes it better or worse?

I'll take a look when I get a mo, but it may be tricky to sort.

ArnoldUK commented 1 year ago

Yes, changing the cpu speed to 4Mhz is a slight improvment but unmoderated and flickering issue is gone. Obviously, unmoderated is impossible for playing any games. I'm curious as to why this flickering is only visible in some games and not others ? Maybe I could add a small delay after the 239 check and see what happens.

fruit-bat commented 1 year ago

I'm guessing, but I suppose games that render a background then add the sprites afterwards suffer the worst.

fruit-bat commented 1 year ago

Delay sounds interesting. Also might be worth trying reducing 239 and see what happens. Although you hinted you have already tried that.

ArnoldUK commented 1 year ago

Interesting, not tried that so I will try 478 and see the effect. I was messing around with the for loop in the main_loop which was causing the emulator to freeze.

I've also added a few more features to the emulator which I will update in my repo when I can find time to tidy the code.

  1. Added option to load external ROMs
  2. Added extra built-in ROMs including Retroleum's DiagROM (not sure if this would be allowed or cause issues, I can remove it if so)
  3. Added an extra Menu item for managing quicksaves.
  4. Added an auto booting snapshot if exists on the SD-Card. Similar to Kiosk mode.
  5. Made keyboard funcions more compatible with the original spectrum keyboard.
  6. Graphical Menu...under construction. Download the UF2 firmware from my repo pico-zxspectrum-extras
fruit-bat commented 1 year ago

That all sounds very good. Please pull request when you get time.

Had another thought about the flickering. The unmoderated mode handles the audio input differently... The unmoderated CPU does not wait on the audio input FIFO. Maybe the audio input moderation runs too long without checking for the end of frame? Sort of a rhetorical, but what do you think?

ArnoldUK commented 1 year ago

Kind of makes sense but I would not know where to begin with that. Some of the emulation code is a bit too low level.

fruit-bat commented 1 year ago

Been having a play with this and it is quite mysterious. Having either moderator active causes flickering and does not seem related to having either the audio input/output enabled. I'll keep trying to figure it out.

fruit-bat commented 1 year ago

I think this is a problem with interrupt handling. The following in ZXSpectrum.h seems to sort the problem out...

  void interrupt() {
    z80_int(&_Z80, true);
    _Z80.int_line = false;
  }

Not sure if this is an issue with the Spectrum emulator or the Z80 emulation.

Needs a little testing if you have time. If it doesn't cause problems elsewhere I will add it to the main codebase.

ArnoldUK commented 1 year ago

Gave the code a test and that appears to have fixed the issue and not affected anything else. In the same code file ZXSpectrum.h I found a define named EAR_BITS_PER_STEP which I changed from 32 to 64 #define EAR_BITS_PER_STEP 64 that has also fixed some sound clicking in the speaker for beeper. May want to look at adding that also. Like I say, I have no idea what any of these statements are doing. Great work!

fruit-bat commented 1 year ago

Thanks for the feedback. I have pushed another tweak to main.cpp to move where the frame timing starts, which helps in some cases.

I tried raising EAR_BITS_PER_STEP but that caused the flickering to start again for me. Also, I don't get any cackle on the audio. I might need some more specific information to track that one down.

ArnoldUK commented 1 year ago

Ok, the EAR_BITS_PER_STEP might be some kind of placebo effect for me as I'm using some lame jumper wiring. I will revert it back and make some hard wired connections for testing as I'm working on breadboards.