Jump to content
Andrew Davie

Wen hop? The Search for Planet X

Recommended Posts

Here's a new binary (Stella only, for now) with zooming/scanline, and a bunch of planets.

Use hold-SELECT to switch to next planet.  LEFT/RIGHT to change rotation speed.  UP/DOWN to zoom in and out.

 

 

So, how is it done?

 

Well firstly, it uses the engine that I'd previously shown - that one for drawing the Wen Hop game screen with all the flashy character animations and scrolling. It's exactly the same to start with - a "level" is unpacked to a screen buffer which is just a bunch of character #s used to define that screen. Whereas the wenhop playfield was 40 x 24 characters, with a scrolling 10 x 8 (ish) window viewport onto that, for the planets we have a 40 x 12 character area with a scrolling 10 x 12 (invisible) window onto that.  I copy the leftmost 10 character columns to column 30 onwards, so I get a "wrap-around" in terms of when I'm scrolling into that 40 x 12 area.

 

So now I have the planet texture unpacked into that 40x12 area ("the board") it behaves exactly as for WenHop itself.  That is, all the objects on the board animate and are processed, participate in collisions etc.  This is why you see dogecoin on some of the planets as they rotate, and the dogecoin are animating. It's just the original system in action.

 

So the "texture" is the same as the original WenHop screen that you play on, in technical terms. But in this case, it's hidden and just used as source data. So, based on the X scroll, I first "draw" the texture as a 10x12 window into that 40x12 "board" representing the planet surface. It's a rectangular, flat, scrolling window.

 

The next part is wrapping that texture onto the surface of a sphere. So, for this I wrote a small python utiltiy to generate some mathematically correct data.  All it is really doing is rendering a selected subsection of the rectangular texture map and showing it on the screen. That sounds difficult, but the technique is quite straightforward.

 

Let's cover verticals, first.  If you think about a sphere, and as you step down each scanline in a sphere, then the textured surface wraps around - of course. But the mapping of the scanline position to the texture pixel is actually quite straightforward. On a line-by-line basis, we know that ALL pixels on the line come from the same horizontal line in the texture map. So the real task here is just to find which horizontal line of the texture we're looking at, for each scanline. It comes down to some simple trigonometry; based on the curve of a sphere we can use pythagoras and trig to figure out the distance down from the top of the texture. That's done for each scanline, and so we effectively now ONLY display those texture lines which each scanline points to. And with that, we how have a horizontal cylinder onscreen.

 

Now it gets tricky. But not too much more so. The screen is drawn in two halves (left/right).  Each half is effectively a mirror in terms of the calculations, but with just a different texture offset (mirrored). So we'll look at only the right-side.  Now the earlier scrolling code took the rendered window-into-the-board to create the correct PF0 PF1 PF2 bytes.  In the planet code this is done slightly differently.  Rather than unpacking the potential 6 characters (catering for scroll) that we might see in this half, and copying 20 of those 24 pixels (with scroll 0..3 dropping off some) directly to the PF bytes (taking account of the weird PF format)... instead we only copy SOME of those 20 pixels. Consider the texture itself being a whole screen wide (i.e., 40 pixels for the sphere). We want to wrap this rendered 40 pixels onto the sphere itself, which varies in width from maybe 0 up to 30 or so pixels.  In other words, SOME of those pixels need to be used, and some discarded.

 

So, for each scanline I first calculate the width (in screen pixels) of that half of the scanline from the center. I know that I need to map those 20 pixels of the texture into that many pixels in the final screen display, and I'll have wrapped the texture around the sphere - for that line.  Trigonometry comes to the rescue again, and if you consider a single scanline half, but instead of looking head-on, we look top-down at it. We see half a hemisphere, i.e., a 90 degree sweep across the sphere. And we know that the 20 pixels of the texture map evenly onto the curved outer edge of that half-hemisphere.  So if for each pixel onscreen we know where it intersects that curved outer edge, we get a distance (horizontally) into the texture/surface map. We already know the line, from the vertical calcs, so now we are just getting the correct pixel in that line.

 

So, the python program aforementioned also creates a table for each scanline which is effectively a mask. It starts from the center, and specifies on/off for 20 bits horizontally. If a bit is ON, then we add a pixel from the texture. If OFF, then we skip that pixel.  And so, we get an effective gradated selection of pixels being dense towards center-screen, and sparser as it gets to the edge.

 

Put these two together - first the wrapping to a horizontal cylinder as described, and then on each line of that cylinder wrapping around a vertical cylinder (effectively) we get the combined effect of the both of them together forming a sphere. So, horizontal cylinder x vertical cylinder = sphere, I guess :). Anyway, that's how I did it. The actual calculations on the ARM are simple enough that i can scroll/animate/render the entire planet every single frame.

 

