Is it possible to create an SNES 'Mode 7/Pseudo 3D' type game in FUZE?
-
I'm a complete noob with very little actual coding experience. I have my eyes set on a project I would like to do that involves creating my own version of the SNES game Pilotwings, specifically the skydiving game.
I just need to know if it would be possible to create the pseudo 3D effect found with the SNES' Mode 7? (IE Super Mario Kart, Pilotwings etc)I am currently doing research and brushing up on my math as it is lacking quite a bit :P
If I am wasting my time trying this then I would greatly appreciate any input šš»
I plan on learning everything needed to complete this project and any tips or resources you could share is also greatly appreciated šš»šš»https://en.m.wikipedia.org/wiki/Mode_7
https://en.m.wikipedia.org/wiki/PilotwingsWasn't sure if this should've been posted in 'Help' or 'WIP' as I haven't actually started yet. I do plan on sharing my progress so maybe this could be moved to WIP after I do begin?
Thank you
-
Mode 7 is basicially scale and/or rotation right? I have never done anything like this personally but it should be possible to simulate it at least. Check in help under 2d graphics to see some of the commands that would be related to this
-
@QIsLegit It should be possible but it would be much easier to use the built in 3D engine. It is a cool effect though and would give a very retro feel to a game. I used to love F-Zero and Super Mario Kart on the SNES!
-
@pianofire
Would this involve drawing 2D sprites in 3D as sprites or textures applied to flat planes?F-Zero was one of the first games I remember playing!
-
@rdurbin
Yes. It's basically transforming 2D sprites based on the player view/camera in a way that gives a 3D effect. I'm still in the process of wrapping my head around it but it's something that has really caught my attention and has drawn me in.edit
It is actually only the background that gets transformed/translated and not the sprites. -
@QIsLegit You know as much as me at this point. Reading the article it seems like the effect only acted on the background not the sprites.
-
@pianofire
You are correct! I misunderstood! The sprites are drawn as is and separate from the background.This is the mistake of trying to take in too much info at once š¤£ I had also been looking at Sprite Stacking.
What would be considered a 'background' in Fuze? Just a large Sprite or a Map? I'm assuming a sprite as I'm not seeing anything about transforming/translating maps/layers.
šš» -
Mode7 is an interesting thing
Basically it is a single scalable layer - you can see the effects of this when Bowser stretches and scales in the final boss of Super Mario World and obviously most famously in f-zero and mario kart, where the ground is scaled, but the scale changes at each scan-line, producing a projected plane effect.
I've written mode7 planes before both in C, but unsure if a software scaled layer like that is what we should go for, although @Luke can tell us what method would be best given the graphics hardware
-
@QIsLegit Someone correct me if I'm wrong, but I'm not sure this is possible yet in Fuze! I know you can render a 3d model from the built-in assets...
It would basically be like the 3DO ("cell engine") or Saturn, where a sprite is actually just a quad, and you can arbitrarily rotate and scale it in "3d".
I would love for Fuze to have this capability-- then we could all make pseudo-3d games like were popular on those 32-bit consoles.
-
@Spacemario Replying to myself, lol. The more I think about this, the more I think it might be possible... Fuze can scale and rotate sprites already, so I think fake 3d "objects" would be possible-- think the "super scalar" Sega games, like "Space Harrier".
For the ground, someone on the forum was doing art purely through code, can't remember who that was... but couldn't the pixel data be read back, then depending on the "camera" (which would just be a 3d vector variable in the code), couldn't more pixels just be drawn for each pixel in the image, and scaled cleverly so it would look "flat" and angled, like a surface?
It would be challenging, but not impossible I think...
-
I wonder if the style of output could be faked using the CRT filter? One of the parameters is resolution!
Manipulating objects and a camera is quite easy in 3D if you can get the concepts of moving 2D objects down, playing around with the included 3D demos/tutorial code is a great starting ground.
I'm happy to help with any math for camera movement on or around objects in a scene :)
Keen to see a project for this one !
-
Maybe this is something that we can add support for to the language. In the meantime it will be interesting to see what people come up with
-
@pianofire If we're talking about just a projected plane, then I could see that implemented via a textured polygon function that's kind of like drawQuad, except the source isn't limited to a axis-aligned bounding box, but each 2D vertex source could be assigned much like the destination array for that same function, but for polygons, the destination points would be 3D (else all we'd get is scaling). So then, one would have to draw the layer to a separate target (like making a map and rendering that), then use polygons to create the effect.
But, Mode 7 covers a lot more than just a projected plane. It was able to adjust the position, origin, and 4-value transformation of a layer per scanline, so other effects could be had. Take for instance Super Castlevania IV with the tunnel effect. On the YT channel Retro Game Mechanics Explained, he goes into depth on how the effect is done, with a visual that really helps to explain it.
With the current functions, one could technically make the effect, but it would be quite inefficient, and for something like a full-screen effect, it would eat into processing to the point where you won't be able to get 60fps. So here's my thought. If a request to have a kind of Mode 7 function were to be implemented that allowed more control than just for projected planes, then we'd need to have control over each scanline that is drawn. The function could initially look like this....
drawMode7Line( handle, { xpos, ypos, xorig, yorig }, { A, B, C, D }, { x, y, width, height })
This differs from the drawQuad function because rather than take an axis-aligned bounding box to render it with adjustable destination points, this swaps the box around, making the destination an axis-aligned bounding box and the source have adjustable data. It would be useful for a full-screen effect that is only called once, but to make something like a projected plane, it would need to be called per line, which would then be process-heavy. Perhaps something like this...
drawMode7Effect( handle, count, entries, { x, y, width, height } )
handle Variable which stores the desired image file
count The number of entries that hold data pertaining to the Mode 7 effects
entries Holds the entries for each partition of the Mode 7 effect
x Desired on-screen horizontal axis location
y Desired on-screen vertical axis location
width Desired on-screen width in pixels
height Desired on-screen height in pixelsentries is split up every 9 elements
[0] - Number of lines this entry covers
[1] - X Position
[2] - Y Position
[3] - X Origin
[4] - Y Origin
[5] - A Transform
[6] - B Transform
[7] - C Transform
[8] - D TransformIf, for instance, you planned on the effect having a different value per line for a 720p result, you'd need an array that is 720*9 elements (so 6480 elements, which is a lot). Filling that data would be time-consuming, but certainly less consuming than with current functions. Maybe this could be shrunk if we included an element per entry that is bitField-related, where if bit0 is set, then X Position is part of the changes, bit1 is for Y Position, bit2 for X Origin, etc. to reduce the number of elements needed. Each bit set will carry the values over to the next entry, in case those do not have the particular bits set.
-
Had to stop watching that video - it was making me feel sick!
-
@Martin Hah, doesn't help that the framerate is like 10 fps on that "tube" part. I have a Super NES and copy of this game at my cabin, and cringe every time I get to that level-- the effect is really cool, but it sure runs slow!
-
@Spacemario said in Is it possible to create an SNES 'Mode 7/Pseudo 3D' type game in FUZE?:
@Martin Hah, doesn't help that the framerate is like 10 fps on that "tube" part. I have a Super NES and copy of this game at my cabin, and cringe every time I get to that level-- the effect is really cool, but it sure runs slow!
That segment would have slowdown the moment it had to deal with a good number of sprites. The enemies that would pop out, the explosion of bones when you defeated them, even using the whip all required additional sprites to be displayed. Even without those, the very platforms themselves are all sprites as Mode 7 only has one background layer, and that's used for the tunnel effect itself. Any SNES game with a bunch of sprites onscreen tends to have slowdown frequently (such as Gradius 3).
The effect itself actually requires very little manual processing due to the nature of HDMA channels, which are hardware-controlled, and using pre-made static Lookup Tables. Only scrolling horizontally and vertically are manually done, but that is once per frame, not per scanline. That is why when there are fewer sprites on-screen, the effect achieves 60fps easily.
-
i think i could pul this off with the new map tile animation, i may have a go later
-
@waldron It'd be incredible if you got this working!
I also wondered if the texture-mapped cube thing could be used; like, what's the upper bound texture resolution that his engine supports?
In other words, "mode 7" could just be a huge cube for the ground, with a giant (or series of smaller I suppose) texture applied to it.
To be honest, I have a lot of questions about that code. Texture-mapped 3d environments are possible now! But what are the limitations? Sometime today I'll ask in that thread.
-
@Spacemario the way i thought i can get it to work is all through animation, i wouldn't be able to use that technique
thats beyond me lol
but i do wonder is it possible to load 2 maps and have code that switches between them periodically -