It is currently Thu Oct 19, 2017 10:31 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Aug 21, 2017 5:25 am 
Offline
User avatar

Joined: Mon Aug 21, 2017 4:47 am
Posts: 6
Image


Hello there, i hope my simple and newbie question is accepted here. This question is specific to Snes9x, but i think can be applied to most emulators that i'm aware of.

The snes is able to rotate, scale, shift palettes, shift hue, apply transparency, make the image looks brighter or darker, etc etc ... I guess emulators must support these functions to allow games to produce such outputs.

Also, as far as i'm concerned, most emulators work by the means of software blitting. Some might not, but in this thread i want to focus in the ones that work that way. In my old notebook at least it could not work by shaders, for example. So, unless i'm mistaken here, i'll take this fact for granted.

The thing is, as a little experiment, i tried to reproduce some of these effects via software too. In the case of snes9x i got a steady 30-50% of cpu usage. But, to my surprise, when i try to replicate some of these basic actions, it ends up consuming all the cpu. This makes me think that i'm doing something very wrong.

The question then is, how do emulators process images to end up being that fast? Do they avoid float point operations? I'm interested in knowing this, maybe have a look at some code, because to me is no different than magic. Thanks for your time.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 5:44 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
I do not understand what you're asking.

I did not reverse-engineer Seiken Densetsu 3 or anything, but the most likely case is that they use two separate, pre-calculated palettes to display during day and during night. It is extremely unlikely the game and/or the emulator does any calculation to do this.

For some games, like maybe the earlier games on the platform, they could use colour subtraction (called "Transparency effects" in SNES9x) to get such effects done (with less flexibility in their result). This is obviously NOT what SD3 uses, as you can see the windows lighting, something that wouldn't be thinkable using colour subtraction only. SNES9x allows dynamic disabling of "Transparency effects" so you should be able to tell immediately which games uses it and which don't.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 6:08 am 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 192
They're asking how emulators produce 60fps images with transparency, scaling, rotation, etc. so quickly on PC hardware without hardware acceleration, not how SNES games do it (with the SNES' hardware acceleration, of course).

I've never written an emulator myself, so I'm afraid I could only guess.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 7:46 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
Emulators don't use floating-point math, for one thing. (Neither does the compositor in the actual S-PPU.) And they use an API optimized for speed rather than one optimized for genericity and colorimetric accuracy. It's not getpixel()/putpixel(); it's get a reference to an array of integers representing a row of pixels and write to that array.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 8:09 am 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 192
Yeah, as part of telling you why your code is slow it'd help if we could see your code :)


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 9:18 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
Yes, it's quite possible to write software renderers that run well / fast. Emulators were even doing this back in the 90s on much less powerful machines.

If you've got to draw 100,000 or 1,000,000 pixels per frame, though, it's still usually something you need to approach with care, even with today's power. The sheer amount of pixels to draw puts a huge multiplier on any inefficiency in your code for it.

...and if writing something that's not an emulator, it's probably better to stick to stuff you can do with a modern GPU if you can.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 10:37 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
rainwarrior wrote:
...and if writing something that's not an emulator, it's probably better to stick to stuff you can do with a modern GPU if you can.

What's the best practice for palette swapping per team color in modern pixel shaders?


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 10:42 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
tepples wrote:
rainwarrior wrote:
...and if writing something that's not an emulator, it's probably better to stick to stuff you can do with a modern GPU if you can.

What's the best practice for palette swapping per team color in modern pixel shaders?

There are a lot of ways to approach this problem, but one way to do it is to have a sprite layer containing just the coloured parts of the uniform in white/greyscale and then using a vertex colour (or shader constant) as a multiplier.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 11:08 am 
Offline
User avatar

Joined: Mon Aug 21, 2017 4:47 am
Posts: 6
tepples wrote:
Emulators don't use floating-point math, for one thing.

Well, that makes me respect emu-devs more. I need to have a look at how they accomplish that.
adam_smasher wrote:
Yeah, as part of telling you why your code is slow it'd help if we could see your code :)

