Someone please explain this to me:
https://twitter.com/Masterjun3/status/9 ... 9170124800Replies in the thread that I found at least somewhat telling, although they made me question the technicalities even more:
https://twitter.com/Azurillkirby/status ... 2583364608Which prompted me to ask more or less "WTF?", to which I got answers which just amplified my "WTF?" even more, hence my thread on nesdev:
https://twitter.com/koitsu2009/status/9 ... 0267436032More verbosely explaining my thought process: I do not see how increasing the rendered resolution of SMW (since this is in an emulator, best I can tell) would at all cause Mario to "jitter". The SNES is a pixel-based system; there are no such thing as subpixels. While the
game engine may in fact calculate positions and movement at amounts that would equate to numbers with decimals (floating point), I do not see how increasing the resolution (i.e. scaling) has any relation to that. The only way I could see this happening is if someone wrote an emulator that somehow tied in to the game engine mechanics for rendering purposes, which doesn't even make it a SNES emulator at that point, but instead some kind of Frankenstein's monster of a horror.
So, can someone please explain this to me? While I get that there may be some >= and <= ranges for things like collision, I do not see how increasing visual resolution would cause said issue to manifest how it does -- because there are no such thing as subpixels on this console.
Educate me. Thanks!
Looks like Mario's fractional position is constantly increasing, but wall ejection makes him stay steady instead. If you increased the resolution AND multiplied out the fractional coordinates when placing the sprite, it would happen.
koitsu wrote:
The only way I could see this happening is if someone wrote an emulator that somehow tied in to the game engine mechanics for rendering purposes, which doesn't even make it a SNES emulator at that point, but instead some kind of Frankenstein's monster of a horror.
It sounds like you understand it perfectly though?
I don't think he's suggesting that you could do this with an emulator or anything. It's just a comment on the physics engine, with the fractional part of the position value visualized. That's my take, anyway...
Back when the Sonic 2 HD project started, people were debating whether to write a new engine from scratch or to just emulate the original and replace the graphics with HD vesions and use the fractional positions to make everything move smoothly. They went with a new engine, for various reasons.
93143 wrote:
I don't think he's suggesting that you could do this with an emulator or anything. It's just a comment on the physics engine, with the fractional part of the position value visualized. That's my take, anyway...
If that's the case -- just a pure visual representation of engine behaviour -- then yeah, OK. Same could have been accomplished with a Mario sprite overlayed on top of a line-drawn box. It makes the animation/GIF incredibly misleading, especially when used alongside the "subpixels". A follow up that says "SMW subpixels are not actual pixels, they're divisions of the pixel used purely for physics calculations" is equally as teeth-gritting.
It's no wonder the general populous have problems comprehending classic consoles. Sheesh.
So my second question is more for Dwedit but I suppose anyone could answer: why would the coordinate system be fractional? OAM/OBJ X/Y offsets are in pixels, so why would a SNES game engine internally be calculating anything but whole numbers? Rephrased (and with the SNES in mind): why would internally you have a sprite tracking system where a sprite could be at coordinate X=25.3 Y=39.7? I can see how there could be cases of "misalignments" if doing something like scaling a screen or sprite resolution by amounts that aren't divisible by 2 (ex. 2x, 4x, 8x, etc.), but I don't see how that would tie in to the game engine...
It's mario's position (which has a fixed point subpixel component), not the sprite's position. The sprite position shown in that picture is merely a visualization of that.
I don't think there's anything particularly wrong with how the tweet attempted to describe and show this in few words. It's an interesting point to make, that from that game's point of view Mario is constantly jiggling a bit.
You seem to have taken an implication that this has to apply generically to an SNES emulator and all games or how the SNES positions sprites, but it's none of that. It's really just about explaining SMW's internals.
As for the actual topic: Emulator authors are constantly looking for ways to offer things that the original consoles didn't: save states, rewinding, video filters, and so on. If they can somehow spy on the variables that represent the positions of game objects to make movement smoother at higher resolutions, I think this is a valid improvement that some users will be interested in. As long as it's optional, of course. I also think it's interesting to see how this ended up exposing something about a famous game's engine, where this "feature" obviously can't be used.
I'm not sure it's actuallly established that this is an actual emulation and not just some image the author made purely as a visualization of the idea.
However, they do seem to be an SMW TASer, so very much they probably do work with "frankenstein" emulator builds or lua scripts or other things to show themselves internal information useful for making the TAS. Being able to render SMW with subpixels positions of objects visualized spatially like this would be pretty cool for that purpose, so if you need a reason to build such an emulator, that's one.
koitsu wrote:
why would the coordinate system be fractional?
To avoid limiting velocity values to whole numbers of pixels per frame. Considering that Sonic the Hedgehog himself can't run faster than 6 pixels per frame, I can only imagine how clunky Mario would feel under such a limitation.
93143 wrote:
Considering that Sonic the Hedgehog himself can't run faster than 6 pixels per frame
Not on his own, but slopes, springs and power ups can help him achieve much faster speeds.
koitsu wrote:
why would the coordinate system be fractional?
It's only for physics calculations. Pretty much every game of this era uses Euler integration (position := position + velocity; velocity := velocity + acceleration). If position was an integer, you would get no change at all unless velocity >= 1, resulting in really clunky (imprecise) movement.
It's pretty common in any platform engine to be honest, to keep the movement from feeling too stiff, even if the games don't have any kind of inertia to the movements. All the way back to Donkey Kong, which curiously only does it when actual physics simulations take over (ie. all game objects have RAM space for a "subpixel" byte for each coordinate, but they are only ever addressed while jumping, bouncing etc.).
Think of the "pixel" not in terms of rendering space, but just as a measuring unit, such as "centimeter" being a subdivision of a "meter".
93143 wrote:
koitsu wrote:
why would the coordinate system be fractional?
To avoid limiting velocity values to whole numbers of pixels per frame. Considering that Sonic the Hedgehog himself can't run faster than 6 pixels per frame, I can only imagine how clunky Mario would feel under such a limitation.
I think it'd feel more like
Wario Land for Game Boy.
Wario Land doesn't really use subpixels and it shows in the game's triangular jumping physics.
Sumez wrote:
All the way back to Donkey Kong, which curiously only does it when actual physics simulations take over
I'm guessing that might be related to the fact that random access to fields of an object is slow on the 8080 family.
Donkey Kong (1981) and its port to ColecoVision use a Z80, which has reg+offset addressing with IX/IY, but the addressing modes using these registers are slow. So the programmer might have been tempted to take shortcuts to avoid hitting the subpixel position field in non-airborne states. Assuming a Z80 is clocked at 3.58 MHz, twice the frequency of the 6502 in the NES, Atari 800, or Atari 7800, a 6502 will use the equivalent of two tstates for each of its machine cycles: one with M2 low and one with M2 high.
Z80
ld a,[ix+5]: 19 tstates
6502
lda actor_field5,x: 8 tstates + 2 if low(ptr)+X >= 256
Z80
ld [ix+5],a: 19 tstates
6502
sta actor_field5,x: 10 tstates
The expanded remake
Donkey Kong (1994) runs on an LR35902, an 8080-like CPU that doesn't have IX/IY. So any access to struct fields would involve software-defined calculation on the HL pointer register, which is more efficient when it is sequential than when it is random. Accesing subpixels might require a couple extra seeks within the struct.
The game doesn't really need to take shortcuts like that though. It would add very little overhead to a game that's already extremely modest with its CPU usage.
I think a simpler explanation could be that the more "advanced" physics simulations weren't added until later in the game (a lot of details about the barrel screen makes me think it was probably the last one created), at which point using double byte coordinates went from being a luxury to a requirement. Also, it is very clear that different developers with very different mindsets have worked with different parts of the code.
I guess that kind of analysis fit better into my thread about converting DK's code, though.
Quote:
It's no wonder the general populous have problems comprehending classic consoles. Sheesh.
Like how 32x32 sprites take "more CPU power" than 16x16 sprites.
My favourite is how Recca apparently pushes the NES to the maximum, to draw much more sprites than you'd think it should be able to.
I'm fairly sure Recca never draws more than 64 sprites, and at least half the game is running at 30fps.
"32x32 is slower" could be a conflation of several issues.
If the game decompresses CHR data from ROM in real time rather than doing all decompression in advance on a blank screen, more pixels means more CPU time. And compression is more necessary with larger cels than with smaller ones.
Super NES has the additional complication of a 2D VRAM mapping. Thus a VRAM allocation system that supports allocation across four rows of OBJ CHR tiles (for 32x32) may use more CPU time than one that supports only two (for 16x16) because you can't as easily get away with allocating an entire row to one actor; you have to allocate a square and blit it using four DMA calls instead of one or two. Genesis VRAM is 1D, and GBA VRAM is 1D or 2D depending on bits in the display mode register.
And on platforms without hardware support for larger sprites, such as NES, Master System/Game Gear, and Game Boy/GBC, larger sprites literally take longer to draw because they fill more OAM entries.
Ignoring dynamic animation, they take the same amount.