Beta Snes9X4D4P - Another New Build, Now With Hi Res And New Rom Picker


So, in keeping with my "can't keep focused on one project at a time" (;)) I added hq2x style antialiasing to the renderer. New PND here, modified source files (because I never did figure out how to create diff files) here. Ivanovic or Science or Skeezix or whomever, feel free to do with the code as you wish. It was mostly pulled from the hqx project which was in turn based on Maxim Stepin's work, and then modified to work entirely with 16 bit colour data.
Enhancements: hq2x blending, obviously. Activate it in the menu. Also added 's' as a hotkey: press it during gameplay to switch between smooth and jagged. If I get around to it, I'll see if I can combine the hq2x and hq3x into an hq2/3x for smoothed stretch play. Now that there's three options to choose from, I also modified the menu slightly to allow you to scroll forward and backward between the options. Not that it was obvious, what with only two options, but previously it only scrolled forward.
You will need to turn on auto frame skipping: the anti-aliasing effectively cuts the framerate to 1/3, which is very unfortunate. Even overclocked to 800 I was still barely getting 30fps. I suspect there's room to use the DSP here, though I don't know how.
Most people probably won't use this; the effect is incredibly subtle at only 2x magnification. I remember 3x and 4x being a lot more pronounced, a lot better looking, but you can still see some improvements in places. There may be some tweaking that can be done to produce even better output but I wouldn't count on it.
 
jonlad1 said:
So blending isnt working with scaling at the moment?
It does 2x scaling/blending, but not the 3x2 widescreen scaling yet. I need to mush up the interpolation algorithms a bit for that, and it could take a while to get it right.

SiENcE said:
uhm no diff.
Yeah, sorry :(
I'll try and figure out how to do it and get you a diff today.
 
Last edited by a moderator:
WizardStan said:
jonlad1 said:
So blending isnt working with scaling at the moment?
It does 2x scaling/blending, but not the 3x2 widescreen scaling yet. I need to mush up the interpolation algorithms a bit for that, and it could take a while to get it right.

SiENcE said:
uhm no diff.
Yeah, sorry :(
I'll try and figure out how to do it and get you a diff today.
Since you most likely work with the svn checkout and hopefully are under linux, thus got a terminal as well as commandline svn:
cd folder/with/svn/checkout
svn diff > my.patch

This should result in the diff compared to "mainline" svn being in the file "my.patch". Feel free how to name the file. It should just work this way and yeah, this diff/patch can easily be applied to a working repository. If you want to see the output either open the file or just call "svn diff" without additional parameters.
 
Last edited by a moderator:
Surprised it reduces render speed so much!

One of these days someone will add some hw accel to SDL for some speedups; stuff like the scale-up should be done on the hw anyway (not hard to add anyway). And a lot of the blitting can be changed to ASM.. but stuff like hq2x really shoudl be done in ASM too, but thats way too much effort for al us lazy bodies :)

jeff
 
skeezix said:
but stuff like hq2x really shoudl be done in ASM too, but thats way too much effort for al us lazy bodies :)

ljp did have ASM filters, may be tinnus could bring these back to life
 
Last edited by a moderator:
Good point on SDL Skeezix, I think we're all forgetting about the improvements that should be made to it. Do you think I should start a new thread on it?

The speed decrease for hq2x doesn't quite surprise me.. looking at the code it appears it can easily take over 150 cycles per pixel before you even factor in cache misses and branch mispredictions. But I think it can be improved substantially with NEON.

These are my observations:

