audetto / AppleWin

Apple II emulator for Linux
GNU General Public License v2.0
47 stars 12 forks source link

sa2: Glitched screen #110

Open wn2000 opened 1 year ago

wn2000 commented 1 year ago

EDIT: the original issue of glitched screen has been resolved by not doing a stride copy from the pixel buffer to the texture, and instead just using the entire pixel buffer to create the texture. The black border can still be removed by rendering a subarea of the texture. But I actually liked the look with the black border.

I built the sa2 version for an arm SoC (RK3328 chip). The environment is GLES2 and KMSDRM, no X. The display is completely glitched as shown below. It looks like many smaller frames wrapping around. Any settings I can adjust to make it show up properly?

image

wn2000 commented 1 year ago

Hmm my board might not support the GL_UNPACK_ROW_LENGTH_EXT extension, so copying a subarea of the framebuffer to the texture may have failed. Added the --no-imgui argument to use the SDL_Renderer based implementation and the display is fine now. But there's another problem: It is fairly slow. CPU usage on one core quickly goes to 100%. As a comparison, running in RetroArch the CPU usage is about 60%. I even changed the SDL texture to SDL_TEXTUREACESS_STREAMING but that did not help either. This chip should be on par with a pi3 in terms of performance, so not sure what might be the problem.

audetto commented 12 months ago

GL_UNPACK_ROW_LENGTH_EXT: the other SDL driver (--no-imgui) does it with a shader, but I am not good enough to apply one. You should change the screen sizes and draw the black borders too, so you don't need the extension. It is done in this area https://github.com/audetto/AppleWin/blob/284825796973f2079d1d9c4654450bde098aa23c/source/frontends/sdl/imgui/sdlimguiframe.cpp#L130

SDL_TEXTUREACESS_STREAMING never made any improvement in my experience.

The performance depends entirely on GLES, even on a Pi it used to be very poor till they did something to improve it, and the only thing we use it for is to display a texture.

I once wrote this https://github.com/audetto/SDL_Demo to test the speed of the texture. See if it still working and use it to test, or try different things. If you find other software doing high FPS for texture, you could try to learn how they do it.

But do this as well: make sure the fast disk speed is disabled, then put a disk in, run it for 30 seconds and show me the full output. And maybe do it for ImGui and without.

And comment out lines 131, 136 in main.cpp.

wn2000 commented 12 months ago

Thanks I’ll try to do the fast disk disabling test. Can you show me the complete command line to do that? I’m using the donkey Kong dsk file for testing.

Regarding GLES performance, there shouldn’t be a problem on my chip. We can do Dreamcast, PSP and other accelerated GPU rendering with good performance. I’m still playing around with the code. At one time it showed that “Event” is taking 100+ ms per frame. I tried to comment out the audio output (which didn’t work anyway on the sa2 version), and it seemed to hang at the title screen.

audetto commented 12 months ago

re audio: I realise it cannot run without audio, I will have to make a change. for now comment out line 194 of dsound.cpp and accept the pop up message.

Disable enhanced speed: edit ~/.applewin/applewin.conf with

[Configuration]
Enhance Disk Speed=0

Command line add this --fixed-speed it will simplify things

Show me the output.

These are other tests to do on your hardware: https://github.com/ocornut/imgui/tree/master/examples/example_sdl2_opengl2 https://github.com/ocornut/imgui/tree/master/examples/example_sdl2_opengl3

wn2000 commented 12 months ago

Here is the log. BTW is there a hotkey to exit the emulator? I cannot exit and had to insert a statement to let it quit after 500 frames.

