Jump to content
IGNORED

creating a new 3d graphics engine for the Atari 2600 (talking phase)


grafixbmp

Recommended Posts

Did you see the pic I have above of a Doom style layout I was just trying to get a feel for the look of doom. Not anything that would look exactly like that on a real atari. But I would like to know what you think. I like the whole ray casting thing, BUT! and this is a BIG but. NOONE should have to turn their screen sideways to play. period.

 

It seems relatively doable except the walls I think would have to be constrained to 40x20 or 32x25 resolution (or something like that). Unless you used superchip ram in which case you could have double the wall resolution.

 

Also I thought more about this...and I think there would definitely need to be distortion correction (i.e stretching wall columns vertically as you get closer to the edges of the screen) or things would not look right when you turned left and right. I think maybe this could be precalculated and hardcoded though since the number of columns is relatively few, thus avoiding any multiplication there...

 

Turning the TV sideways would not be needed. The only reason Merlin's Walls was done like that (I think) is so he could use multiple colors for the walls.

 

Ben

Link to comment
Share on other sites

  • 1 month later...

What attempts have been made to create a basic shape wireframe engine for the atari? I had a side-idea for a simple game of a character walking around a 3D shape on the screen. The 3D shape would verticaly rotate and would spin clockwise or counterclockwise. A very very simple game layout based upon the new super mario galaxy game. also the backside of the wireframe would be best omited from being drawn. you would then go from one object to another distant one.what do you think? I have heard of and seen some tech demos dipicting simple 3D shapes.

Link to comment
Share on other sites

  • 4 weeks later...

Never seen wireframe on the 2600, but with a good line-drawing algorithm, you could store only the transformed vertices and calculate some number of wires per scanline. Bresenham's is a good example, since it's designed to be absurdly fast, but it'll work best here if you're drawing mostly vertical lines. You have some number of lines - let's say five, one for each player/object and one for the ball, all against a black background - and they can move one pixel left or right every scanline. Actually, since you can stretch them 2 or 4 times, there's more horizontally-oriented lines you could describe without breaks or background-based hacks. Bear in mind this is all per-pixel and could use the full 192x168 resolution, so long as you don't need to any vectors outside that magic range of ~210-330 degrees.

 

I think I see how Ben's doing it, and it's entirely possible to get walls without turning the screen. For however many columns you have, you store an integer representing the height of the wall filling that column. Wherever you start drawing your walls, initialize a counter to your maximum wall height, and for every scanline from there until mid-screen, you decrement the counter and turn any columns with height equal to or greater than the counter from BG0 to BG1. Okay, so it's not really per-scanline, because you won't have that much precision, but you decrement and check every N scanlines and it's the same idea. From mid-screen to wherever you stop drawing the walls, do it backward - increment the counter from 0 to the max height, and turn off any columns that aren't in range anymore.

 

The included example illustration is backwards from the description, but the idea's the same.

 

Perspective correction can be done before any of the columns are drawn, since you can tweak the heights of columns by adjusting a single row of numbers. If you wanted to, you could throw in some odd special effects by playing with the column height vector - sinusoidal finagling for drunkenness, uniform scaling for fading in/out, capping with a BG color change for the appearance of closing doors, etc. As an added bonus, this method leaves all sprites untouched and only needs to really fiddle with things every 8th scanline or so.

 

post-8547-1207447233_thumb.png

Link to comment
Share on other sites

  • 3 weeks later...

Alright, here's a half-decent mockup of what the high end could look like for this wall-based raycaster idea. This is a straight dump of the file I've been toying with in MSPaint, so forgive the repetition and random junk all around. The walls are all single-color per scanline and symmetric about the vertical midpoint. Since you're definitely not going to have 256 possible wall heights, there are some options for the one-dimensional array holding the values.

 

post-8547-1209245133_thumb.png

 

One: halve the storage space needed by putting the left half into the lower nibble and the right half into the upper nibble. This limits the engine to 16 wall heights. This is only really useful if you absolutely need a few more free bytes during VBLANK, since the values will have to be bitshifted or booleaned into full bytes before you can use them. Not a great idea.

 

Two: limit the engine to 64 or 32 wall heights and use the upper 2/3 bits for per-line or per-frame effect flags. 00 for normal (solid), 01 for even lines only, 10 for even frames only, and 11 for windows. Windows are solid below their height value, but clear below half their height value - just decoration. Maybe "doors" is a more appropriate term, if they're to be used for something. The per-line effect is shown here, marking what was a door in the Wolf3D screenshot I drew over.

 

Since drawing is symmetrical, it's better to think of the upper and lower halves of the screen as separate routines, or at least to think of the vertical midpoint as the zero. Objects clinging to the ceiling will stop at or above the centerline, so you don't have to consider them for the lower half. Vice-versa for floor objects like that barrel. Tall objects like the guy about to shoot you can be divided, literally or rhetorically, into a ceiling object and a floor object. The horizontal positions of both sprites have to be set only twice per frame: once at the top, and once at the midpoint. The rest is managing which bytes of sprite data to display and what color to make them. In short, you could display four tall objects or eight half-screen objects with 30Hz flicker - and only worry about clock cycle timing on two lines.

 

The sprites near the top show example scaling. The one marked with an X is 150% tall, and the one-two tracking necessary for it probably isn't worth the hassle. The rest are hardware-scaled to 2x or 4x wide and vertically scaled by an integer multiplier.

Link to comment
Share on other sites

Mindbleach, I love the stuff you have been putting into the 2600 in regards to a 3D engine. I have recently be off in a tangent into physics lately specificaly quantum physics and I have been dealing with a job promotion also coming up in the next month. This will undoubtedly be a busy year for me. I hope to comeback to your posts and elaborate a few thoughts on your briliant demo screens and ideas for creating them. BTW, what find of frame rate are you looking at 10 - 15 perhaps?

Link to comment
Share on other sites

I'm not sure on framerate. I don't actually have any non-Batari experience getting code onto an emulator, though that may change after I put some time into the Warning Forever-inspired shooter I've been doodling about. Anything above 10 would be playable; over 15 would be incredible. The bottleneck is in casting rays - stepping through the map in 40 directions. Getting the direction is a hack, stepping through is a hack, and god knows the map will have to be a hack of some sort. It would probably be easier to store a level as a series of lines than as a two-dimensional array... and I should be worried that I'm now thinking about circular rooms and non-ortho walls.

 

Ooh, I think I just solved a problem I had with non-turned, wall-based 3D like this: I know how to do do depth shading. If every logical frame lasts multiple actual frames (persistent through multiple VBLANKs, sprite flickering aside), make the background black and flicker the shorter columns. So if you work at 15 FPS, tall (near) columns are solid, but columns less than 66% of full-height are ignored on every fourth frame, and less than 33% are ignored every other frame... distant walls appear darker, blending with the background. This could become problematic with flickering sprites, but might be an acceptable effect with properly dim walls and bright objects.

 

Anyway. don't worry about tending to reality before this lark. This subforum isn't exactly overwhelmed with traffic, and I took a long hiatus from it without your initial, inspiring post sliding off into oblivion. The content will still be here whenever you've got time. Frankly, it was a pleasant surprise to see such a quick reply.

Link to comment
Share on other sites