The rotation is achieved simply by scrolling over the original board, and letting the draw system draw from a window into the (wrapped) board as described earlier. When the scroll position becomes < 0 then I just flip it to the right edge (30). When it goes past the right edge, I flip it to the left edge (0).  It's seamless because earlier I'd copied the left 10 character columns to the right side.

 

To add to the explanation above, the scaling is achieved by first doing all of the above, but then after we've wrapped the texture onto each scanline half we post-process those 20 pixels with a simple linear scale.  Step through the pixels not one-by one, but by a scale factor and generate a new 20 pixels to use instead.  Similarly for the scanline->texture masking. So the joystick now controls a simple scale/multiplier and thus you get your zooming.

 

The principle here, in the whole engine basically, is to build layer upon layer of capability and use those to abstract away the hardware and difficult things by writing engines/systems, and then work at a higher level which is simpler and more capable.

 

 

WENHOP20210811b.bin

  • Like 9

Share this post


Link to post
Share on other sites
On 8/5/2021 at 5:56 PM, Andrew Davie said:

It uses the CDFJ bankswitch scheme that is supported already by emulators such as Stella and Gopher2600.  Gopher2600 is the more accurate in terms of timing, and perhaps in terms of hardware emulation too.  But they are both excellent and suitable for playing/testing CDFJ games. 

As a third choice, 6502.ts works fine, too (it does not emulate ARM cycles, though)

Share this post


Link to post
Share on other sites

I've made a start at tying the player sprite to the background. This is rudimentary stuff right now - in fact all it's doing is checking the character the player is over, and then 1) moving down if it's blank, otherwise moving up.  That's it. In the video all I am doing is moving left or right, and we see very rudimentary falling, and positioning upwards when "in something".  It's doing OK for such a simple start. The scroll is locking nicely to the player position, too. Bonus crash at the end!

 

 

  • Like 4

Share this post


Link to post
Share on other sites
4 hours ago, Bomberman94 said:

Any plans for a demo for „the real machine“ - maybe a PAL60 version, too? 🤗

Yes, sometime soon. The planet spinner works on the real thing now. I want to get some gameplay going before releasing a demo for that. But it's really close and although it might jump occasionally because the timing isn't as refined as it needs to be, the fundamentals are working fine on hardware now. I have long-term plans for PAL, but that will be late in the piece.

  • Like 2

Share this post


Link to post
Share on other sites

Hi Andrew,

 

Your planet-spin demo had me thinking:

  • is it possible to have a planet scroll up/down besides left/right?
  • does the background have to be black, or could it be another solid color, or even a textured background?

The reason I ask-- there may be some simple mechanics here that could make for an interesting "roll the ball" kind of game.  Since Playfield is a bit tedious to scroll sideways, I was thinking it might be interesting to try a simple vertical scroller, where the ball "rolls".  It rolls over certain power-ups, it gets bigger or smaller.  The ball could get smaller to fall into holes/tubes and pop out the other side, and get bigger to "climb over" walls.  Before thinking about it too hard though, I thought I'd see if any of the above is possible with the current engine idea.

 

Great demos so far, btw!

 

 

  • Like 1

Share this post


Link to post
Share on other sites
9 hours ago, Propane13 said:

is it possible to have a planet scroll up/down besides left/right?

More difficult because of the axis of spin. It's possible, but not with my current code.  The math is slightly different. Remember I'm just effectively "drawing" into a bitmap, so just about anything is possible if you can figure out the math and make it fast enough.

 

9 hours ago, Propane13 said:
  • does the background have to be black, or could it be another solid color, or even a textured background?

The background can be textured, with some minor modifications to the existing code

 

9 hours ago, Propane13 said:

The reason I ask-- there may be some simple mechanics here that could make for an interesting "roll the ball" kind of game.  Since Playfield is a bit tedious to scroll sideways, I was thinking it might be interesting to try a simple vertical scroller, where the ball "rolls".  It rolls over certain power-ups, it gets bigger or smaller.  The ball could get smaller to fall into holes/tubes and pop out the other side, and get bigger to "climb over" walls.  Before thinking about it too hard though, I thought I'd see if any of the above is possible with the current engine idea.

Well, sideways scrolling isn't tedious anymore with CDFJ.  It's pretty straightforward, actually.  I'd encourage you to pick up @SpiceWare's demo code and go from there.  Takes a little while to wrap your head around it, but worth the effort. I think my coding-head is wired differently because both that code, and some of the other code I've worked with recently (e.g., PlusCart) are just different to how I do stuff. Not wrong, just very different architecturally.

 

9 hours ago, Propane13 said:

Great demos so far, btw!

TY, it's been fun.

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Andrew,

 

any news about your fantastic tech demos - maybe a bin file for the „real thing“ and (let me dream) a PAL60 version? 🥳

Share this post