*** Logging started: Fri Sep  8 19:44:39 2023
RegLoadValue: sa2\geometry - width = ??
RegLoadValue: sa2\geometry - height = ??
RegLoadValue: sa2\geometry - x = ??
RegLoadValue: sa2\geometry - y = ??
FindResource: resource 'APPLEWIN.ICO' not found.
MBCardMgr::ctor() g_bDisableDirectSound=0, g_bDisableDirectSoundMockingboard=0
RegSaveValue: Configuration\Slot 6 - Card type = 1
RegSaveString: Configuration\Slot 6 - Last Disk Image 1 = /media/usb0/content/retrofe/collections/Apple II/roms/DonkeyKong.dsk
RegSaveString: Preferences - Starting Directory = /media/usb0/content/retrofe/collections/Apple II/roms/
Init: S6, DoDiskInsert(D1), res=1
Initialisation
RegLoadValue: Configuration - Apple2 Type = ??
RegLoadValue: Configuration - Computer Emulation = ??
RegLoadValue: Configuration - CPU Type = ??
RegLoadValue: Configuration - Joystick0 Emu Type v3 = ??
RegLoadValue: Configuration - Joystick0 Emu Type = ??
RegLoadValue: Configuration - Joystick 0 Emulation = ??
RegLoadValue: Configuration - Joystick1 Emu Type v3 = ??
RegLoadValue: Configuration - Joystick1 Emu Type = ??
RegLoadValue: Configuration - Joystick 1 Emulation = ??
RegLoadValue: Configuration\Slot : - Game I/O type = ??
RegLoadValue: Configuration - Sound Emulation = ??
RegLoadValue: Configuration - Emulation Speed = ??
RegLoadValue: Configuration - Video Emulation = ??
RegLoadValue: Configuration - Video Style = ??
RegLoadValue: Configuration - Monochrome Color = ??
RegLoadValue: Configuration - Video Refresh Rate = ??
RegLoadValue: Configuration - Full-screen show subunit status = ??
RegLoadValue: Configuration - Show Disk II Status = ??
RegLoadValue: Configuration - The Freeze's F8 Rom = ??
RegLoadValue: Configuration - Speaker Volume = ??
RegLoadValue: Configuration - Mockingboard Volume = ??
RegLoadValue: Configuration - Save State On Exit = ??
RegLoadValue: Configuration - PDL X-Trim = ??
RegLoadValue: Configuration - PDL Y-Trim = ??
RegLoadValue: Configuration - ScrollLock Toggle = ??
RegLoadValue: Configuration - Joystick Cursor Control = ??
RegLoadValue: Configuration - Autofire = ??
RegLoadValue: Configuration - Swap buttons 0 and 1 = ??
RegLoadValue: Configuration - Joystick Centering Control = ??
RegLoadValue: Configuration - Mouse crosshair = ??
RegLoadValue: Configuration - Mouse restrict to window = ??
RegLoadValue: Configuration\Slot 0 - Card type = 17
RegLoadValue: Configuration\Slot 1 - Card type = ??
RegLoadValue: Configuration\Slot 2 - Card type = ??
RegLoadValue: Configuration\Slot 3 - Card type = 0
RegLoadValue: Configuration\Slot 4 - Card type = ??
RegLoadValue: Configuration - Slot 4 = ??
RegLoadValue: Configuration\Slot 5 - Card type = ??
RegLoadValue: Configuration - Slot 5 = ??
RegLoadValue: Configuration\Slot 6 - Card type = 1
RegLoadValue: Configuration\Slot 7 - Card type = ??
RegLoadValue: Configuration - Harddisk Enable = ??
RegLoadString: Configuration - Save State Filename = ??
RegLoadString: Preferences - HDV Starting Directory = ??
RegLoadString: Preferences - Starting Directory = /media/usb0/content/retrofe/collections/Apple II/roms/
RegLoadString: Configuration\Slot 6 - Last Disk Image 1 = /media/usb0/content/retrofe/collections/Apple II/roms/DonkeyKong.dsk
RegLoadString: Configuration\Slot 6 - Last Disk Image 2 = ??
RegLoadValue: Configuration - Enhance Disk Speed = 0
RegLoadValue: Configuration\Slot 1 - Dump to printer = ??
RegLoadValue: Configuration\Slot 1 - Convert printer encoding for clones = ??
RegLoadValue: Configuration\Slot 1 - Filter unprintable characters = ??
RegLoadValue: Configuration\Slot 1 - Append to printer file = ??
RegLoadString: Configuration\Slot 1 - Printer Filename = ??
RegLoadValue: Configuration\Slot 1 - Printer idle limit = ??
RegLoadValue: Configuration - Window Scale = ??
RegLoadValue: Configuration - Confirm Reboot = ??
Number of sound devices = 0
DSCreate failed for all sound devices
Spkr Config: soundtype = 1 (WAVE)
Spkr_DSInit: g_bDSAvailable=0
Spkr_DSInit(), res=0
RegSaveValue: Configuration\Slot 0 - Card type = 17
RegSaveValue: Configuration\Slot Auxiliary - Card type = 13
RegLoadString: Configuration\Slot 3 - Uthernet Interface =
RegLoadValue: Configuration\Slot 3 - Uthernet Virtual DNS = ??
Time from emulation reboot until first $C000 access: 5 msec
*** Logging ended

And the stdout output:

SDL Video driver: KMSDRM
SDL Audio driver: alsa
SDL Game Controller: Control deck
arm_release_ver of this libMali is r7p0-00rel0, rk_so_ver is '1', built at '14:45:10', on 'Apr  2 2020'.
IMGUI_VERSION: 1.89.8 WIP
GL_VENDOR: ARM
GL_RENDERER: Mali-450 MP
GL_VERSION: OpenGL ES 2.0
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00
Default GL swap interval: 0
Video refresh rate: 60 Hz, 16.67 ms
Post Color Buffer Success
Global:  total =   17095.08 ms, mean =   17095.08 ms, std =       0.00 ms, n =      1
Frame:   total =   17094.08 ms, mean =      34.12 ms, std =       5.99 ms, n =    501
Screen:  total =    3720.82 ms, mean =       7.43 ms, std =       5.94 ms, n =    501
Events:  total =      18.78 ms, mean =       0.04 ms, std =       0.01 ms, n =    501
CPU:     total =   13347.85 ms, mean =      26.64 ms, std =       0.62 ms, n =    501
audetto commented 12 months ago

Now you can with Shift-F2