Alright, here's a half-decent mockup of what the high end could look like for this wall-based raycaster idea. This is a straight dump of the file I've been toying with in MSPaint, so forgive the repetition and random junk all around. The walls are all single-color per scanline and symmetric about the vertical midpoint. Since you're definitely not going to have 256 possible wall heights, there are some options for the one-dimensional array holding the values.

 

post-8547-1209245133_thumb.png

 

One: halve the storage space needed by putting the left half into the lower nibble and the right half into the upper nibble. This limits the engine to 16 wall heights. This is only really useful if you absolutely need a few more free bytes during VBLANK, since the values will have to be bitshifted or booleaned into full bytes before you can use them. Not a great idea.

 

Two: limit the engine to 64 or 32 wall heights and use the upper 2/3 bits for per-line or per-frame effect flags. 00 for normal (solid), 01 for even lines only, 10 for even frames only, and 11 for windows. Windows are solid below their height value, but clear below half their height value - just decoration. Maybe "doors" is a more appropriate term, if they're to be used for something. The per-line effect is shown here, marking what was a door in the Wolf3D screenshot I drew over.

 

Since drawing is symmetrical, it's better to think of the upper and lower halves of the screen as separate routines, or at least to think of the vertical midpoint as the zero. Objects clinging to the ceiling will stop at or above the centerline, so you don't have to consider them for the lower half. Vice-versa for floor objects like that barrel. Tall objects like the guy about to shoot you can be divided, literally or rhetorically, into a ceiling object and a floor object. The horizontal positions of both sprites have to be set only twice per frame: once at the top, and once at the midpoint. The rest is managing which bytes of sprite data to display and what color to make them. In short, you could display four tall objects or eight half-screen objects with 30Hz flicker - and only worry about clock cycle timing on two lines.

 

The sprites near the top show example scaling. The one marked with an X is 150% tall, and the one-two tracking necessary for it probably isn't worth the hassle. The rest are hardware-scaled to 2x or 4x wide and vertically scaled by an integer multiplier.

 

Well, I looked over your demo shots with more detail and I mught have a few thoughts for you. Aside from the raw 3D calculations, one thing that may perhaps be necessary just for canculation times would be double higth playfield pixels. This would not only allow less memory for housing the screen data for any givven time but would also give more room in the scanlines to accomplish other things for a fuller game play envirnment. Also, have you thought about what it takes to store all that screen data and have very little memory left for other things not tomention 3D calculations.

 

You may have had more time to think on these things buy what about this: instead of storeing a bitmaps worth of screen data, why not just store a set of angular trajectories for the walls edges against the ceiling and in turn the floor as well (since we would reuse the same data) and then just fill in the rest inbetween. the inbetween could just be stored as say 10 bytes allowing for 2 bit pixel "collum" data. This could allow for windows, doors, and shaded distance like walls or unlit rooms. For whatever is done from the top of the screen to the horizon will then be duplicated in a mirror image on the bottom. Anywhere that a trajectory line is drawn, for any pixel for a single scanline, the next scanline below is applied the inbetween data. and when the floor trajectory line is drawn in the same fashion, the inbetween data is zeroed out for the same areas.

 

Think of it as modulating a carrier wave with a digital signal and also duplicating it by fliping it below itself and then filling in the area between them. Depending on how the wave was modulated, would depend on the types of rooms you would want to have. A triangle or sawtooth wave will give you the angular corners of a room like square or rectangular rooms. A sine wave calculation would give the round rooms you wanted and so-on.

what do you think?

Link to comment
Share on other sites

Playfield pixel height is shown as 1 in the examples only because there's space for it. If the 3D display area is 192x128, the most detail you could possibly put into wall height is just 64 pixels, so you get two flag bits for free. Doubling up so you only have to play with the BG every other line is probably a very good idea.

 

Assuming I understand what you mean with modulation, I like the idea, but I'm unsure about the horizontal resolution being enough for what I think you have in mind. Let me play it back and see if I received correctly.

 