- The compare absolute difference part is taking a large chunk of the work. In NEON you can perform absolute difference operation in one instruction, vabd, and over 8-bit quantities you can perform this for 4 pixels simultaneously. The compare can be done in parallel as well, producing 16 masks for four pixels. Y, U, and V comparisons can be combined with a second 32-bit parallel compare, producing 4 masks, and reduced to a 1-bit LSB indicator with an 8-bit shift. This can be done twice for 8 pixels, then the masks combined with a vsli (vector shift left and insert) instruction (8 2-bit flags over 32-bits) and condensed from 128-bit to 8-bit with two vsli instructions. All of these instructions issue in 1 cycle, with the exception of the vsli's which take 2 for 128-bit. You likely will have to do multiple output pixels per-iteration to hide latency of the operations. All in all, it reduces the operation time from likely over 100 cycles down to something like 15.
- Those 4 possible Diff functions in the switch cases are either already done on previous pixels or will be done on future ones (they're the same as the one done against the center pixel). So it's better to perform all of the Diffs ahead of time in a buffer so it can be referenced. The ideal will be to store no more than 3 scanlines in a ring buffer that stays one scanline ahead. This will also make it easier to unroll the loops to perform multiple pixels per iteration as mentioned above.
- In NEON an 8x8->16 + 16 multiply and accumulate can be done over 8 values per cycle. All of the pixel functions are of the form ((a * p5) + (b * px) + (c * by)) >> 4, where a, b, and c are some coefficient, p5 is the center pixel, and px and py are some adjacent pixels. The third multiply/add step is only necessary sometimes, but I think it'll be cheaper to do it all the time. The switch cases then load px and py for four pixels, and multiply coefficients. Outside of the switch, the actual three multiplications occur for the four pixels, followed by a shift + narrow, and a compact back to 16-bits.
- I'm not sure if this is a good idea or not, but possibly at least worth trying: at a slight additional cost per-pixel, those four possible diff values can be sampled and added to the switch state, making it over 12 bits instead of 8 bits. This will remove conditionals from the cases that have the tests, which will take out branch misprediction penalties. It'll add to the number of unique cases, but it'll make the individual cases where it does smaller.
- If the above is done it also may be possible to use a LUT instead of a switch, to load up pixel values px/py and coefficient values b and c, on a 4-pixel basis. px and py will be 3-bit values and the coefficients will be 5-bit values, so a single 64-bit load can get everything for 4 pixels. The only way I know of to select values is using vtbl/vtbx - unfortunately that only selects bytes (and it isn't that fast, but for this purpose it's still reasonable). To get around that you have to either work in a data stream that's component parallel and work with at least 2 output pixels at a time, or you have to generate byte indexes by expanding the 32-bit value to 128-bit (use wide from 8-bit to 16-bit to 32-bit) then increment it by 0x03020100 in each vector. Eliminating the switch will reduce its branch mispredict costs, which will be more often than usual, and will make it so components don't need to be loaded individually. But all things considered, I doubt it'd actually be faster.

All this should hopefully bring performance down to a few dozen cycles per pixel instead of hundreds.
 
I'm looking around to see if anyone has already done an SSE2 optimized hq2x or somesuch. I haven't found just that, but I did find an hq2x.cpp from blargg, for bsnes. The code does a lot of pretty interesting things. I recommend trying it instead.

EDIT: On second thought, I think it's going to run pretty expensive on Cortex-A8 due to have four switches per pixel instead of 1. The trick with the diff, on the other hand, is quite clever.

Still worth trying and comparing.

But NEON will win you more ;)
 
SNES9x4p refuses to run games on my pandora...
The screen just goes black after starting a game and then it does nothing.

Does anyone have an idea how to fix this?
 
Please paste the content of /tmp/pndrun*something_with_snes9x*. In there some error message or the likes should be shown.
 
Ivanovic said:
Please paste the content of /tmp/pndrun*something_with_snes9x*. In there some error message or the likes should be shown.
Code:
rm: cannot remove `/tmp/cpuspeed': No such file or directory
none on /mnt/utmp/snes9x.skeezix.alpha type aufs (rw,si=628bba17,noplink)
Union already mounted
[------------------------------]{ App start }[---------------------------------]
ROM filename is /media/SD1/pandora/appdata/snes9x.skeezix.alpha/snes/Adventures of Batman & Robin, The (U).smc.7z
PWD pre-run /mnt/utmp/snes9x.skeezix.alpha
cat: args.txt: No such file or directory
No ROM file header found.
"V?:?c?-r??K?????U???L" [bad checksum] LoROM, C[-------------------------------]{ App end }[----------------------------------]
cleanup done
to 50hz LCD
Rate: 32000, Buffer size: 512, 16-bit: yes, Stereo: yes, Encoded: no
SupportHiRes = FALSE
Starting PickleLauncher.
Running from './picklelauncher'
Loading config.
Initializing SDL.
SDL initialized.
LoadImage -> Could not load image: Couldn't open images/button_edit.png at path='images/button_edit.png'
LoadImage -> Could not load image: Couldn't open images/button_options.png at path='images/button_options.png'
Loading profile.
Closing TTF fonts.
Quitting TTF.
Quitting SDL.
Quitting PickleLauncher.
[-------------------------------]{ App end }[----------------------------------]
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount failed, didnt clean up. Process still using this FS :
 4124 ?        Ss     0:00 /bin/bash /usr/pandora/scripts/pnd_run.sh -p /media/SD1/pandora/menu//snes9x4p_20101028.pnd -e ../../../usr/bin/arora -a ard README_Snes9x4X.txt -b snes9x.skeezix.alpha -c 600
 4162 ?        Sl     0:18 ./../../../usr/bin/arora ard README_Snes9x4X.txt
Here you go
 
Last edited by a moderator:
FragMage said:
Ivanovic said:
Please paste the content of /tmp/pndrun*something_with_snes9x*. In there some error message or the likes should be shown.
Code:
rm: cannot remove `/tmp/cpuspeed': No such file or directory
none on /mnt/utmp/snes9x.skeezix.alpha type aufs (rw,si=628bba17,noplink)
Union already mounted
[------------------------------]{ App start }[---------------------------------]
ROM filename is /media/SD1/pandora/appdata/snes9x.skeezix.alpha/snes/Adventures of Batman & Robin, The (U).smc.7z
PWD pre-run /mnt/utmp/snes9x.skeezix.alpha
cat: args.txt: No such file or directory
No ROM file header found.
"V?:?c?-r??K?????U???L" [bad checksum] LoROM, C[-------------------------------]{ App end }[----------------------------------]
cleanup done
to 50hz LCD
Rate: 32000, Buffer size: 512, 16-bit: yes, Stereo: yes, Encoded: no
SupportHiRes = FALSE
Starting PickleLauncher.
Running from './picklelauncher'
Loading config.
Initializing SDL.
SDL initialized.
LoadImage -> Could not load image: Couldn't open images/button_edit.png at path='images/button_edit.png'
LoadImage -> Could not load image: Couldn't open images/button_options.png at path='images/button_options.png'
Loading profile.
Closing TTF fonts.
Quitting TTF.
Quitting SDL.
Quitting PickleLauncher.
[-------------------------------]{ App end }[----------------------------------]
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount failed, didnt clean up. Process still using this FS :
 4124 ?        Ss     0:00 /bin/bash /usr/pandora/scripts/pnd_run.sh -p /media/SD1/pandora/menu//snes9x4p_20101028.pnd -e ../../../usr/bin/arora -a ard README_Snes9x4X.txt -b snes9x.skeezix.alpha -c 600
 4162 ?        Sl     0:18 ./../../../usr/bin/arora ard README_Snes9x4X.txt
