Jump to content
IGNORED

Anyone think Ballblazer is possible on the 2600?


Recommended Posts

I don't know yet. I take little steps, program every day a little bit, so I don't get burned out.

 

Hi!

 

Good model to follow; don't let anyone pressure you.

The last few mini-projects I've worked on have been like this.

I spend 15-60 minutes a day on them, and go from there.

 

Any more, and I burn out. And, if people ask for updates, I tend to burn out.

I think the work you're doing is amazing-- go at your own pace, and most importantly, have fun!

 

-John

Link to comment
Share on other sites

I don't know yet. I take little steps, program every day a little bit, so I don't get burned out.

Good model to follow; don't let anyone pressure you.

The last few mini-projects I've worked on have been like this.

I spend 15-60 minutes a day on them, and go from there.

 

Any more, and I burn out. And, if people ask for updates, I tend to burn out.

I think the work you're doing is amazing-- go at your own pace, and most importantly, have fun!

Maybe that's the secret. Spend a little time every day on whatever it is you're working on instead of spending many hours at a time on it or going days or months without working on it at all.

Link to comment
Share on other sites

Yep, the tile-setup-code has to move somewhere. I can even make the screen not 262 lines now :D

Due to the more efficient kernel, it can now be put in inside the sky-kernel, consuming one byte of RAM per line, about 20 bytes now. Or inside the checkerboard kernel. enough options now :)

So when is your next post of kernel source and something new? :)

--Selgus

 

I don't know yet. I take little steps, program every day a little bit, so I don't get burned out. For the rotofoils I have now two options:

1. store all versions of the rotofoils in ROM, but there a lot of them if you want to do it smoothly. The code would look something like:

LDA (ROTOFOIL_PTR),Y

STA GRP0

STA GRP1

 

2. use some templates in rom and map them over each other, code would look something like:

LDA (Foot_A),Y ;lower part template 1

ORA (Foot_B),Y ;lower part template 2

AND (Head),Y ;the head of the rotofoil

AND (Mask),Y ;some mask to remove garbage.

STA GRP0

STA GRP1

 

Or some combination of the above two options...

Don't forget that the rotofoils aren't always symmetrical!

 

And I'd definitely go for the 1st version; store all shapes in ROM. It'll burn a lot of ROM but that's what it's there for. ;)

Link to comment
Share on other sites

And I'd definitely go for the 1st version; store all shapes in ROM. It'll burn a lot of ROM but that's what it's there for. ;)

You're right, the rom is only 8KB now, there is a lot of room. I might have to split the kernel into two banks, since it's an big unrolled kernel which takes a lot of ROM.

 

I just calculated how much space I need for 1 side of a rotofoil. I think the biggest rotofoil will be 48 pixels heigh and the smallest 3 or 6. I need heights of 48, 45, 42, 39, 36 etc. The sizes 47,46 44, 43 etc. are created through masking at the top. I added some pictures as illustration.

 

Can I just put the sprites after each other in a table? 48...3 would take 405 bytes of space. 2 more for side few, and maybe 1 more with a window for front view.

I must be sure that no page boundary is crossed...

front_48.bmp

front_45.bmp

front_42.bmp

front_39.bmp

front_36.bmp

Link to comment
Share on other sites

Doesn't the 800 version use some sort of rendering algorithm?

 

I'd have thought - have several horizontal sizes of each view. Then use a 2 byte "index"... first byte is just a fractional value, 2nd byte is the actual index.

 

Then that should give you numerous vertical sized iterations for each definition.

Link to comment
Share on other sites

Doesn't the 800 version use some sort of rendering algorithm?

 

I'd have thought - have several horizontal sizes of each view. Then use a 2 byte "index"... first byte is just a fractional value, 2nd byte is the actual index.

 

Then that should give you numerous vertical sized iterations for each definition.

The atari 800 version uses an algorithm where the rotofoil is divided into 6 parts, which are more cropped when the rotofoil gets smaller, well, that's what it looks like.

 

Would your idea look something like?:

	CLC	;2