You want to store the wall data as a series of lines, filling everything in from the top of the wall to the middle of the screen (and vice-versa, though we'll take that to be assumed from here on out). To make these straight lines more interesting, you want to apply a sort of filter that will fiddle with the height of any given wall, making straight lines jagged, wavy, square-waved, etc. This could look very good if used properly, and would in fact be a nice alternative to texturing. However I worry about its effects on distant and therefore small walls - little details would get blown out, and short walls might appear to grow and shrink when you turn.

 

Perhaps you're suggesting column end-caps with finer horizontal detail than the 40 columns of the background? I don't think that's possible without some serious ball abuse, and it would flicker like nobody's business.

 

Or maybe I've read it completely wrong, and you're thinking of a texturing of sorts... where every column has a few bits controlling the halves or quarters of the wall. Kind of like the window idea, but also allowing thick striping, tall doors, high & low windows, or anything blocky pattern that's vertically symmetrical. If so, even better. An adaptation of this would be to repeat some number of bits as a one-dimensional texture down the length of the column. That way you could do finer details, but the effect in motion would be strange. The whole world would be textured like that salesman's jacket in Monkey Island... he moves, but the plaid doesn't.

 

However you mean, I'm left with the impression that I explained myself poorly with regards to storage.

 

The screens shown use only 40 bytes to hold the walls, flags included. "Only" anything is a stretch with 128 bytes to your name, but those bytes and 6 bytes of scrap space are all that's needed to draw the walls once the rays to find them are cast. Except... oops, I missed something. You can only call it 40 bytes if you update your rays in-place, so the new wall heights sort of slide across the screen every tenth of a second. A tolerable compromise if your framerate's good. If you can update one ray/column during each VBLANK, it would take 40 VBLANKs to update the whole scene... meaning our framerate's nearly unplayable unless we can eke out at least seven rays per VBLANK. This is why I was worried about raycasting as the bottleneck. We do a lot of it.

 

If 40 bytes is really too much, making playfield pixels four lines tall gives you 16 possible wall heights. That's hex, so you can double up the columns into 20 bytes and worry about windows and other effects elsewhere.

 

When I mentioned oddly shaped rooms, I wasn't thinking of visual hacks, I was thinking of actually building the level out of geometric shapes. It's probably excessive, especially if the static level data can stay in ROM.

Link to comment
Share on other sites

Playfield pixel height is shown as 1 in the examples only because there's space for it. If the 3D display area is 192x128, the most detail you could possibly put into wall height is just 64 pixels, so you get two flag bits for free. Doubling up so you only have to play with the BG every other line is probably a very good idea.

 

Assuming I understand what you mean with modulation, I like the idea, but I'm unsure about the horizontal resolution being enough for what I think you have in mind. Let me play it back and see if I received correctly.

 

You want to store the wall data as a series of lines, filling everything in from the top of the wall to the middle of the screen (and vice-versa, though we'll take that to be assumed from here on out). To make these straight lines more interesting, you want to apply a sort of filter that will fiddle with the height of any given wall, making straight lines jagged, wavy, square-waved, etc. This could look very good if used properly, and would in fact be a nice alternative to texturing. However I worry about its effects on distant and therefore small walls - little details would get blown out, and short walls might appear to grow and shrink when you turn.

 

Perhaps you're suggesting column end-caps with finer horizontal detail than the 40 columns of the background? I don't think that's possible without some serious ball abuse, and it would flicker like nobody's business.

 

Or maybe I've read it completely wrong, and you're thinking of a texturing of sorts... where every column has a few bits controlling the halves or quarters of the wall. Kind of like the window idea, but also allowing thick striping, tall doors, high & low windows, or anything blocky pattern that's vertically symmetrical. If so, even better. An adaptation of this would be to repeat some number of bits as a one-dimensional texture down the length of the column. That way you could do finer details, but the effect in motion would be strange. The whole world would be textured like that salesman's jacket in Monkey Island... he moves, but the plaid doesn't.

 

However you mean, I'm left with the impression that I explained myself poorly with regards to storage.

 

The screens shown use only 40 bytes to hold the walls, flags included. "Only" anything is a stretch with 128 bytes to your name, but those bytes and 6 bytes of scrap space are all that's needed to draw the walls once the rays to find them are cast. Except... oops, I missed something. You can only call it 40 bytes if you update your rays in-place, so the new wall heights sort of slide across the screen every tenth of a second. A tolerable compromise if your framerate's good. If you can update one ray/column during each VBLANK, it would take 40 VBLANKs to update the whole scene... meaning our framerate's nearly unplayable unless we can eke out at least seven rays per VBLANK. This is why I was worried about raycasting as the bottleneck. We do a lot of it.

 

If 40 bytes is really too much, making playfield pixels four lines tall gives you 16 possible wall heights. That's hex, so you can double up the columns into 20 bytes and worry about windows and other effects elsewhere.

 

When I mentioned oddly shaped rooms, I wasn't thinking of visual hacks, I was thinking of actually building the level out of geometric shapes. It's probably excessive, especially if the static level data can stay in ROM.

 

I'm going to see if I can explain in a bit more detail. I had basicaly had this idea before but never flushed it out. (it still needs to be flushed out a bit more if it is even possible. I call it point casting instead of ray casting. The idea isthat you have a set of point data in ROM which could be around 100 to even 200 points depending on the level size.

 

Each one has 2 bytes representing an x and y cordinate. there mayalso be other data to each point as well indicating barriiers or something. your player or point-of-view has an x and y cordinate as well and a directional viewing degree (which way you are looking). the idea is to calculate the distance of each point directly in front of you and store the values af each and how far left or right from center (the middle of your viewing angle.)

 

when you have the info you need from this then it is time to modulate your line. I have enclosed a crude sep-by-step diagram of how I envision it. The first step is to figure out how many points there are in your view, how far left or right from center view they are and their distance. lets say there are 6 points cancualted. each of them are spaced out in relation to the screen or field of view. there may be 2 of them near the left and one near center and the other 3 are evenly spaced apart on the right side. (just an example)

 

now each one has a distance from you and are relayed to the screen as follows. the closer the point, the higher the peak, the farther away, the lower the peak.[stage 1]

 

once the line has been properly modulated to reflect the point data, then the modulation data is fliped verticaly in values. [stage 2]

 

Now comes the fun. when the upper and lower lines are in place (memory, calcualtions, whatever) Then comes the fillin data.[stage 3]

 

this can easily be 2 bits for each collum. 40 groups in total. one instance for a door, one instance for shaded distance (basicaly out of range for calculations where no wall exists yet) and 2 other types of changes to walls. [stage 4]

 

I hope this helps out. I can be hard to follow my thinking quite easily.

post-10601-1209449956_thumb.png

Link to comment
Share on other sites

Ahhhh. That's actually quite nice. Using points instead of blocks is a lot more flexible, and the way you've done non-ortho walls is orders of magnitude better than the terrible methods I've been thinking up for it.

 

I think I'd still use a hybrid method, filling 20 or 40 bytes with per-column data instead of trying to unify the 'modulated' line. Find the points in your field of view and in range, construct lines, and then build the columns based on the highest (i.e., closest) line going through it. The problem I see with finding and drawing from the modulated line directly is that partially obscured walls need to be detected and dealt with to avoid having the line jump around. I've taken your step 2 and marked where the points are:

 

post-8547-1209452362_thumb.png

 

The ones offscreen - outside the field of vision - have to be found and accounted for. The ones 'inside' the wall can throw the final drawing algorithm if they're not recognized as part of a seperate wall section.

 

If those problems can be dealt with reliably, this algorithm may be more efficient than a straight raycaster. The only potential snag I see is that complex rooms in front of you will take a long time to sort out even if your face is pressed up against a wall and all you see is solid brown. With rays you have consistently mediocre performance, but points could vary wildly without conservative level design.

 

Not to one-up you, but I've been sitting on an idea for a few days because it's absurdly high-end. Maybe a 5200 or Supercharger idea, just for the RAM involved.

 

post-8547-1209453171_thumb.png

 

I tried to go past what the 2600 could do, and figured it could fake the walls for variable-height raycasting as a reasonable extension of my method (or yours, now), but floors would be completely beyond it. Even in Doom and Rise of the Triad, floorcasting is the least efficient part of the engine, and once you have it you have to store it. Floors & ceilings can't be done per-column or per-scanline with any sort of quality, and using huge pattern blocks was a hack not worth its limitations. In comes the ball. You can't texture or color the floors, but it's not like you're texturing the walls - just a hint indicating the presence of a wall is enough. The idea is explored in the middle six shots. Top pair: wire & filled walls with full lines indicating ceiling/floor jumps. Second pair: 'sketch' edges indicating ceiling/floor jumps. Third pair: dashed lines indicating ceiling/floor jumps. I'm fond of the third method because it's constrained; there is a definite maximum number of 'edge hint' points to be drawn, and they can be handled every few scanlines. Also note that the last two methods have occlusion, so the walls don't show through the floor or ceiling.

 

The set of images on the far right shows an example conversion, including the simulated effect of distance-based flickering for darker depths.

 

The final image (not the white one, but the red above it) represents about 80 bytes of information. Every column starts and ends at some value from 0 to 63 (doubled pixels), requiring two bytes for each of 40 columns. The edges are stored as four-bit horizontal positions every fourth frame, taking the unused high bits of the first 32 column start-end byte pairs. Drawing is a matter of turning a column on between its two high/low bytes, plus the placement of a single horizontally mark on every fourth scanline. Occlusion is done per-column, clipping the far walls by finding the height of near ceilings and floors. I'm not actually sure what should happen if two edges want to use the edge marker on a given scanline. It's academic, really, since the Atari barely has enough memory to store the absolute necessities, let alone the CPU power to make the game worth playing.

 

Anyway, it's really late and I'm incredibly tired. Thank you for explaining your method visually, it helped immensely. It may be the key to good performance if any of this ever ends up as more than idle banter.

 

Edit: the example picture is wrong. There's no way this engine could do a wall over a hallway, as in the bottom right of the screen. The equivalents of Doom's High and Low texture spaces would be black, with only ceiling-to-floor walls and the hints of edges. When casting a ray, you keep the first floor & ceiling height change as your visible edge, the highest floor and lowest ceiling as your occlusion limits, and the first wall encountered as the stopping point. I'll draw proper examples with maps tomorrow.

Edited by Mindbleach
Link to comment
Share on other sites

I have been trying to bring this concept down to a working solution and have came up with some atributes to point data that may help to properly calculate rooms and other features as well. this will also alow predefined texture types to fill certain areas. this includes windows, doors, ceiling objects, and hidden walls as in walls that can move like doors, etc. So far I have came up with about 7 types of points. This also depends on if we can set up drawing ruls to acomodate them and if all types are neccesary. Sofar, for the simplified first level of DOOM that I created, I calculated about 190 points of data total. Each point has the following atributes. X cordinate, Y cordinate, type of point (this allows the engine to treat each type diffrently) and an angle of trajectory away from open space.

 

To describe this in more detail, I will give a few examples. Asuming that 0 degrees is east, 90 is north 180 is west and so on. Let us say that there is a corner that is a 90 degree angle with one wall toward 90 and the other toward 0. The angle that would be in the data would be 45.

 

Now lets asume that there is a corner that is just the opposite of this there the open area is only 90 degrees with one wall going 180 and the other going toward 270. Thisangle recorded in the rom data would also be 45.

 

The basic idea is that this angle represents the center of the angle of a wall corner that is facing away from an open area. But the cool thing is that any point in the data will not ever be used for calculations if the angle points tward you. It will automaticaly be omited from calculations. the only way it would be used is if you went into a room where the angle of a point faced away from you. And any angle that was far off and did face toward you, would simply be out of range to calculate anyway.

 

I do hope however that a grid of 256 by 256 would be large enough to create a game play area. I will test some ideas to that end later.

 

I have enclosed a png of some of the work I did to come to some of these conclusions.

 

black is walls

brown is a ground barrier

red is windows

orange is doors

purple/pink is ceiling objects (hang up above)

blue is hidden coridors (fake walls)

and green indicates dangerous floors (like acid or lava)

 

being able to come up with ways to display these things will be tricky to say the least. but some of it may need to be omited because of hardware constraints.

 

post-10601-1209530317_thumb.png

 

 

On a side note, I was thinking about actual framrate in relation to the games framerate. If changes were made to the games framerate every 6 actual frames then we would have 10 frames a second. id they could be squeezed into 5 frames we would have 12 frames a second. I like this number best.

 

5 frames should be enough time to do most of the things we are postulating. but for most of this time we are spending redrawing the screen each frame and we have to keep all that data on hand while creating new data to inturn switch to after the fifth frame and then start over again. there are many things that must be done to complete a full frame. First off, where are we? we need to always know where we are in relation the the environment and calculate all the numbers for the room or the imediate space we are in. Then we must populate the room with the things we want in it and set all the rules for how thoes things interact with each other. The biggest thing is calculating the movement through a 3D space or rather the movement of a point on a 2D plane in the direction it is traveling in relation to the obsticales around it. And we can forget doing the whole playing area simply because we don't need the whole thing at any given time and due to the hardware being unable to do this all at once anyway. So we should have a plan of attack of how we plan to do this before we get in over our heads. I will try to build a diagram for creating a kernal or rather the overall 5 frame program loop that will alternate between 2 areas of memeory for the needs we need.

Edited by grafixbmp
Link to comment
Share on other sites

I've taken your call for a reality check to heart. Here's the basic outline for a naive, ortho, single-height raycasting kernel:

 

post-8547-1209748575_thumb.png

 

This is somewhat simplified from the version I have on paper, which takes corners & floor/ceiling heights into account. It's a bit more high-level than it should be, lacking such details as incrementing the column number after finding and writing the wall height for a given column. Every line that starts with "get" involves some sort of table lookup or nontrivial math, but each happens only once per ray. Most of the CPU drain comes from stepping and checking. Each step is two or four additions, depending on whether the X & Y coords of the player take up one or two bytes each, and each check requires some minor conversion (e.g. bitmasking as a modulus) before reading part of a byte from ROM.

 

Let's we assume we are very bad at optimizing and give ourselves figures of 100 operations overhead and 50 operations per step. There's just over 5000 cycles in a normal VBLANK, plus whatever we add in by turning off the screen early. We need at least 7 columns per VBLANK to make 10 FPS. Division says that' just over 700 operations available per column. Subtract 100, divide by 50, get a maximum draw distance of 12 unit steps. The maps to be used are perhaps 32 units square, so that's not terrible despite ample room for improvement.

 

Please shoot me down if I've overestimated the 2600's ability to add numbers, apply bitwise logic, and look up values in ROM, but I'm feeling strangely optimistic. If the screen-drawing algorithm isn't overzealous, this crazy scheme just might work.

Link to comment
Share on other sites

I've taken your call for a reality check to heart. Here's the basic outline for a naive, ortho, single-height raycasting kernel:

 

post-8547-1209748575_thumb.png

 

This is somewhat simplified from the version I have on paper, which takes corners & floor/ceiling heights into account. It's a bit more high-level than it should be, lacking such details as incrementing the column number after finding and writing the wall height for a given column. Every line that starts with "get" involves some sort of table lookup or nontrivial math, but each happens only once per ray. Most of the CPU drain comes from stepping and checking. Each step is two or four additions, depending on whether the X & Y coords of the player take up one or two bytes each, and each check requires some minor conversion (e.g. bitmasking as a modulus) before reading part of a byte from ROM.

 

Let's we assume we are very bad at optimizing and give ourselves figures of 100 operations overhead and 50 operations per step. There's just over 5000 cycles in a normal VBLANK, plus whatever we add in by turning off the screen early. We need at least 7 columns per VBLANK to make 10 FPS. Division says that' just over 700 operations available per column. Subtract 100, divide by 50, get a maximum draw distance of 12 unit steps. The maps to be used are perhaps 32 units square, so that's not terrible despite ample room for improvement.

 

Please shoot me down if I've overestimated the 2600's ability to add numbers, apply bitwise logic, and look up values in ROM, but I'm feeling strangely optimistic. If the screen-drawing algorithm isn't overzealous, this crazy scheme just might work.

 

Well the ability to do bit wise boolean operations is easy for the cpu and addition is also part of its specs as well as subtraction (multiplication and division are what get ya). But I had been thinking about framerates and can tell you this. If you want 10 frames a sec you will have 6 actual vblanks worth of space to work with. if you want 12 frames a sec you have 5 and if you want to shoot for a whoping 15 frames you only have 4. I think 12 frames a sec is a steady round number if you think 5 vblanks worth of a single frame is enough to work with. so either 6,5,or 4. I was also thnking about rom size like 16K including extra ram as well.

 

Now I wasn't sure how you wanted to store the actual levels in memory but I had been working on some intresting ideas. I redid my first doom level map in the post above to fit into byte sizes of 0 to 255 by 0 to 255 and it looks quite good. I just hope it is big enough to moove around in. I have also been painstakingly ploting out all the points of the corners by number in a text document. I am almost done but was thinking about adding a few oyher plot points features to it. I also went back to the old DOOM95 game and played through the first 2 levels to get a feal for it again. The one thing I am worried about when it comes to in a sense porting DOOM to the atari, is all the games atributes. Will the engine be able to keep up with each diffrent thing (or atleast most of them) or are you just more intrested in just doing a simple maze game? Either way you go, I sure would love to atleast have the first level of doom playable on it. I was also thinking about doing about 5 screen demos shots of this socalled engine as if it were a DOOM port and see what ya think of them. I may have figures out how ti do a few of the sudotexture/screen effects for a few of the featured and as a bonus how would you like some areas where you can go outside or even darkened areas where the lights are going out? these may be possible in a simi fasion.

 

Any way get back to me and let me know what your thoughts are. I like where you are going with the design sofar. But remember in order to have an actual game, some of the programing space needs to be left for enimies and their respective movement, weapons and other game play features like this as well.

 

I will post the image I redid and as you can see it is 255 by 255

 

post-10601-1209796060_thumb.png

Link to comment
Share on other sites

SOrry to doubble post but I got tothinking about something. I am not sure but I think all the data needed for a single level could be contained in 1K of memory (ROM). that being the case, I think it wouldbe rather cool if we set up a type of WAD system like DOOM itself so that other people could make their own levels. That way, this could be a rather popular engine if it works out. And I finnised most of the plot points in text for the first level of doom and I am rather sure they are all there and are correct. I only ploted out the points and assigned each a type of point. I listed them from left to right and from top to bottom for the solid structures. All the other types of points are listed in groups.items, enemies,floor and ceiling, etc attributes are independant from the main bulk of the data. If you want, I could zip it up and post the document. let me know.

 

So far I have a total of 220 points 145 of which are the solid walls and other things, that are solid: doors, outside walls, moveable walls (hidden walls or areas), exit door.

 

 

 

UPDATE: I've almost finished one demo image of the acid room as I call it from The Hanger level and please note I did this by sight and in no way calculated anything so don't worry if it doesn't look right. This is just a sampling of a few ideas I have had for the types of graphics me and Mindbleach have been working on. I have one item and one enemy firing a fireball along with your first weapon. Hope you guys like it. On a side note, i didn't have time to do the HUD but the space is there for it.

 

I've now added the first part of the level drawn by sight as well. THe real thing probably won't look too much better than these.

 

A third image now with the newer parameters. Hard to tell but the sides are always a full bar so this is not calculated and every PF pixel is double height. I have not added any shading texturing, which would be a hack anyway. This is by sight as well but of the image you had in your post of doing a type of edge imply for ceiling edges. I hope you like it. The only added thing from normal imaging is the ceiling objects. I've got a few ideas on these later if you ever get back to the forum.

 

post-10601-1210139896_thumb.png post-10601-1210220793_thumb.png post-10601-1210898467_thumb.png

 

For this magnitude of screen manipulation, a bankswitching type with extra ram is needed for a screen buffer for the playing field and the sprites as well. The sprites will need to be flickered as well with some kind of smart sprite rendering algorythm where every other frame displayed a diffrent sprite when they cross horizontal paths and because a sprite could pass behind one object drawn with the playingfield while another object drawn with the playingfield is behind them, a sprite mask table will be in ROM which will fix all sprites in the buffer so they look right. I just hope 5 framses is enough time to render everything and enough time to load all of it. we only have to store half of the playing field unless things on the ground are diffrent than the top and vice versa. Now if 5 frames are used for a single frame, this may very well through off sprite flicker unless a way can be created to divide up 5 frames worth for the sprites correctly.

 

Here are some things that need to be found out. How many cycles for each type of loading and writing does it take for 6 bytes (one scanline) and for sprites if both are used, sometimes they need to just be written and others they need to be masked first and then written. For some items the missles will be used and unless they are drawn by themselves, will always default to the colors of their respective sprite for their scanline. A good way to be sure the perspectives are correct needs to be made so that missles and sprites are increased in width correctly as they get closser. The weapon hand os done with one sprite that is doubbled in width.

 

Also, since the screen needs to be buffered, then things can be single heigth playfield pixels as well as the spritesbut for the sprites, as the get closer, could be double or quad pixel high. One other thing that I was thinking about... If a window or doorway looks out onto an outside area, every scanline along the window or doorway area needs to be on and only then can the color change to blue shades and be seen through the doorway or window the same for the opposite effect.

 

One more thought and I'm done. So that there will be less room on screen which means less computation for the playfield, a message bar could be at the top of the screen for info to be displayed. Once again I hope 5 frames is enough space to do all of this. With heavy optimizing and squeezing every clock cycle out of normaly unused areas for programing, I bet this could work as long as the game levels are made to conform to the limitations.

 

Oh almost forgot that outside wall need not be shaded and inside walls canbe shadded single double or quad increments as illistrated in the mock images. I'm still not sure if the single should be offset or not. This can be done with masking too. And now I am thinking that a larger type of ROM size should be used with the extra RAM included. I will have to redesign all the levels without vertical scaling so no ups or downs except for some type of elevators of some kind. We may need sprite designers help for the things in the levels. But this will have to wait untill later.

 

Update: I upgraded the demo image template a bit with some standardizations and accuracy of pixels. with this new image, I will redo the former ones and hopefuly do more. I centered everything and intend to do double PF pixel height from now on. this will make sure there is enough memory for all. I would hope that it will be possible to keep single sprite pixel height though. I also added the message bar and fighured that most messages should me pre-wrote in ROM.

 

The new one has 7 scanlines for text across the top, 29 scanlines at the bottom for the HUD, and the middle is 156 scanlines with this dividedby 2 into 78 scan lines for half the screen. With each PF pixel at double height, this gives 39 gameplay pixels for half the walls with the other half duplicated plus any diffrences with additional memory. If 6 bytes are used for every 2 scanlines, then it takes 234 for half the screen and just flip the order which it is drawn and have the bottom. it would take 468 bytes to cover the whole screen for the playingfield or to have 2 drawing buffers.

 

post-10601-1210614555_thumb.png

Edited by grafixbmp
Link to comment
Share on other sites

I think you're overshooting what the 2600's capable of. Floorcasting is not a pretty business, so unless you've got some very nice algorithms I'm unfamiliar with, that and your sprite worries could kill any chance of a workable framerate.

 

In terms of RAM - if we're going to cheat like engineers and say "just add hardware," Why not go the full nine yards and do texturing? It's just one-dimensional stretching, and it needn't be pixel-perfect so long as the wall's the right height. Perhaps a more Wolf3D-like use of wall shading? I know that game did it with separate textures, but here we could make north-south bright and east-west walls dark for clarity... not that your map system has anything like that implicitly. Maybe we should consider this a Supercharger game...

 

That hanger picture is sexy, by the way - throw in some proper multicolor sprites and this could be a high-speed 7800 game.

 

I'm going to keep thinking of this as a vanilla 2600 game. Bankswitching, sure, but not more than 16K.

Link to comment
Share on other sites

I think you're overshooting what the 2600's capable of. Floorcasting is not a pretty business, so unless you've got some very nice algorithms I'm unfamiliar with, that and your sprite worries could kill any chance of a workable framerate.

 

In terms of RAM - if we're going to cheat like engineers and say "just add hardware," Why not go the full nine yards and do texturing? It's just one-dimensional stretching, and it needn't be pixel-perfect so long as the wall's the right height. Perhaps a more Wolf3D-like use of wall shading? I know that game did it with separate textures, but here we could make north-south bright and east-west walls dark for clarity... not that your map system has anything like that implicitly. Maybe we should consider this a Supercharger game...

 

That hanger picture is sexy, by the way - throw in some proper multicolor sprites and this could be a high-speed 7800 game.

 

I'm going to keep thinking of this as a vanilla 2600 game. Bankswitching, sure, but not more than 16K.

 

 

Well traditional ray casters were designed for higher end systems. You should check out Merlin's walls for the 2600 if you haven't already. This is an actual raycaster that has an incredible framerate but it also has been created to display walls with the actual screen turned 90 degrees for ease of rendering and is rather blocky to boot and righfully so cause I bet it only uses the system RAM.

 

As for adding extra RAM, i'm not sure what you mean by cheating cause even bankswitching itself by that definition is cheating and people have added extra RAM and ROM to countless computing systems for decades. NES, SEGA, SNES which also had faster co-processors as well. Even the N64 had a 4 MB RAM expansion along with the Commodore 64 which also had a faster CPU co-processor addon as well. They're both memory, just one you can change and one you can't. I don't see the need for texturing though cause for it to be playable is just that everything needs to be implied and not neccessarily detailed. Which brings me to the floor layer. This idea isn't a traditional texturing but a simple hack of ever other scanline having its pixels turned on for places where the floor has a hazzard and normal ground is omited from this process.

 

There is one thing to remember about creating this type of engine, or something like it, especialy for the Atari 2600: Most good game engines for the systems usualy use some sort of hack. And there is nothing wrong with hacks. Also since very little if any sprites will be drawn for the top area of the screen, this gives even more room for programing aelbeit very little. Remember that when ray casters were first popular, high end texturing was done on all surfaces with alot of other atributes as well to process. We won't be having to do near that much here and anything we do that constitutes a texture is really a hack. To get distance shading besides other types of texturing, all textures will be done with hacks. Like if a vertical row of pixels are defined to be at a particular height, then every other pixel is omited from the bytes with a mask and the same goes for the next level up where every 3rd pixel is omited and then every other 5th pixel is omited for the next size level. The floors are done the same way as the walls except that the data gathered for floors is treated to a special hack every other 3rd line and where ground should be then thoes pixels are simply omited. I was also thinking about the slopes for the angles of the difrent walls and started coming up with a visual of a table that could be in ROM like 2 over and 1 down or 1 over 2 down and then 2 down again. With a table in ROM that could contain this kiind of data, then just check the distance and use one set of data from a table that fits within thoes parameters. I will post the image that I came up with. Not sure if this could help or not. But its always good to think out of the box. This is what makes pushing the limits of the system so appealing. Windows can be done by using the same slopes for the walls but bringing them closer to the hoizon..Floor barriers are done the same way as a window except where the top of a window would be, will be omited as well. For ceiling objects, the opposite of floor barriers can be done. To get all the values you need to create the data that goes on the screen can be the easier part but creating the screen before it is displayed could be difficult.

 

For this reason I think this would be well suited for the new 4A50 type of bankswitching at 32K with extra ram. http://www.casperkitty.com/stella/cartfmt.htm This type of cart has the ability to write data directly to the RAM specificaly for writing directly to the screen and is an excellent buffer to put higher detail onto the screen. I am glad Supercat brought this to my attention. And I know that 32K seems like a lot but I don't see the reason in having a great engine without enough levels to justify its creation. Also for the game to not be so repetitive, it should have plenty ot features for replay value as well.

 

The image does not have all possible angles but it has several to get a general idea.

post-10601-1210310820.png

 

I have figured part of the area for the playing field that will be used for the game play which comes to 158. half of this is 79 fo you will need 474 bytes to store 79 scanlines high and twice that to have the whole screen and double that number to buffer the lext frame. Thats pretty hight of a nunber to have and calculate. but if the laying field was always 2 pixels high, the value would have to be rounded to 39 and you would then need 234 bytes to storethis and double that for both top and bottom. This would be 468. and double that to have 2 places to store as a buffer which would be 936 bytes. this will leave 88 bytes left for sprite data and any other things you will need. that is to say if you were working with only 1 K of extra ram. See if these number help any.

 

I also calculated what I believe to be all the point you need to calcualte for distance and general location left or right from you to display the first screen of DOOM but remember that you viewing angle should be quite smaller that what is shown so you could get away with less. Oh and btw, I figured that small items like potions and helmets and such should only be shown when you are very close to them and then only displayed with the missle.

 

post-10601-1210313873_thumb.png

 

UPDATE: I've got a few more ideas that could help things out even more. Fist off I decided to group all the points into sub sectors of the full level so that while in a given sector no outside points of the sector are even looked at untill a sector boundary is about to be crossed. and If I can find a good way to eliminate parts of objects that are on the backside of the area that you are looking at, then they can be ignored as well through the full set of calculations. And there could also be a maximum distance boundary from your location that is ignored as well as any unnecesary points behind you. I was also thinging about if a secondary set of equasions could be used for where when you know where a point is for your given location, then when your location changes offset the original calculations to compensate for the players shift instead of recalculating each individula point and angles. But first and foremost the sectors will be the biggest help cause if you don't need it, don't use it untill you need it. And lastly, the angle of screen viewing will play a part in eliminating points you won'tneed untill you rotate the player. I hope some of this camhelp out to speed up the process by eliminating un needed equasions.

 

 

How about this:

 

Pre setup (begining of a level) setting of current sector and first full screen and variables

Frame 1

 

check stick movement

if yes to movement begin ploting new calculations of envirnment for new location to be displayed for screen [1] (between 15 to 20 points) for current sector and eliminating unused data while embeded with display of screen [0] and current sprite set

 

After screen is finished displaying check for collisions and store values then focus on all calculations eliminating all unused portions and some environemnt calculations for displaying (some actual display data may be written to the new buffer)

 

Frame 2

 

continue unsing calculations for next 20 to 30 points and possibly write more data if avaliable to be written all while displaying next phase in current screen data for screen [0] once screen is finished check for collisions and store data then complete calculations and dedicate all remainding time to drawing the screen data to screen [1]

 

Frame 3

 

For this area, display next phase in current screen data and continue drawing next data to screen [1] when the halfway point is met, stop and check for added features like ceiling , floor barriers, and closest items. begin altering written data to conform the changes in the lower part of the screen that apply when screen [0] is finished drawing check for collisions and store data then continue full with adde features for upper and lower areas. copy concurent parts for the bottom that would be diffrent from written top data while making changes with a mask and store begining value for data lines that are diffrent for the bottom.

 

Frame 4

 

Display next phase in curent screen while beginning the calculations for closest items for use with the sprites and setup sprite display patterns in memory for next frame. set color codes and check for bariers to next sector. And reset barrier values acordingly. when screen [0] is finished check for collisions and store data.

 

Frame 5

 

Display last phase in screen[0] and check current items ,weapons, collisions and alter sprite data acordingly with exeption alterations for changes in game (explosions, items aquired, HUD, message board) check barriers in gameplay for wall contacts and apply boarder blocking to stay in the rooms (revert back to previous screen data) apply movement to enemies and firing patters. once last screen is done check for collisions and store (all collisions will be used in next set of frames) Updata message rendering if needed and updata HUD data for next screen. If all checks out, swap to next screen and repeat from frame 1. and repeat for next new screen.

 

 

Now I may have left lots of stuff out but I am hoping I got most stuff in and in a decent order but I am tired now and may not be thinking strait. But what do you think?

Edited by grafixbmp
Link to comment
Share on other sites

I once again found a copy of merlins walls and went throughit again. super fast gameplay but WAY too blocky. I also found an interview with the company ebivision (just 2 guys) who released it, only one of them actualy made it though. The intterview is at http://www.gooddealgames.com/interviews/int_Bacher.html

 

Here is a part of the conversation:

 

MT> Ebivision created the first realtime 3D game for the Atari 2600 -- Merlin's Walls. Did you discover any programming secrets or 'angles' in order to get the 2600 to perform in a manner that it was never meant to perform?

IB> The answer is completely given in the book sealed with the cartridge of Merlin named "3D for VCS - why and how" which is a kind of making of Merlin's Walls. I used a principle found by searching a way to ask to the VCS to do 3D as fast as possible. This 3D doesn't use meshes or things like that for the objects. The trick to making the VCS able to do that is that the 3D world is maximum simplified to have the less computings to do. The walls are in a 16 x 16 grid, the mathematic computations are made on 1 byte precision and the graphics have been turned of 90° to be nearer to the TV system (which scans horizontally)... everything have been done in that way to communicate as quickly as possible to the 6507 chipset. And hopefully, it could be possible at 60 frames/second. Since this time, I've found other ways to do 3D, to have the picture right (not turned of 90°) and to put textures on the walls. This means to have only 12 frames/seconds and a very low resolution of 40 x 24. It works on paper, but it needs a lot of time to program it... so maybe one day...

 

I'm not sure if he is just using the systems ram or extra ram as well. I bet that with extra ram, a higer resolution could be done at 12 frames a sec. And with other types of 3d techniques used, it could be more detailed and pull off more sprite graphics and objects too. I still think it could be rather cool to design it to use a WAD type system so others could make there own levels. we just have to design it right and lay down the ground rules like limited angles in rooms, limited room accents ie: ceiling objects, floor bariers, windows, and floor hazzards. Not to forget a limited amount of items, enemies, and barrels. I had thought about barriers like seethrough fence walls but this may be harder than it seems so may have to scratch that.

 

I was also calculating clock cycles amounts that we have to work with and these are the numbers I came up with.

 

These are for the CPU not the TIA colorclocks. Between the vblank and overscan, there are 5,092 CPU cycles. Each scanline has 22.66 cycles that are not visible for a total of 4350 for 192 scanlines. There are 76 for each of the 3 v sysnc lines for a total of 228. This does not include the visible screen. We have 5 times this to work with for one frame of this engine. That is ALOT to work with and may very well be possible. I still think we will need some extra RAM on the bankswitched cart mode we use. And alot of the cycles during the screen will be taken up with the kernel but these are the numbers we have to work with. Just for the Vblank and overscan periods for 5 frames comes to... 25,460 CPU cycles. I sure hope this is enough besides bank switching and load and store times.

Edited by grafixbmp
Link to comment
Share on other sites

I figured out some more for the level designs for the layouts of each level. The breaking up of levels can be done as follows. First and largest order of magnitude is quadrants. Obviously there can be a maximum of 4 and each quadrant is broken into sectors. These sectors aren't grid based but room based. Each sector is stored in a particular order where you have PF based objects that are basic in design and then added features that are PF based that require difrent processing and finaly sprite based objects like items, weapons, and enemies are broken into persistent and relative. persistant are always visible in render range and relative are visible within close proximity. Each sector has the items only for its area and nowhere else.

 

For the first part of the level in ROM, the addresses for each starting place of each quadrant are listed alond with color palette and and a few other attributes. At the biginning of each quadrant are listed the starting places for each sector and in each sector starts with an address map for basic walls and accent object are next then sprite objects are last. Every quadrant has its own set of coordinants on difrent planes. This being, Some large levels will pull data from 2 diffrent quadrants where they cross coordinants and will pull from 1 sector from each. Since the system just rolls over data after 255, then the math should still work from one Q 1 S14 to Q2 S1.

 

The only reason I present this level design template, is to eliminate unneeded data from processing so to keep things moving so as long as the overhead doesn't take as long as it would otherwise. In a way, this is similar to bankswitching itself. So, each level would be like if it were 9 bit by 9 bit grid. However, ti looks like each level will have to keep each quadrant to a 1K by itself. So a full 4 quadrant room will more than likely have to be 4 K. This could put a damper on things for DOOM in general. But I doubt that many of the levels go beyond a 2 quadrant space or even a 3 at most. We will just have to wait and see how the data works out. I would hate to get this too large. But on a sede note, I asked a question once about bankswitching and got a cool piece of code that help well for jumping back a forth in a bankswitched cart.

 

http://www.atariage.com/forums/index.php?showtopic=122388 vdub_bobby 's post with a nice subroutine for calling other subroutiones from any bank whereever. I like it.

 

I have thought about one other thing that may need to be done for a few reasons. I think it may be agood idea to do only 38 pixel wide screens instead of 40. Basicaly have the far left and far right colums always turned on similar to this (the same image posted above):

post-10601-1210890680_thumb.png

 

for 2 main reasons 1: is this will be 2 less colums to calculate and 2: to somewhat obscure any H Move black lines cause you know we are bound to have them. If no form of gameplay happens in thoes areas, then black bars can be easier overlooked. I know this limits the playingfield even more but it may help out with thoes few remaining precious clockcycles we need. Afterall even the SNES and SEGA 32-X versions had boarders around the gameplay parts.

 

OK This is the bankswitching scheme I have been looking for specificaly a screen buffer using the 32K type. It has 2K RAM and aparently flash too perfect for doing a 3D game among other things. http://www.casperkitty.com/stella/cartfmt.htm

Edited by grafixbmp
Link to comment
Share on other sites

I was remembering the hoax of Duke Nukem Forever for the 2600 and I just have to laugh cause if this project here can be done, it could even make that hoax a reality. I think if some hard work is put into this and few 'negative nancys' or ney sayers try to claim "It can't be done", this could possibly have aproval from ID but that is nither here nor there... yet. I can only imagine how many diffrent 3D games could be done with an engine like this one proposed. I bet many thought that Andrew's Boulderdash engine was not possible but it works and rather well I have to say. I had a previous game in mind to utilize his full color tech/process but my mind has shifted full swing to this for now. I just wish some others were intrested in this idea. Seems many aren't intrested in anything I try to bring to the table. Only time will tell I guess. I don't nor have ever claimed to know much about programing concepts for the Atari. I am still learning as many here are. But I know I like pushing the limits of hardware as far as it can go and will try to learn more in the process. I have already learned so much now. However, I can't do it by myself. That why I ask for some tutorial help along the way. Thanks anyway for all everyone has done. I'll keep going as far as I can and maybe help to bring 3D to the 2600 someday.

Link to comment
Share on other sites

I have done some preliminary work for a DOOM title screen. This is resized from the original and the logo is slightly repositioned. I did this for a 6 sprite spread of 3 player0 and 3 player1 along with the 2 missles at the end for a 50 pixel wide shot. But if the 2 missles arent going to be able to be done, the I can cut the left and right sides off for 48 only. I hope my RGB separation and dithering are accurate. Here they are with the original image.

 

Now I just need to feed the data into the code for ICC and the title screen is done. post-10601-1211176773.png post-10601-1211176788.png post-10601-1211176809.png post-10601-1211176831.png

Edited by grafixbmp
Link to comment
Share on other sites

Can't wait to see that title screen, good work :thumbsup:

 

This isn't exactly a BIN file but in creating this, it allowed me to arange the data in the proper displaying order for the sprite. This can give you a reasonable idea of what to expect to see. This is BTW the actual size of the pixelsa data wise for the atari. That is why it is so small like the others.

post-10601-1211254548.gif

And here is one at twice the size. It may be dificult to make out the image with this one. If only it would animate faster.post-10601-1211290050.gif

 

I now need to write code that will display 6 sprites (3 of one and 3 of the other) and the 2 missles at the end. I can load both of the missles with one shot can't I?

 

update: I have been going over the code for the 2 marios bouncing and find with the movement added to it, it seems over complicated for my needs so I will try to simplify what I need for my sprites. I guess I will have one scanline dedicated to the position of the first sprite where I need it along with tripple duplicates then another scanline for position of the second sprite also with tripple duplicates and then one line for missle one and another for missle 2. Then I will have display code that start on the first scanline I need with 7 grooups of indexing with the 2 missles out of the way first with one shot and then wityh the standard 6 sprite display kernel probably like the score trick but I thought that Andrew mentioned that he needed to use an iligal opcode LAX for some reason. I see it in the source but haven't scrutinized it that far to find out. Like I said It seems over complicated for my needs. I only have to do this for 64 lines and then wait untill the next frame for the next 64. Because I am doing 64 lines with each sprite section being in their own table, I only need to index up to (or down to) 64x3 that way I can keep the indexing to 192 bytes each. I'm still worried about the missles but the position, and color would be already taken care of. I just need to load them each time with the proper data each line. In andrews code, he has every scanline executing with exactly 76 cycles each time through.

 

Here is the original code :

.LABG       lda #GREEN          ; 2
           sta COLUP0          ; 3
           sta COLUP1          ; 3

           ldy LoopCount       ; 3

           lda (.S1),y         ; 5
           sta GRP0            ; 3
           lda (.S2),y         ; 5
           sta GRP1            ; 3
           lda (.S3),y         ; 5
           sta GRP0            ; 3

           lda (.S6),y         ; 5
           sta Temp            ; 3
           .byte $b3,.S5       ; 5  --> lax (.S5),y
           lda (.S4),y         ; 5
           ldy Temp            ; 3
           sta GRP1            ; 3
           stx GRP0            ; 3
           sty GRP1            ; 3
           sta GRP0            ; 3
           
           dec LoopCount       ; 5
           bpl .LABB           ; 3
   
           bmi EndDraw

.LABR       lda #RED            ; 2
           sta COLUP0          ; 3
           sta COLUP1          ; 3

           ldy LoopCount       ; 3

           lda (.S1),y         ; 5
           sta GRP0            ; 3
           lda (.S2),y         ; 5
           sta GRP1            ; 3
           lda (.S3),y         ; 5
           sta GRP0            ; 3

           lda (.S6),y         ; 5
           sta Temp            ; 3
           .byte $b3,.S5       ; 5  --> lax (.S5),y
           lda (.S4),y         ; 5
           ldy Temp            ; 3
           sta GRP1            ; 3
           stx GRP0            ; 3
           sty GRP1            ; 3
           sta GRP0            ; 3
           
           dec LoopCount       ; 5
           bpl .LABG           ; 3

           bmi EndDraw

.LABB       lda #BLUE           ; 2
           sta COLUP0          ; 3
           sta COLUP1          ; 3

           ldy LoopCount       ; 3

           lda (.S1),y         ; 5
           sta GRP0            ; 3
           lda (.S2),y         ; 5
           sta GRP1            ; 3
           lda (.S3),y         ; 5
           sta GRP0            ; 3

           lda (.S6),y         ; 5
           sta Temp            ; 3
           .byte $b3,.S5       ; 5  --> lax (.S5),y
           lda (.S4),y         ; 5
           ldy Temp            ; 3
           sta GRP1            ; 3
           stx GRP0            ; 3
           sty GRP1            ; 3
           sta GRP0            ; 3
           
           dec LoopCount       ; 5
           bpl .LABR           ; 3

EndDraw     rts

 

As it cycles through and counts the loopcounter down, it will return to the start of the 3. and then for every frame it starts its cycle at either the red, geen, or blue subroutine. I get all that. I want to rig the missles too, cause I once heard it could be done. I figured I should do them at either the veryend of this display for the next line or one if the first things before all this is done. Any thoughts?

 

I kinda wanted to keep things as they are without disrupting this beautiful work so I may have to rig up a pre subroutine before all this so I can keep the index register pointing to the right place so I should point to a new (.s7) first and load the missles well before all of this takes place huh.

 

I wanted to see how well it would look as if it was back to its normal dimentions so I redid a new gif with a diffrent sequence to it at more of a true size. This should be more as to what it should really look like. Unfortuantely, I don't have all the great tools at my hands so I have been doint the data by hand and it isn't pretty. I am afraid by doing it this way I will miss something. Anyone have any tools for transfering BMP images to byte size data for ICC?

post-10601-1211430256.gif

Edited by grafixbmp
Link to comment
Share on other sites

Meanwhile back at the engine itself, I thought some more about the process and am going to take another quality trait from Andrew's plate (if he doesn't mind). One thing for his boulderdash engine is that he only alters changes made to the screen which saves some unneeded processing and time as well. I think that with some specific equations geared tward how a 3D environment should look and move, thoes equations could save some effort in trying to recalcualte every spot on screen just by altering them every 5 frames instead of doing the full process evertytime. That way the original process is geared only for new points that come into range.

 

Later on I want to establish some data for an area with some rules and see if someone can manualy recreate the area as an image based upon the data and rules. If this checks out, then an engie could be created using the same methods. Granted that each final level will need to be simple enough as not to overwhelm the engine.

 

The idea is that for each piece of data that is curently in memory will just be repositioned based upon the new players location and the original distance from the player. For rotations, the distance will not change but the angle of view will so, for each piece of data that is at it's current distance will be fed into a calcualtion for the new altered image thereby creating a new frame without having to fetch so much new data.

 

The problem is making shure the calculations are made so that new data matches the old data that is alterd so that the aspect ratio on the whole area is the same from old to new.

 

I think most of the equations will need to be that of curvatures like, when moving forward, the closer the objects are the taller they get and the rate at which they do is faster too. The farther left or right from center they are, the faster they travel in thoes directions. And when rotations of the player happen, there would be a slight curvature to their move ment left or right. The curvature would be outward from the player and closer to the player on the sides. The one would be just a slight curve the farther away something is but the curve would be greater the closer the object is. The best example to this is that of flying through starfields. If anyone has experience with that kind of engine, that would be most helpful.

Edited by grafixbmp
Link to comment
Share on other sites

The only problem I see with this is, you have to account for worst case scenarios, the engine has to still perform properly when the most is going on that can. What if the player is moving constantly forward and left, in a circle? Then sprite movement and scaling, and playfield rotation and scaling are all happening at once. I don't' really know what I'm talking about so please disregard if this is stupid.

Link to comment
Share on other sites

Unfortunately, I don't have all the great tools at my hands so I have been doing the data by hand and it isn't pretty. I am afraid by doing it this way I will miss something. Anyone have any tools for transfering BMP images to byte size data for ICC?

I wonder if you could use the program mentioned here:

 

http://www.atariage.com/forums/index.php?s...t&p=1491393

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...