There are a lot of quite generic functions. For example, to make the screen look darker (a common operation with snes games), i do:
Code:
//f in 0.0 - 1.0
//Pseudocode, each channel is actually a byte.
for each pixel:
  pixel.red *= f;
  pixel.green *= f;
  pixel.blue *= f;

However this operation in the whole screen is quite costly.
rainwarrior wrote:
...and if writing something that's not an emulator, it's probably better to stick to stuff you can do with a modern GPU if you can.

Yes, with GPU you can accomplish much, but also the learning curve is huge. Just by looking these games emulated you can tell all the great effects you can accomplish without knowing opengl/vulcan


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 12:22 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
OneQuestionPlease wrote:
There are a lot of quite generic functions. For example, to make the screen look darker (a common operation with snes games), i do:
Code:
//f in 0.0 - 1.0
//Pseudocode, each channel is actually a byte.
for each pixel:
  pixel.red *= f;
  pixel.green *= f;
  pixel.blue *= f;

However this operation in the whole screen is quite costly.

It doesn't need to be done on the entire screen. Games change just 256 values (the palette), and everything else on the screen refers to that palette. And because division by 256 is so fast, games will scale things by multiplying by a fraction 1/256 through 255/256 by first multiplying by 1 through 255 and then dividing by 256. There are even shortcuts for that multiplication.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 1:02 pm 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 192
The SNES has a screen brightness register; that's what most games would probably used to darken the screen.

Nevertheless, the idea is the same: the emulator precomputes the darkened palette and uses it to draw the screen rather than doing a floating point multiply on each pixel after-the-fact.


Last edited by adam_smasher on Mon Aug 21, 2017 1:36 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 1:29 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
Oh, and
OneQuestionPlease wrote:
The question then is, how do emulators process images to end up being that fast? Do they avoid float point operations?

I am not extremely familiar with the hardware, but I'm pretty sure floating point is not slower on PCs than fixed point. It is slower in embedded systems without an FPU. FPUs has been incorporated in PCs since much earlier.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 1:33 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
Bregalad wrote:
I am not extremely familiar with the hardware, but I'm pretty sure floating point is not slower on PCs than fixed point. It is slower in embedded systems without an FPU. FPUs has been incorporated in PCs since much earlier.

It's slower in a lot of ways, maybe not so much on a per-instruction basis anymore, but when the whole pipeline is involved it's still pretty significant.

SIMD instructions can help a lot with floating point efficiency too, but that's a whole field in itself.


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 12:02 am 
Offline
User avatar

Joined: Mon Aug 21, 2017 4:47 am
Posts: 6
tepples wrote:
And because division by 256 is so fast, games will scale things by multiplying by a fraction 1/256 through 255/256 by first multiplying by 1 through 255 and then dividing by 256

I didn't realize that, and after a small adjustment the difference is now notable. I could not think the float/int difference would be that high. Now i find my self looking at places where to apply this optimization.
adam_smasher wrote:
The SNES has a screen brightness register; that's what most games would probably used to darken the screen.

But i guess that at some point you have to apply the brightness anyway.
tepples wrote:
Games change just 256 values (the palette), and everything else on the screen refers to that palette.

adam_smasher wrote:
Nevertheless, the idea is the same: the emulator precomputes the darkened palette and uses it to draw the screen rather than doing a floating point multiply on each pixel after-the-fact.

This makes a lot of sense, i count the number of colors on the picture above and is roughly 100, very low and common in pixel art. Having to process just 100 is a lot faster than computing each pixel. But thinking about it, might be nightmarish to apply transparency, isn't it? I imagine the workflow to be:
Code:
for each color in palette2:
  if it exists in palette1: update index in image 2
  else: add new color and update index in image 2

  for each pixel in image2:
    copy index to image1

Image
Now, if you have to take into account the new colors produced by alpha blending, having to locate every new color (probably it didn't exist before) can be a slow operation.
Also, does the snes emply a different palette for every sprite/tile?


Top
 Profile  
 
PostPosted: Tue Aug 22, 2017 5:02 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
The S-PPU has 8 palettes for backgrounds and 8 palettes for sprites. A palette can be assigned to each 8x8 pixel tile or each sprite. Blending on the S-PPU uses the formula (r1+r2), (r1-r2), or (r1+r2)/2. See Please consolidate all info.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group