LDA index_fract;3
ADC scale_factor;3
STA index_fract;3
LDA index	;3
ADC #0	;2
STA index	;3
TAX	;2
LDA SPRITE_LEFT,X;4
STA GRP0	;3
LDA SPRITE_RIGHT,X;4
STA GRP1	;3 = 35

 

So your idea is to scale the sprite smoothly in vertical direction, and store horizontal scaled verisons in rom? the horizontal scaled rotofoil would have only 8 versions since one side is 8 pixels wide.

Link to comment
Share on other sites

So your idea is to scale the sprite smoothly in vertical direction, and store horizontal scaled verisons in rom? the horizontal scaled rotofoil would have only 8 versions since one side is 8 pixels wide.

I would also use as much pre-processed data in ROM as possible. Even if you have to add padding to make each part start on some boundary for a simple calculation. How many cycles in the playfield kernels do you have left to work with?

--Selgus

Link to comment
Share on other sites

So your idea is to scale the sprite smoothly in vertical direction, and store horizontal scaled verisons in rom? the horizontal scaled rotofoil would have only 8 versions since one side is 8 pixels wide.

I would also use as much pre-processed data in ROM as possible. Even if you have to add padding to make each part start on some boundary for a simple calculation. How many cycles in the playfield kernels do you have left to work with?

--Selgus

That's variable. at this moment, I have a minimum of 54 cycles to play with. I already made a schematic of cycles left per line, at line 15 the kernel branches:

 

1  68
2  62
3  68
4  65
5  60
6  57
7  58
8  61
9  61
10 64
11 62
12 64
13 61
14 61
15 54	branch!

 K1  K2
16 57  61
17 67  63
18 61  56
19 66  66

Link to comment
Share on other sites

That code snippet before was what I was thinking along the lines of...

 

I imagine that if you get the fractions right, you should get a smooth zoom transition along a certain level of depth (z) until you then just switch to the next set of definitions for closer/further away.

 

You might even be able to kludge a bit and only use certain sections of the rotofoil definition (e.g. just the top half of the triangular part, added to the top section of the base portion) for "further away" views.

 

So, e.g. for a closeup view you might use a slowly increasing index...

		[ ]
	[ ]
   [   ]
   [   ]
  [	 ]
  [	 ]
 [	   ]
 [	   ]
[		 ]
[		 ]
   [   ] 
  [	 ]
 [	   ]

 

As the 'foil moves away, you speed up the indexing, so you might have a slightly more distant view that looks like:

 

	   
	[ ]
   [   ]
   [   ]
  [	 ]
 [	   ]
 [	   ]
[		 ]
	[  ] 
  [	 ]
 [	   ]

 

I guess you'd need to play around a bit to see what works... one problem with this method is that you have aspect ratio changing since Y expands/contracts but X doesn't.

 

But if you can somehow use truncated sections of the animation joined together like I mentioned before, maybe it could be made to work well.

Link to comment
Share on other sites

@Rybags,

 

I thought about it for a while, and I will try to load the sprites from ROM. Since they are so low-resolution, I doubt that scaling on-the-fly will give better results, as scaling will generate artifacts too. As long as I can fit 1 view of the rotofoil (front/back/side) + checkerboard kernel in 4K, I'm saved.

Edited by roland p
Link to comment
Share on other sites

I don't know yet. I take little steps, program every day a little bit, so I don't get burned out.

Good model to follow; don't let anyone pressure you.

The last few mini-projects I've worked on have been like this.

I spend 15-60 minutes a day on them, and go from there.

 

Any more, and I burn out. And, if people ask for updates, I tend to burn out.

I think the work you're doing is amazing-- go at your own pace, and most importantly, have fun!

Maybe that's the secret. Spend a little time every day on whatever it is you're working on instead of spending many hours at a time on it or going days or months without working on it at all.

 

I find this to be much more effective.

Going days to months without looking at the code only makes things more difficult.

I find that when I come back to my code, not only do I need to fix what was previously broken, but now I also have the additional work of re-learning whatever I put into code in the first place. Not exactly fun. So, with that, I usually delay more, and more, and more, and never come back.

 