Here you go
Try to rename the rom or use a different rom. This line is *very* suspicious:
"V?:confused:c?-r??K?????U???L" [bad checksum] LoROM, C
 
Last edited by a moderator:
Ivanovic said:
FragMage said:
Ivanovic said:
Please paste the content of /tmp/pndrun*something_with_snes9x*. In there some error message or the likes should be shown.
Code:
rm: cannot remove `/tmp/cpuspeed': No such file or directory
none on /mnt/utmp/snes9x.skeezix.alpha type aufs (rw,si=628bba17,noplink)
Union already mounted
[------------------------------]{ App start }[---------------------------------]
ROM filename is /media/SD1/pandora/appdata/snes9x.skeezix.alpha/snes/Adventures of Batman & Robin, The (U).smc.7z
PWD pre-run /mnt/utmp/snes9x.skeezix.alpha
cat: args.txt: No such file or directory
No ROM file header found.
"V?:?c?-r??K?????U???L" [bad checksum] LoROM, C[-------------------------------]{ App end }[----------------------------------]
cleanup done
to 50hz LCD
Rate: 32000, Buffer size: 512, 16-bit: yes, Stereo: yes, Encoded: no
SupportHiRes = FALSE
Starting PickleLauncher.
Running from './picklelauncher'
Loading config.
Initializing SDL.
SDL initialized.
LoadImage -> Could not load image: Couldn't open images/button_edit.png at path='images/button_edit.png'
LoadImage -> Could not load image: Couldn't open images/button_options.png at path='images/button_options.png'
Loading profile.
Closing TTF fonts.
Quitting TTF.
Quitting SDL.
Quitting PickleLauncher.
[-------------------------------]{ App end }[----------------------------------]
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /mnt/utmp/snes9x.skeezix.alpha: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount failed, didnt clean up. Process still using this FS :
 4124 ?        Ss     0:00 /bin/bash /usr/pandora/scripts/pnd_run.sh -p /media/SD1/pandora/menu//snes9x4p_20101028.pnd -e ../../../usr/bin/arora -a ard README_Snes9x4X.txt -b snes9x.skeezix.alpha -c 600
 4162 ?        Sl     0:18 ./../../../usr/bin/arora ard README_Snes9x4X.txt
Here you go
Try to rename the rom or use a different rom. This line is *very* suspicious:
"V?:confused:c?-r??K?????U???L" [bad checksum] LoROM, C

I have tried about 10 different roms, and none of them work.
Might be possible that the roms I downloaded are all named wrong, I'll take a look
 
Last edited by a moderator:
Does snes9x even support 7zip compression? Have you tried uncompressing it and running the rom directly?
 
WizardStan said:
Does snes9x even support 7zip compression? Have you tried uncompressing it and running the rom directly?

It SHOULD support 7zip if only ONE file is in there - unless Ivanovic changed my script (or my script has an error, as I haven't tried 7zip myself ;))
 
Last edited:
Just noticed the nice comments about picklelauncher, thanks. Very glad everyone seems to like it.

Ive got some updates coming for it (hopefully done soon).
1. External commands i.e set the cpu speed type scripts
2. In-menu selectable options
3. Internal zip support

1 ans 2 are basically done and 3/4 of the way there.
 
Back
Top