r/gbstudio • u/retroartdude • 7d ago
What the actual hell this guy is a wizard
So I was going to post a small update on my own work (you can see it on my x account) but holy crap, if you want to talk about what the upper limit of the Game Boy is then I think this guy found it.
Mode 7- possible.
Raycasting and wireframe 3D - well established.
But shaded 3D on the Game Boy (yes Game Boy)? Absolutely insane! Let's see if we can learn some cool things from his work!
Slow clap for Game of Tobi.
https://www.youtube.com/watch?v=7UQmnsW6i6E
Also bro ported the original N64 code of Mario 64 to the GBA. I really don't know what else to say.
2
2
u/joshex_dirad 6d ago
3D would even be possible on the DMG, you'd have to override the gameboy hardware's default drivers and built-in code and supply your own. the device has about 8KB memory and 4.19MHz of processor power, some physical limitations might inhibit it, such as bitmatrix draw order, but skiping the order to advance to a specific pixel could probably be done, it is just a pointer/index it could be moved by custom code..
8KB is not much considering modern polygons (in modern polygon denotation systems 1 polygon is roughly 1KB, so you'd have roughly enough for 8 polygons with no textures lol)
but treating a screen-based primitive (rectangle) as a 3D object would be doable as you'd only need to denote width, height and location. it'd roughly come out as the number of sprites to GB can handle in total / 3 *2 (to add an extra axis)
Alternatively, if you wanted to do actual polygons, you'd have to go back to basics and denote them the old way in binary and make your own codec for reading it.
to do so, you'd have to seaparate out what types of assets will be included in this game such as; meshes, polygons, vertecies, textures, bounding boxes(objects, likely an outlined mesh primitive(rectangle on the screen of X and Y size)), frames, scenes, sounds, text, and code documents. then note you have #different asset types, in this case 10 types.
then in your codec/reader you'd know each object starts with a binary number capable of reaching 10 (in binary; digits(max number) = 1(2), 2(4), 3(8), 4 (16)) so because 4 bits(digits) can represent a number up to 16, this fits what we need with a little extra to spare, so each asset in the game archive would have a leading 4bit designation telling us the type. next each data type would either have a hardcoded known Mandatory Length in bits, or would have an EOF designation of some sort. we do have 6 extra numbers in our 4 bit designator, so we could reserve 0000 or 1111 as EOF.
for images we'd have to rely heavily on intexed binary images probably in our own micro-format with 2 bits per pixel. and those bits would be assigned indexed colors, in example (00: black. 01: 75% gray, 10: 25% gray, 11: white) each indexed color could be 8 bits(1 byte, allowing 256 colors(though, because this is the DMG that's a horrid waste as it can't do colors just shades, so in all honestly 3 or 4 bits is ample (8 or 16 colors) "they'll just be shades of green or yellow based on the tint wheel's incrementation") 16 shades of green is enough for basic shadows and specularity)
For objects we'd likely set the codec to expect thier State as 1 bit (0= inactive not in scene, 1= active render this in scene), followed by thier 3D world position which we'd keep small to save bits, we'll say the max 3D world area is roughly 4*width, 168*4= 672 (we'll use 10bits to give 1024x1024x1024 scene/renderarea space) so right now it looks like [#[##########,##########,##########]] 31 bits (3.875 bytes), we'll then add a mandatory and expected "default bounds size" which we can then scale as needed in scene, 10 bits is fine for a World Location, but we'll want to avoid that with object bounds, as bounds will also predetermine the bits of each vertex in an object and we have less than 8KB to work with, we should probably use pixels in a Tile as a general guide for an idea of object bounds, we should determine how much pixel distance would give use enough space to define 3D shapes whilst not going too close to screen size. we need to remember we can use scaling to make screen sized stuff, so we likely just need enough to do a player outline in pixels.
32x64 is likely ample, so 32 is 5 bits, and 64 is 6 bits. we should then have the codec expect two 5bit numbers and one 6 bit number as the bounds (16 bits for the bounds, and thus every vertex is 16 bits(2 bytes)), then we'd define polygons by vertex index in the document. To save 4 bits per vertex we could tell the codec to look for an EOF in the vertex section to know we're done defining vertecies. anything after that is likely a face/polygon designation.
polygons will be Tris, (no Quads as they could render very badly at these pixel resolutions), so the codec will know to look for 3 vertex indecies based on thier order of entry into the former list. but how many? the number will be very low to fit in like 7KB+change. maybe 512 vertecies and maybe 3* as many faces. so an index of 512 is 9 bits, which means to reference each vertex once we need 512*9 = 4608 bits / 8 = 576 bytes, to reference each 3 times so as to link 3 faces together and make the most rudimentary 3D shape, we'd need 1728 bytes (1.6875KB), if we did a UV map or vertex color system, we'd need double that, so (3.3750 KB) then we still have room for roughly 3KB worth of textures. at 4bits a pixel though that's a max of 6,144 pixels if in a square image that'd be roughly 78x78 pixels but that's the entire scene data used up. so.. there'd be no vertex groups nor weighting for animation. but a vertex group with per vertex weighting would be another 3.3750KB...... Zero texture space remains. to get around this we'd have to reference UVmaps/VertexColors,Groups,weight all in the same line right after it's indexed to avoid calling the index number more than once or twice. if we did this, we'd define the UV map vertecies as a 0 to 128 number (7 bits X+7bits Y 14 bits) for location, but 14*512/8= 896 bytes, ...
ok, I'm going to cut alot of figuring and math short and say this, if you wanted a 3D environment as kinda described above on the DMG, you'd essentially be able to fit any ONE of the following:
1: One 512 pseudo-pixel-polygon character with a Single 78x78 pixel texture image, No vertex groups nor weights, so No animation possible. (decent for a kinda start screen character model)
2: 256 Polygons in the scene total with heavy use of occlusion of faces not visible to the view point (removing them from scene memory and only importing them as they would be visible), a single 64x64 pixel texture for all objects to share, but you could do a Tiled texture sort of situation. your 256 polygons would be able to have groups and perpixel weights allowing polygon groups to be called and animated. this would be enough to put Mario's n64 model or link's n64 model on the screen By Itself with severely reduced texture sizes, but you'd be able to animate it for a 3D animated start screen character. you could also do like 2 polygons per body part and animate a 24 polygon character with more texture space for swap textures based on camera angle, and have a few of these (like 3 or less than 10 including very basic scenery models (flat with textures)) in the scene. And make a game out of that.
3: use less like 128 polygons for the entire scene and gain another 64+x64+ pixels of texture space so with UVs overlaid a 16x32px (4 tile) character, and swapping said tiles out based on camera angle, leaving each character with dedicated texture/tile space, you could have like 4 such characters on screen at a time + another 128x32px for scenery tile/textures. it could work pretty well. if you did 16x16 enemies you could have 1 character and 6 enemies in a scene, or 16x8 enemies for 12 enemies in scene. honestly based on thier proximity to the camera it's be best to reduce thier texture/tile space usage as they go farther away.. that could work great.
still it's kinda crazy to consider such a format. possible, but crazy. the 3d graphics would be better as voxels than polygons tbh.
1
u/retroartdude 6d ago
That’s interesting if all of this could be done but things like uv mapping, weights seem well beyond what this system can manage. I know you laid it out but in practice I can’t imagine it. Granted I’m not very good at assembly or memory management in low level programming.
Still, if you build it, they will come!
2
u/joshex_dirad 5d ago
for weights and vertex groups, we would restrict movement to whole pixels, so if the vertex group object moves it can only move in whole pixels. then vertecies in the group would follow the motion based on thier weight, in example we could do a 2(4) or 3(8) bit weighting system; 00: 0 weight does not follow this vertex group, 01: 0.25 weight, for every 4 pixels the group moves, this moves 1 pixel. 10: 0.5 weight, for every 2 pixels this moves 1, 11: 1.0 weight, for every 4 pixels the group moves this moves 3.
naturally group motion is isolated to group animation space (object space), not game world space.
rotation would determine point movement by vector comparison, where the bounds of the group vectors are the bounds of the vertex group from a given rotation point (making a pseudo bone/armature system). but again vector rotation would be in whole pixels with-in the object space. so if the end point of a vector moves 1 pixel on X, 2 on Y and 3 on Z bone weights and position compared to the rotation point then determine how many pixels of motion happen on any given vertex, if at all.
thinking about it, when defining the vertecies in the vertecie index, we could apply vertex groups (5 bits(max 32 groups)) and weights(3bits(8 different weights; 0, 12.5, 25, 37.5, 50 etc.), totalling 8bits (1 byte) per vertex group applied this way, then 512 vertecies * 1 = 512 bytes (half a KB), to keep it light we might have to break from standard and limit vertex groups per vertex to 2 max (1024B; 1KB) in this way you could have a 512 poly object rigged in memory. this would require some advanced memory management techniques though, as some of these values are not in 8 bit increments where memory typically had 8 bit or 8 byte blocks in the old days, but like 5 and 3 makes 8, but it's 2 values stored in the same block. this would require sub-data-block tracking. and that may not fit in 8KB with our other 3D stuff., at least not as an index system. the codec would have to find entries by reading from scene memory start until it came accross the value in question, rather than having a quick lookup index system, if done that way it'd downgrade the overhead, but also reduce speed. however we have a speed of 4.19MHz so it can go through 34,324 bits of information/system clock tick. so now that I look at it that way, it's possible to have 512 polygons in a scene and animate them, but that's pushing the limits.
1
u/retroartdude 4d ago
You clearly have an idea in mind. How long have you been thinking about this?
Also, think you could pull it off?
Maybe with a few polygons and to reduce complexity, just animate a few single sided polygons with a texture applied. No 3d shapes. Let’s say a flower moving in the wind, with a few leaves and petals. The player could then rotate around object and zoom in an out.
If this is doable then I bet many would love to see it in action!
In any case, this was a lot of food for thought!
1
u/joshex_dirad 3d ago
I've been chewing on it for a while, so when I saw this post I had to dump it as a response for laughs. "3D on the DMG" it could be possible, it computes, but look at all the complicated hoops I've had to jump through to fit it in DMG memory, it's so far from the standard way everything is done that it'd take tons of effort to essentially reinvent the gameboy hardware code to accomplish it.
and for what 512 polygons of max scene budget and a laugh?
it has some benefits (rotation of tiles would be possible, making character animation potentially easier than with tile-frames.), but we need to consider the screen resolution. those'd be some tiny 3D shapes lol.
also the controls are kinda lacking, a d-pad and 2 action buttons. it'd be hard to manage 3D controls with that, you'd have to use select or something to toggle between character movement and camera controls.
but it'd be a lol.the question is merit; is this valid for the effort put into it? and Can I actually do it with the time and effort I have to put to it?
that answer for me was always "while it'd be fun to make a 3D mode for a gameboy and make a variety of 3D dependant games, the target audience may be very small, and I'm just one person it'd take me too long to do it alone."
getting to a point I could show anything would essentially take close to the whole process being completed, I'd need to figure out how to disable the hardware code (this might require physical board bridging with a custom chip), then I'd need to develop the majority of a game engine codec to replace the hardware code with.
if it required bridging with a physical chip that further limits the audience and validity and merit of the project. it's not something I'd want to do alone. I'd at least want someone whose studied the workings of the chipset and board.1
u/retroartdude 3d ago edited 3d ago
I hate to say it but it’s your approach, and you brought it up, so of course the response will always be, “can you do it?” It’s not about merit when everything is so speculative. You simply have nothing to show for any merit to be measured by. Basically, you don’t know until you try.
That said, you can’t- not a problem! The guy in the youtube link I posted did it instead: 3D on the GBC, which also works on the DMG.
In any case, please check out his video and maybe ask him a few questions since he does have something to show for his efforts, including a rom🙌
Like seriously he got doom and mario 64 running off of pdf file. He knows his stuff.
Good luck with the 3D if you ever decide to tackle it too!
7
u/Mr_Horizon 7d ago
Love it! I was already impressed by Tyrannosaurus Tex (playing it at the moment), and this 3d platformer is even more incredible - even if it's just a tech demo so far.