Link to post
Share on other sites
3 hours ago, Bomberman94 said:

any news about your fantastic tech demos - maybe a bin file for the „real thing“ and (let me dream) a PAL60 version? 🥳

I will come back to this sometime; I think it has a lot of potential and was fun.

But for the short/medium term I will probably not be working on it; I have studies which should be taking up my time for the foreseeable future.

 

  • Like 1

Share this post


Link to post
Share on other sites

I've had a bit of a play with this as I'm between other things that were taking my time.

 

Here I'm playing with rock/boulder mechanics. In the earlier iterations, the board was scanned top-to-bottom. That meant that if a rock decided it was going to fall, then it could move straight away, but the rock above it (if any) would not start falling until the next frame, and the rock above that would not fall until the frame after that. So the rocks got rather separated. I'm working towards allowing whole columns of rock to fall as a unit. Actually I want this so that I can have solid objects of arbitrary size that behave as "units" and will all fall as one "thing" without me having to do any work at all to make that happen.

 

So, to get that to happen, I changed the board scan to work bottom-to-top.  Now, when a rock sees it can fall, it moves down, and leaves a gap. The rock above it will, when its row is processed, see the gap, and also move down. So All movement in any column should happen at the same time. This video shows it partially working. Definitely areas where it's definitely working, but also areas I'm not-so-sure about. It's hard to see for sure.

 

As the rocks fall and land next to other rocks, they "merge" to form a solid rock mass.  I'm still deciding on exactly how the mechanics work for that, as I want passageways defined by rocks, through which you move. But I also want large sections of overhangs to be able to break off and fall by themselves. So, that's to come.

 

For now, though, I'm just re-familiarising myself with the code and learning how it all works.

 

 

Share this post


Link to post
Share on other sites

One of the things that's happening there is that when rocks fall, they don't have the "cohesion"/joins with adjacent rocks, so they appear separate. This may be a gotcha peculiar to rocks. Other things falling will not separate like that because they don't dynamically "join" to other things. I may have to rethink all this; perhaps this is as good as it gets.

 

Share this post


Link to post
Share on other sites

I have worked out a way to get the rock conglomeration happening "instantly" instead of next-frame, and so blocks of objects (in any column) now look as one larger rock. Also, individual rock behaviour is still working properly, so I'm now happy enough with the basics here (visually). Not sure if/how I'll use it in the game; perhaps when time expires everything just falls in a heap. Dunno.  Anyhow, here's the improved visuals...

 

 

  • Like 4

Share this post


Link to post
Share on other sites

Had a little play with some of the code today and cleaned up a few things.

I am working on the "eggs" which are no longer eggs, because they looked more like little worms/bugs.

So, in this video if you look at the wormy-things (wiggling white dots) - they now "eat" dirt. They also multiply. So, there's a balance between them growing/expanding into dirt areas, and them dying, and turning to dust. I see these as a potential tool/obstacle to assist with opening up areas of dirt for Mellon to move into. It seems to work OK, so I'll put this into the toolkit for gameplay use later on. Still very up in the air about all of this... rather disillusioned with everything Atari at the moment.

 

 

WENHOP20211121.bin

 

Hold F1 or F2 (reset/select) for screen restart.

Brief tap of SPACE (fire) toggles to overview screen and back

 

Edited by Andrew Davie
  • Like 5

Share this post


Link to post
Share on other sites

Sometimes I forget some of the cool things. Look at that awesome smooth horizontal scroll, colour playfield, animations.... never would have thought it possible, even with hardware assist. And so much going on.  Let's not forget the rotating texture-mapped planets. The circular wipe/fade.... Hope one day I can turn it into a game.

  • Like 8

Share this post


Link to post
Share on other sites
3 hours ago, Andrew Davie said:

rather disillusioned with everything Atari at the moment.

say it ain't so!

Share this post


Link to post
Share on other sites
3 hours ago, Andrew Davie said:

Still very up in the air about all of this... rather disillusioned with everything Atari at the moment.

 

For what it's worth, I really like enjoy following this thread and its updates when they occur.  If the disillusionment is about the recent news where Atari is releasing "3 classics from 1983" and doing kind of a terrible job of it-- well, that isn't really Atari anymore from my perspective.  They're long gone, but I consider this community to be the real heart of Atari.  It's here where people are pushing hardware, communicating, teaching, and overall just keeping the spirit of things alive.  I hope you keep on going; this is always fun to check in on whenever news occurs.  And, I hope there's some new ship animations in the future-- those look FANTASTIC.

  • Like 1

Share this post


Link to post
Share on other sites
13 minutes ago, Propane13 said:

but I consider this community to be the real heart of Atari.  It's here where people are pushing hardware, communicating, teaching, and overall just keeping the spirit of things alive.

Yes. I've said this very same thing 10 years ago.

Share this post


Link to post
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...