Jump to content
IGNORED

Anyone think Ballblazer is possible on the 2600?


Recommended Posts

Makes a big difference. The cycle-window for a normal-behaving HMOVE is actually pretty small...only about 4 cycles IIRC.

 

A write to HMOVE triggers a latch that does three things: (1) it sets a another latch which is cleared at the end of each scan line, and which will delay the start of the visible portion of the next scan line by eight pixels (effectively pushing all sprites right 8 pixels); (2) it turns on a pulsing circuit for each sprite; (3) it starts the position-compare counter if it's not already running.

 

Every four pixel clocks (1.33 CPU cycles) each pulser circuit will compare its HMxx with (position-compare-counter xor 8 ) and shut off if they match. Then the position-compare counter will be incremented if it's non-zero or if HMOVE was just written. After those things are done, every sprite whose pulser is enabled will receive a motion pulse.

 

Motion pulses received during the visible part of the frame will distort a sprite's image but not move it. Each pulse received during horizontal blanking will move a sprite one pixel leftward.

 

If an HMOVE occurs on cycle 73 or 74, all of the motion pulses that result will occur during the blanking interval, but the latch responsible for blanking 8 pixels of the next line will not get set (thus, outputting 0-15 pulses will cause sprites to move 0-15 pixels left). If the HMOVE occurs before cycle 73, one or more of the pulses will occur during the displayed part of the frame and the sprite will not move as far left as expected. If an HMOVE occurs within a few cycles of its normal time, the system may manage to output all of the required motion clocks during the blanking interval. If the HMOVE occurs too late, some of the motion clocks will occur during the displayed part of the frame and thus not cause motion. The more motion clocks need to be sent, the earlier the HMOVE must begin.

Shorter version of that: http://www.qotile.net/minidig/code/hmove.txt ;)

 

The window is 5 cycles, actually, not 4. Though depending on what you're trying to do, you might be able to get away with writes to HMOVE outside of that window.

 

EDIT: And thanks for posting the source. I was poking around in Stella's debugger a bit and the dynamic method of waiting 5/6 cycles is tricky - I haven't seen that before. :D

   sbc $90
  bcs Label
Label:

Edited by vdub_bobby
Link to comment
Share on other sites

I've now attached the source.

 

Some notes to help you:

 

ballblazer.h = mainfile, templates for the drones are now put here.

setup_sprites.h = for calculating the pointers for the masks that create the drones, executed during VBLANK

position_sprites.h = for position the sprite horizontally (with the Divide15 routine) executed before each playfield

 

checkerboard4.h = This draws the sky + checkerboard. The first 14 lines of the sky is a loop, then 6 lines of sky unrolled, then 19 lines of checkerboard unrolled. Between the unrolled lines, a subkernel is inserted by calling SUBKERNEL macro. The subkernel macro creates the sprites and takes care of vertical movement by skipping one or zero cycles, depending on the amount of horizontal movement.

On a first glance through this, I'm pretty sure you always can know, within 1 or 2 cycles, where the start of the scanline is. So you could hit HMOVE if you have the free cycles at those spots.

Link to comment
Share on other sites

On a first glance through this, I'm pretty sure you always can know, within 1 or 2 cycles, where the start of the scanline is. So you could hit HMOVE if you have the free cycles at those spots.

But the code is synchronised with WSYNC at line 14 and after that, it can skip one cycle on each line. So the first line of the checkerboard (checkerboard itself sarts at line 20), can be moved 6 clockcycles, and line 15 of the checkerboard can be moved 21 cycles. So, at line 15, there are 21 possible moments in time for the sta hmove command, relative to the horizontal sync. Can that work?

Link to comment
Share on other sites

Which method did you go with for the 'foil rendering?

There are now 2 sprites which move closer to eachother. The 'foil is created by combining 3 templates:

	LDA (PTR_PART1),Y;5 get footer (wide to small part)
ORA (PTR_PART2),Y;5 get footer (small to wide part)
AND HORIZONTAL_MASK;remove unneeded pixels
STA TEMP;3 remember foot of drone, we reuse it for the right part.
AND (PTR_PART3_RIGHT),Y;5 finish it with the top part

 

The smooth movement of two sprites getting closer to eachother can only be used for front view, where the drone is symetrical. At the side view, the drone isn't symetrical anymore, so I have to change the method somehow, with HMOVE for higher resolution, or some sort of subpixel rendering and coarse movement of the two sprites.

 

It looks impressive, just 2 criticisms: the distant view... would look much better with some more detail, and at all distances, it looks "unattractive" when the 'foil has 2 blocky pixels at the pointy end (top).

 