I came up with the "work a little bit" scheme awhile back, and have one additional piece of advice-- break something before you're done.

It's counterintuitive to "break" code to consider your day complete, as most people like to have satisfaction that everything's working.

In my case though, I find that breakages annoy me. So, in the morning, I'll work 15-30 minutes and solve yesterday's last breakage. Then, I'll feel good about how far I got, and work on the next phase, getting it to work, but potentially damaging something else (adding an extra scanline, or having some ugly artifacts on screen, etc). Instead of doing the cleanup work, I leave that until tomorrow. Then, through the day, it picks at the back of my mind, and I come up with solutions to the problems I introduced. I REALLY want to fix them, but force myself to do it the next day. Then, the next day, I make my easy fix from the day before, and break something else. And, so, the cycle continues.

 

Without doing this, I would never get anywhere.

 

-John

Link to comment
Share on other sites

I might have to split the kernel into two banks, since it's an big unrolled kernel which takes a lot of ROM.

I did that in Medieval Mayhem - the top castles kernel was in one back, the bottom castles kernel in another while the dragon kernel was scattered over 3 banks because of all the frames of animation for the dragon, knight and text messages(DRAW and DEMO).

 

I probably could have done the dragon kernel in 1 bank, but all the artwork came late in the game so I squeezed in those graphics where I could.

Link to comment
Share on other sites

I don't know yet. I take little steps, program every day a little bit, so I don't get burned out.

Good model to follow; don't let anyone pressure you.

The last few mini-projects I've worked on have been like this.

I spend 15-60 minutes a day on them, and go from there.

 

Any more, and I burn out. And, if people ask for updates, I tend to burn out.

I think the work you're doing is amazing-- go at your own pace, and most importantly, have fun!

Maybe that's the secret. Spend a little time every day on whatever it is you're working on instead of spending many hours at a time on it or going days or months without working on it at all.

 

I find this to be much more effective.

Going days to months without looking at the code only makes things more difficult.

I find that when I come back to my code, not only do I need to fix what was previously broken, but now I also have the additional work of re-learning whatever I put into code in the first place. Not exactly fun. So, with that, I usually delay more, and more, and more, and never come back.

 

I came up with the "work a little bit" scheme awhile back, and have one additional piece of advice-- break something before you're done.

It's counterintuitive to "break" code to consider your day complete, as most people like to have satisfaction that everything's working.

In my case though, I find that breakages annoy me. So, in the morning, I'll work 15-30 minutes and solve yesterday's last breakage. Then, I'll feel good about how far I got, and work on the next phase, getting it to work, but potentially damaging something else (adding an extra scanline, or having some ugly artifacts on screen, etc). Instead of doing the cleanup work, I leave that until tomorrow. Then, through the day, it picks at the back of my mind, and I come up with solutions to the problems I introduced. I REALLY want to fix them, but force myself to do it the next day. Then, the next day, I make my easy fix from the day before, and break something else. And, so, the cycle continues.

 

Without doing this, I would never get anywhere.

 

-John

And I always thought that "If it aint broke, don't fix it" was good advice!!! :lol:
Link to comment
Share on other sites

I've thought a lot about the rotofoils sprites, and I decided to try to generate the sprites on-the-fly.

 

As far as I understand, sprites are ususally generated with a pointer and a mask with code like (where Y is the current line number):

 

LDA (PTR),Y
AND (MASK),Y
STA GRP0

 

For the rotofoils I came up with the following idea:

 

LDA (PTR_PART1),Y;get footer (wide-to-small part)
ORA (PTR_PART2),Y;get footer (small-to-wide part)
AND (PTR_PART3),Y;finish it with the top part
STA GRP0

 

I've good hopes fitting this in the kernel for left and right part of the rotofoil, and two missiles for goals.

 

The templates will look like:

PART1
00000000 (padding)
...
00001111
00001111
00011111
00011111
00111111
00111111
01111111
01111111
11111111
11111111
...
00000000 (padding)

