"TwistIT", a small demo/intro

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
"TwistIT", a small demo/intro
by on (#213106)
http://resistance.no/releases/snes/Twis ... elease.zip

https://www.youtube.com/watch?v=9qHBVDgwCiI

A little something I worked on over the last month or so for the oldschool intro compo at Demobit this weekend, where it ranked first (out of... two...) Contains some HDMA abuse and attempts at semi-fast realtime 3D without a coprocessor. Totals a bit smaller than 64kb.

Most of the code was written as experimental stuff at a few points throughout late 2017, and then around the new year we decided to put it together into an actual production. I used Optiroc's libSFX tools/library (which I also helped out with a bit during development) and snesmod for music.

Source: https://github.com/ResistanceVault/demo-twistit
Re: "TwistIT", a small demo/intro
by on (#213107)
Also, http://www.pouet.net/prod.php?which=74656
Re: "TwistIT", a small demo/intro
by on (#213110)
Thank God somebody made this demo. Now I have stuff to show if anybody says that the SNES can't do polygons without a Super FX chip.
Re: "TwistIT", a small demo/intro
by on (#213124)
Excellent, I really like the music, and the polygon graphics / blending are great!

Kudos for finishing it, and I'm eager to see your next release!

One silly question from a newbie SNESdev: How are you doing the "title blinking". Do you use an identical graphical data with a dynamically modified palette, or did you simply make a small "blinking" animation using different sprites / tiles data?
Re: "TwistIT", a small demo/intro
by on (#213147)
psycopathicteen wrote:
Now I have stuff to show if anybody says that the SNES can't do polygons without a Super FX chip.

Of course it can, the question is how many fps spf.
Re: "TwistIT", a small demo/intro
by on (#213148)
psycopathicteen wrote:
Thank God somebody made this demo. Now I have stuff to show if anybody says that the SNES can't do polygons without a Super FX chip.

There actually is another demo out there that pushes about the same number of polygons at the same size and framerate. Of course, for a person's first demo though, this is excellent.

We all know the main problem with producing 3D on the SNES though, is having to convert the framebuffer to the SNES graphics format once the frame is done, unless you can find a way to render unshaded polygons on a framebuffer using the SNES graphics format at a faster speed.
Re: "TwistIT", a small demo/intro
by on (#213149)
If you're referring to the demo I think you are:

Image

Even at its smallest size/number of faces, this is never running at more than 20 fps, whereas my large cube is a constant 30fps (and would probably get a little higher at a size that small). The other (24-face) shape runs between 15-20 fps depending on how much else is happening (unfortunately all the stuff happening in the NMI keeps it ultimately locked at 15).

(If you're talking about a different demo that I've somehow forgotten about, then never mind :))

There's also not really any "conversion" needed on the software side if you make good use of $2115. I can demonstrate better once I get around to releasing the source, but basically I render into two separate 1bpp buffers and DMA them individually such that they're basically "converted" to 2bpp on-the-fly.

drludos: The flashing logo just uses some alternate palettes which are generated from the normal one by bitwise-ORing the colors with a few increasing shades of grey. (I could have also just used multiple pre-made palettes, but doing it programmatically on the SNES seemed easier somehow)
Re: "TwistIT", a small demo/intro
by on (#213150)
Revenant wrote:
Even at its smallest size/number of faces, this is never running at more than 20 fps, whereas my large cube is a constant 30fps, and the other (24-face) shape runs between 15-20 fps depending on how much else is happening (unfortunately all the stuff happening in the NMI keeps it ultimately locked at 15).

Okay then; nevermind. :lol:

Revenant wrote:
but basically I render into two separate 1bpp buffers and DMA them individually such that they're basically "converted" to 2bpp on-the-fly.

What would you have to do to get 4bpp? 2bpp is pretty much irrelevant for an actual game.
Re: "TwistIT", a small demo/intro
by on (#213151)
4bpp is probably doable the same way (the "address translation" and "increment after high/low" bits in $2115 are the key). At that point you'd have to be more careful about DMA bandwidth, though; ultimately I'm DMAing 128x128x2bpp of pixel buffer which takes nearly the entire vblank period.
Re: "TwistIT", a small demo/intro
by on (#213157)
How are the starting and ending phases in the twist layer calculated for each frame?
Re: "TwistIT", a small demo/intro
by on (#213164)
Basically, the value of "f(t)" (where f(x) is some relatively simple sinusoidal function and t is a frame/tick counter) is added to the current scanline number and then used as the parameter to two other similar functions which determine each scanline's horizontal position (with an appropriate phase difference between the two twisters) and the actual twist position (which you can probably guess is just vertical scrolling, and each of the two layers uses a different function for this part).

f(t) is also used for the translucent twister to determine per-scanline color math settings for the "in front/behind" pseudo-3D thing.

So basically the horizontal movement as well as the actual twisting are just functions of the frame and scanline numbers (something like "sin(y + sin(t))"; that's not literally the equation since there's some additional frequency/amplitude/phase twiddling going on but you probably get the idea).
Re: "TwistIT", a small demo/intro
by on (#213168)
I was also interested in the per-frame calculation for the twist position at the top and bottom.
Re: "TwistIT", a small demo/intro
by on (#213173)
It's calculated the same way for the top and bottom as it is for every individual scanline (or rather, every two scanlines) in between, using a combination of elapsed frames and the scanline number (and two or three lookup tables for some fairly basic sine-based curves).

It's not really as sophisticated as it might look, I just generated some sinusoid tables and experimented with ways to combine them and factor in frame/scanline counts until it looked sort of cool. I couldn't really tell you any exact equations or anything without trying to "un-work" a bunch of loops and lookup tables :P
Re: "TwistIT", a small demo/intro
by on (#213180)
Revenant wrote:
Even at its smallest size/number of faces, this is never running at more than 20 fps, whereas my large cube is a constant 30fps (and would probably get a little higher at a size that small). The other (24-face) shape runs between 15-20 fps depending on how much else is happening (unfortunately all the stuff happening in the NMI keeps it ultimately locked at 15).

15 FPS is still twice as good as Starfox, and without a coprocessor, I'd say that's a feat. Of course, running a game at that speed is an entirely different challenge altogether. But I'm looking forward to seeing where SNES demos will go from here. I feel like the hardware should allow programmers to get way more creative than what the MegaDrive allows.
Re: "TwistIT", a small demo/intro
by on (#213185)
Aha, neat trick with the bitplane conversion!
Re: "TwistIT", a small demo/intro
by on (#213187)
I like it, a little bit short but cool,and show some interesting effects .

Quote:
We all know the main problem with producing 3D on the SNES though, is having to convert the framebuffer to the SNES graphics format once the frame is done, unless you can find a way to render unshaded polygons on a framebuffer using the SNES graphics format at a faster speed.

May be you can use mode 7 for that,for dealing with chunky rather than planar, and use sprites to avoid a black background .
Re: "TwistIT", a small demo/intro
by on (#213204)
Sumez wrote:
Of course, running a game at that speed is an entirely different challenge altogether.

It definitely is, and I'm certainly not trying to suggest I could do anything even remotely close to Star Fox without some kind of hardware assistance - when you have to deal with potentially complicated game logic and rendering multiple moving 3D objects as part of a scene, it becomes a totally different ball game. But being able to get reasonable performance from any 3D at all on the stock hardware is an interesting challenge of its own :)

Optiroc wrote:
Aha, neat trick with the bitplane conversion!

I honestly wonder if that sort of thing isn't specifically what Nintendo intended the address translation bits in $2115 to be used for. In particular, part of what led me to experiment with it was the way it's described in nocash's docs:

Code:
2115h - VMAIN - VRAM Address Increment Mode (W)
  7     Increment VRAM Address after accessing High/Low byte (0=Low, 1=High)
  6-4   Not used
  3-2   Address Translation    (0..3 = 0bit/None, 8bit, 9bit, 10bit)
  1-0   Address Increment Step (0..3 = Increment Word-Address by 1,32,128,128)
The address translation is intended for bitmap graphics (where one would have filled the BG Map by increasing Tile numbers), technically it does thrice left-rotate the lower 8, 9, or 10 bits of the Word-address:
  Translation  Bitmap Type              Port [2116h/17h]    VRAM Word-Address
  8bit rotate  4-color; 1 word/plane    aaaaaaaaYYYxxxxx --> aaaaaaaaxxxxxYYY
  9bit rotate  16-color; 2 words/plane  aaaaaaaYYYxxxxxP --> aaaaaaaxxxxxPYYY
  10bit rotate 256-color; 4 words/plane aaaaaaYYYxxxxxPP --> aaaaaaxxxxxPPYYY
Where "aaaaa" would be the normal address MSBs, "YYY" is the Y-index (within a 8x8 tile), "xxxxx" selects one of the 32 tiles per line, "PP" is the bit-plane index (for BGs with more than one Word per plane). For the intended result (writing rows of 256 pixels) the Translation should be combined with Increment Step=1.
Re: "TwistIT", a small demo/intro
by on (#213240)
Sumez wrote:
15 FPS is still twice as good as Starfox

...no?

IIRC Star Fox is capped at 20 fps (the Arwing at the title screen is a good example), and 15 isn't unusual. Wolfenstein 3D is capped at 15.

I'm wondering how polynes3 was achieved. It seems (can't find a frame advance control in Nestopia) to be pulling off 30 fps with a cube - a big one - in actual perspective. It then proceeds to higher-order polyhedrons at lower frame rates, but still solid-filled. Apparently it uses a bunch of illegal opcodes and is optimized to the rafters, so I can't guarantee that it isn't using precomputed vertex positions or some such...

...

Nice demo, BTW. Good to see more of this sort of thing starting up. Maybe we'll have an answer to Overdrive 2 someday...
Re: "TwistIT", a small demo/intro
by on (#213241)
93143 wrote:
I'm wondering how polynes3 was achieved. It seems (can't find a frame advance control in Nestopia) to be pulling off 30 fps with a cube - a big one - in actual perspective. It then proceeds to higher-order polyhedrons at lower frame rates, but still solid-filled. Apparently it uses a bunch of illegal opcodes and is optimized to the rafters, so I can't guarantee that it isn't using precomputed vertex positions or some such...


All vertexes are distance 1 from the origin and that simplifies the math a lot. There's no clipping whatsoever, which obviously means it doesn't have to perform costly clipping operations, but it also means that it can use a fast xor filling algorithm for rasterization. It's also orthographic and not true perspective, which removes the need for the expensive z divide.

At least that's what I remember. Don't quote me on it.
Re: "TwistIT", a small demo/intro
by on (#213249)
pubby wrote:
It's also orthographic and not true perspective, which removes the need for the expensive z divide.

This doesn't look orthographic to me:

Attachment:
polynescube.png
polynescube.png [ 25.91 KiB | Viewed 2498 times ]

For reference, this is the ROM I'm talking about:

Attachment:
polynes3.nes [128.02 KiB]
Downloaded 88 times

Quote:
Don't quote me on it.

Oops...
Re: "TwistIT", a small demo/intro
by on (#213251)
Is the SNES demo just drawing front facing polygons, like the NES demo does?
Re: "TwistIT", a small demo/intro
by on (#213252)
Assuming you mean mine, the cube is front faces only, the other shape has front and back faces on opposite bitplanes (using the 3 palette colors to "blend" them).
Re: "TwistIT", a small demo/intro
by on (#213269)
Revenant wrote:
Optiroc wrote:
Aha, neat trick with the bitplane conversion!

I honestly wonder if that sort of thing isn't specifically what Nintendo intended the address translation bits in $2115 to be used for. In particular, part of what led me to experiment with it was the way it's described in nocash's docs:

Yeah, maybe. They must certainly have had bit depth conversion in mind, like using 1bpp font data in ROM and translate it to 2bpp data as it is sent over to VRAM. Who knows if they saw this use case as well.

I've never looked into how the polygonal triforce splash screen in Zelda 3 is rendered. Being an early game with the developers surely in close contact with the hardware team, it sort of serves as Nintendo's canonical example of how to render polygons on stock hardware.
Re: "TwistIT", a small demo/intro
by on (#213272)
93143 wrote:
Sumez wrote:
15 FPS is still twice as good as Starfox

...no?

IIRC Star Fox is capped at 20 fps (the Arwing at the title screen is a good example), and 15 isn't unusual. Wolfenstein 3D is capped at 15.

I don't have any hard numbers, but I find it hard to imagine Starfox is running at 20FPS during gameplay. Is there any video out there that measures it? It's surprisingly hard to get details on.
Re: "TwistIT", a small demo/intro
by on (#213275)
I'm getting 4-6 frames per update on Corneria in Snes9X, and the gameplay feels about right to me (I don't think bsnes has frame advance). I did say "capped" and not "locked"...

The beginning of the training level runs at 3 frames per update, or 3-4 once some buildings show up in the distance. This is with maneuver but no weapons fire. There's not much on screen, but it is technically gameplay...
Re: "TwistIT", a small demo/intro
by on (#213276)
What do you mean by "per update"?
Re: "TwistIT", a small demo/intro
by on (#213277)
I'm using "frame" to mean a video frame, and "update" to mean a graphics update - what you'd call a "frame" if you were talking about fps. So 3 frames per update is 20 fps, and 6 frames per update is 10 fps.

I figured it would be evident, but I'm not good at judging how well other people can read my mind (sometimes it feels like they can't do it at all, which is weird because I can read my mind just fine...). I used "frames per update" rather than fps because fps is usually considered an average, and I was just taking a few consecutive point measurements without really trying to average them. I should probably have changed it to "VBlanks per frame" or something, but since I wasn't specifically detecting VBlank it felt pretentious and inaccurate... "frames per frame" perhaps?
Re: "TwistIT", a small demo/intro
by on (#213280)
BizHawk has a frame advance function, and you can switch it to use a bsnes core.
Re: "TwistIT", a small demo/intro
by on (#213341)
https://github.com/ResistanceVault/demo-twistit

Here is the (messy) source to this thing. I didn't comment it as thoroughly as I probably should have, but oh well.
Re: "TwistIT", a small demo/intro
by on (#213377)
The most interesting part is the bottom of the "vector plot" doc. That's what does the polygon filling.
Re: "TwistIT", a small demo/intro
by on (#213478)
Revenant, that's an awesome demo!
Congrats on making first place and keeping the spirit alive on the SNES!
Excellent tune, too.

Looking forward to your next prod!