Thanks, I could increase the resolution, but I have to deal with a certain memory constraint. If I split the kernel over two banks, I can use more templates and the resolution can be higher. The two blocky pixels has to do with the smooth movement of the two sprites, it can be easily masked away, but when I choose a different rendering method the two pixels will be gone anyway.

Edited by roland p
Link to comment
Share on other sites

Scaling rotofoil version 1

The scaling is nice, but it would be good if the rotofoil could be displayed at a higher resolution?

I will take a look at the HMOVE method.

 

The HOVE method is going to be difficult since you can't easily predict the start of each scanline. My feeling is that it might just be easier to pre-calculate all of the sprite sizes/positions and just load the appropriate one during the kernel.

 

Chris

Link to comment
Share on other sites

The HOVE method is going to be difficult since you can't easily predict the start of each scanline. My feeling is that it might just be easier to pre-calculate all of the sprite sizes/positions and just load the appropriate one during the kernel.

I would agree. IMO it is going to be very hard to get the timings exact unless you use a pre-calculated table that you can just index during the kernel. The problem turns more into, how can you organize your banks to make the data available during the kernel.

--Selgus

Link to comment
Share on other sites

Scaling rotofoil version 1

 

I noticed that the players can only start on every other line. Is there a way for you to use VDEL or something to reach full vertical positioning accuracy?

 

I'm not sure. The updates of the players doesn't occur on every line, so VDEL won't make a difference. Maybe it is possible, but only if I update a player immidiatly at the start of the scanline, and at the end of the scanline.

Link to comment
Share on other sites

The scaling perspective seems odd... as if you're sitting on top of your rotofoil instead of inside it.

Maybe I didn't make de rotofoil heigh enough. I'll tweak it a bit.

 

It seems that there are 12 moments (cycle 75-85 and 10) for positioning sprites. I only need -2,-1,0,1,2. To do this in my kernel, I need to branch at line 12 to ensure that every STA HMOVE is within that 12 cycle window.

Link to comment
Share on other sites

I tweaked the rotofoil a bit. Jitter is reduced (hopefully), the player sprites are used more optimal, the top of the rotofoil is almost right and I've ajusted the size.

I think it's pretty good now and I should concentrate on other stuff (horizontal movement, removing black bars, gameplay). What do you think?

ballblazer_scaling_rotofoil_v2.bin

  • Like 1
Link to comment
Share on other sites

That looks much better - except of course the lifting in the distance but I imagine an easy fix there.

 

Are you going to have the blacked out part too (triangular type window)... it'd make it look much more authentic.

 

ed - also, just checked the A8 version... the 'foils actually "sink" as they move over the horizon... should be pretty easy, that?

Edited by Rybags
Link to comment
Share on other sites

That looks much better - except of course the lifting in the distance but I imagine an easy fix there.

 

ed - also, just checked the A8 version... the 'foils actually "sink" as they move over the horizon... should be pretty easy, that?

Yep, it's now following the 'official' route. I'll stick it to the horizon for a while and then let it sink. Maybe I've to let it visible for a longer distance since it's disapearing quite soon now.

 

Are you going to have the blacked out part too (triangular type window)... it'd make it look much more authentic.

I'm not sure yet. A transparent window should be possible. I different colored window would be more difficult and I've to check if there are cycles for it (probably not)...

Link to comment
Share on other sites

Are you going to have the blacked out part too (triangular type window)... it'd make it look much more authentic.

I'm not sure yet. A transparent window should be possible. I different colored window would be more difficult and I've to check if there are cycles for it (probably not)...

From the side you could look through it and make it transparent, but from the front not.

 

The only idea I have, is flickering the window there. But then you should make sure, that the window is always within the static sky area, not the scrolling playfield. Else it would look odd.

Link to comment
Share on other sites

The only idea I have, is flickering the window there. But then you should make sure, that the window is always within the static sky area, not the scrolling playfield. Else it would look odd.

You're forgetting about the goalbeams and the plasmorb. There's no practical way to guarantee that the area behind the window will be blank.

 

I'd say just cut a hole out where the windows should be and not worry about it. People will be too gobsmacked by all the other technical feats this game is pulling off to even begin to care the that windows aren't solid-filled.

Edited by ZylonBane
Link to comment
Share on other sites

You're forgetting about the goalbeams and the plasmorb. There's no practical way to guarantee that the area behind the window will be blank.

Good catch. Then maybe just a frame or pattern which indicates a window or where the front is. Else you will not konw where the opponent is heading too.

 

I'd say just cut a hole out where the windows should be and not worry about it. People will be too gobsmacked by all the other technical feats this game is pulling off to even beging to care the that windows aren't solid-filled.

True, but with so much effort spend into everything else of this game, IMO it is worth to wonder a bit about the windows too. That would be another step into perfection. :)

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...