PART2
11111111 (padding)
...
01111111
01111111
00111111
00111111
00011111
00011111
00001111
00001111
...
00000000 (padding)

PART3
00000000 (padding)
...
00000001
00000001
00000001
00000001
00000011
00000011
00000011
00000011
00000111
00000111
00000111
00000111
00001111
00001111
00001111
00001111
00011111
00011111
00011111
00011111
00111111
00111111
00111111
00111111
01111111
01111111
01111111
01111111
11111111
11111111
11111111
11111111
...
11111111 (padding)

 

Some more templates will be used for side views and smaller versions of the rotofoils

 

I hope to get some working code soon.

Edited by roland p
Link to comment
Share on other sites

I haven't been following the rotofoil-rendering discussion very closely... Is your current plan to define the rotofoil shapes entirely with bitmaps? If you instead used a combination of bitmaps and horizontally nudging the player sprites every few lines, you could achieve a perceived resolution rivaling that of the 7800 version.

Link to comment
Share on other sites

I haven't been following the rotofoil-rendering discussion very closely... Is your current plan to define the rotofoil shapes entirely with bitmaps?

I'm going to use different shaped masks. Right now, I can combine 3 masks to render a rotofoil. It's now a static rotofoil, but I'm in the process of making it scalable.

 

If you instead used a combination of bitmaps and horizontally nudging the player sprites every few lines, you could achieve a perceived resolution rivaling that of the 7800 version.

 

The resolution of the biggest rotofoil is now 16 pixel wide, using 2 quad sized players. What do you mean by nudging? Maybe I could enhance the perceived resolution when the rotofoil is moving? (See signature :D)

Link to comment
Share on other sites

The resolution of the biggest rotofoil is now 16 pixel wide, using 2 quad sized players. What do you mean by nudging? Maybe I could enhance the perceived resolution when the rotofoil is moving? (See signature :D)

So what do you make the plasma ball in this model? Is that somehow constructed with missiles? If so, how do you intend on changing it's color?

--Selgus

Link to comment
Share on other sites

The resolution of the biggest rotofoil is now 16 pixel wide, using 2 quad sized players. What do you mean by nudging? Maybe I could enhance the perceived resolution when the rotofoil is moving?

Say you're rendering a front-facing rotofoil such that each "pixel" is, for example, 8 scanlines high. If on every other scanline you were to use the motion registers to move the left sprite one pixel left, and the right sprite one pixel right, the result would be a smooth diagonal at a perceptual 160H resolution.

Edited by ZylonBane
Link to comment
Share on other sites

The resolution of the biggest rotofoil is now 16 pixel wide, using 2 quad sized players. What do you mean by nudging? Maybe I could enhance the perceived resolution when the rotofoil is moving?

Say you're rendering a front-facing rotofoil such that each "pixel" is, for example, 8 scanlines high. If on every other scanline you were to use the motion registers to move the left sprite one pixel, and the right sprite right one pixel, the result would be a smooth diagonal at a perceptual 160H resolution.

It's impossible to do exact STA HMOVE's in the checkerboard kernel. When the board scrolls to the right, the STA HMOVE will occur later, and if the board scrolls left, the STA HMOVE will occur sooner, and this gave strange results.

Link to comment
Share on other sites

I thought it didn't make any difference when you hit HMOVE, as long it as wasn't actually coinciding with a sprite draw? Surely you have some scanline-level sync in your kernel, for properly stuffing the sprite data registers and such.

 

Oh well, would have been nice, but I won't try to second-guess your kernel design.

Link to comment
Share on other sites

I thought it didn't make any difference when you hit HMOVE, as long it as wasn't actually coinciding with a sprite draw?

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

 

Surely you have some scanline-level sync in your kernel, for properly stuffing the sprite data registers and such.

Yeah, I would have thought so too - now I'm intrigued...:ponder:

 

EDIT: Do you mind posting the latest source code again?

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.

source.zip

Edited by roland p
Link to comment
Share on other sites

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.

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