2 things require attention

  1. Default GL swap interval: 0 the emulator is heavily reliant on OpenGL's vsync, while yours does not seem to have it. But you should have got an error, so maybe it works but it is not the default. Try to add --gl-swap=1 and report back.
  2. Your CPU takes 26ms per frame. This is not OpenGL but pure CPU, so we need to see if it is true. Skip it, by commenting out ExecuteOneFrame in main.cpp.

Ideally you want to see the Frame's mean time at 16.67ms. If the bottleneck is really the CPU, then you will have to profile the code (and check in a RELEASE build as well).

Try another thing as well: --headless --fixed-speed (with and without CPU actually running).

Copy only the output to the console, ignore the logfile.

audetto commented 12 months ago

If you run with --no-imgui you can select different SDL renderers via --sdl-driver=X I have these

SDL: 3 rendering drivers
 0: opengl
 1: opengles2
 2: software
Active driver (-1): opengl
 SDL_RENDERER_SOFTWARE: 0
 SDL_RENDERER_ACCELERATED: 1
 SDL_RENDERER_PRESENTVSYNC: 1
 SDL_RENDERER_TARGETTEXTURE: 1

Try them all and gather some information.

audetto commented 12 months ago

And finally, to see the maximum FPS achievable do this

sa2 --fixed-speed --gl-swap=0

open the About window and read the FPS and it should really be above 60 to run well.

wn2000 commented 12 months ago

And finally, to see the maximum FPS achievable do this

sa2 --fixed-speed --gl-swap=0

open the About window and read the FPS and it should really be above 60 to run well.

I realized that I messed up my build env. I was building without any -O flag. After doing -O3 it runs very well now (despite the problem below). I've been using --fixed-speed --gl-swap 0 in my tests, that's why you saw "default GL swap interval 0". With that I got 73fps. Removing --gl-swap 0 I got a solid 60fps. So all is good.

Now the problems:

  1. Sound still does not work in sa2. Have to comment out dsound.cpp:194 to avoid a hang in the title screen.
  2. Shift-F2 does not quit the emulator.

Once these two issues are resolved this would be awesome!

audetto commented 12 months ago

So, both things you will have to debug.

Look in the pressKeyDown function and try to figure out what key code is generated by Shift-F2.

For audio, it is important that the callback is called to empty the audio buffer. See what happens.

wn2000 commented 12 months ago

Look in the pressKeyDown function and try to figure out what key code is generated by Shift-F2.

Found the issue:

https://github.com/audetto/AppleWin/blob/eb550570203aa6a5fe82701959f0b582a4b78624/source/frontends/sdl/imgui/sdlimguiframe.cpp#L248-L257

So the key down/up events are swallowed by ImGui and never passed to SDLFrame::ProcessSingleEvent().

Is there a reason to do that?

Anyway, is there a way to exit by gamepad? Like pressing SELECT twice like in the libretro version?

audetto commented 12 months ago

That code only matters if a ImGui window is active. Click on the apple video and they will be processed.

I can add something like libretto.

wn2000 commented 12 months ago

That code only matters if a ImGui window is active. Click on the apple video and they will be processed.

I can add something like libretto.

Well I commented out line 248 and SHIFT+F2 worked like expected.

ProcessSingleEvent() is a virtual function. So this line: https://github.com/audetto/AppleWin/blob/eb550570203aa6a5fe82701959f0b582a4b78624/source/frontends/sdl/sdlframe.cpp#L252

actually calls SDLImGuiFrame::ProcessSingleEvent(), which swallows the key down event.

What do you mean by "click on the Apple video"? For context I'm using this with a keyboard and a gamepad only, no mouse. Even with a mouse for some reason the SDL KMS driver does not show the mouse pointer, so it'll be very difficult to use.

EDIT: hmmm I think what you mean is that only when the ImGui settings window is active should io.WantCaptureKeyboard be true. But in my case, io.WantCaptureKeyboard is true even when no settings window is active.

wn2000 commented 12 months ago

For audio, it is important that the callback is called to empty the audio buffer. See what happens.

I found out why my audio did not work in sa2:

https://github.com/audetto/AppleWin/blob/eb550570203aa6a5fe82701959f0b582a4b78624/source/frontends/sdl/sdirectsound.cpp#L213

This opens the default audio device. In my system, the default audio device is a loopback device on top of the real physical device. It does not support mono channel so it returned 0. Once I change nullptr to the name of the physical audio device it starts to work.

So two suggestions:

  1. Handle errors of this call. At a minimum print out an error message.
  2. Add a setting to specify an audio device. I know RetroArch and some standalone emulators have that option.
audetto commented 12 months ago

Thanks. I will do both.

audetto commented 12 months ago

Just pushed a couple of things

  1. --audio-device NAME to select the audio device
  2. SELECT twice in 1 sec to quit

If audio does not work well, there are still issues, but I need more work to fix them.

wn2000 commented 12 months ago

Just pushed a couple of things

  1. --audio-device NAME to select the audio device
  2. SELECT twice in 1 sec to quit

If audio does not work well, there are still issues, but I need more work to fix them.

Thanks! Both work pretty well in sa2. Audio is good after selecting the hardware device through --audio-device.

My only wish now is to see a "press again to quit" message as in ra2 :-)

audetto commented 12 months ago

I will see how much code I need to write to do it.