Jump to content
IGNORED

2600 sprite multiplex


Recommended Posts

hi,

 

sorry to post this here but you might popped by this:

 

http://www.atariage.com/forums/index.php?s...pic=68025&st=25

 

we are discussion several methods in enhancing atari's sprite capabilities...

actually i am dealing with sprite multiplexing via raster interrupts and i was wondering how you 2600 guys handle the mutliplexing & kernel?

 

f.e. joust, asteroids or pac man are using kind of flickering when more than 2 hardwaresprites are on one scanline... how are you dealing with it? maybe there is a kind of effective approach which i could adapt...

Link to comment
Share on other sites

i was wondering how you 2600 guys handle the mutliplexing & kernel?

a. repositioning inside the kernel, which allows displaying the same sprite more than once at different positions and with different graphics (vertical separation)

b. intelligent flicker (there has been a quite extensive discussion about this at [stella] around March 2002.)

Link to comment
Share on other sites

danke, thomas. but i haven't found any logical description or even source code? i went through several pages...maybe you can point me to post directly???

 

i would need information how the actual flickering is done, f.e. flicker through the virtual sprites which share the same scanline...

Link to comment
Share on other sites

but how do you "inteligent flicker"???

I don't have any code, but generally you sort the Y positions and when two or more objects overlap in that sorted list, you display them alternating.

 

Manuel has written some special code for Star Fire and explained how it works quite detailed at [stella]. Another idea is, to give every object a priority variable, which is decreased when it is drawn and increased when not. When objects overlap, the one with highest priority is drawn.

 

There are a few problems to solve and decissions to make (e.g. to you want to draw partial objects?). And the final solutions more or less depends on the game you are writing.

Link to comment
Share on other sites

Hi there!

 

Manuel has written some special code for Star Fire and explained how it works quite detailed at [stella].

 

In short:

 

The sorting in Star Fire does just one iteration of a bubble sort per frame and no complete sort. The sorting is also tweaked in a way that overlapping sprites (doesn't matter how many!) will constantly(!) swap positions, so each sprite of the "conflicting" group will get equal display time.

 

There is never a "final" sorting result (especially when all things are moving), but the sorting of objects is "constanly improving". If you have 7 objects entering the screen at once, then after 6 frames you have them "almost" sorted, with only the conflicting sprites continuing at swapping their positions.

 

During display, I just move through my sorted list and display as many sprites as possible, skipping those where I already "missed" the starting point.

 

Don't know if parts or any of this will help in a system with 4 hardware sprites though, as in Star Fire I have only one object per scannline, as I combined both sprites to 16 pixel wide objects.

 

Greetings,

Manuel

Link to comment
Share on other sites

thanks manuel... question: when you are refering to "just move through my sorted list and display..." what exactly are you meaning?

 

i mean... f.e. if your sorted list is:

 

1,2,3,4,[5] ; assuming 4 hardwaresprites 5th sprite is marked as "rejected"

 

how would you walk through this list?

 

in my test i am sorting every frame 16 randomly moving sprites and map them to 4 hardware sprites... rejecting overlapping ones which could not fit on the scanline... and now i am searching for a method (f.e. MSX ringbuffer method...) to display the rest... examples on atari8bit are ms pacman & joust as most knewn commercial games doing this kind of "intelligent flickering".

Link to comment
Share on other sites

thanks manuel... question: when you are refering to "just move through my sorted list and display..." what exactly are you meaning?

Since RAM is extremly precious on the 2600, the same list is used for the display kernel too.

 

1,2,3,4,[5] ; assuming 4 hardwaresprites 5th sprite is marked as "rejected"

There are no "rejected" sprites, just sprites that overlap. Only the first of those sprites is drawn then, the other ones are "automatically" skipped, because the display kernel "misses" their starting position and continues with the next sprite, which didn't overlap the previous one.

 

Before the next frame, the list is resorted and overlapping sprites are swapped. So in the next round, the display kernel "choses" a different sprite to draw.

Link to comment
Share on other sites

what do you think of this?

 

;XASM 6502 source code format
;you have to know about the atari800 hardware (4 player (8x256), 4 missles (2x256).
;DLI zone 1
mva sortsprx  stack
mva sortsprx+1	stack+1
mva sortsprx+2	stack+2
mva sortsprx+3	stack+3
sta ll+1
ldx #4
loop	lda sortspry,x
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue	;saves for the VBL how many sprites are per zone
;DLI zone 2
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,x
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+1	;saves for the VBL how many sprites are per zone
;DLI zone 3
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,x
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+2	;saves for the VBL how many sprites are per zone
;DLI zone 4
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,x
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+3	;saves for the VBL how many sprites are per zone
...

 

 

the VBL can now flicker through the display stack and prepare the DLI flags to handle the display properly.

Of course it must copy the sprite data in the correct player/missle area but this should be no

problem at all as we move data in to the players in the order 4,3,2,1,4,3,2,1 etc... --> MS Pac Man Atari 800.

 

 

the DLIs can reposition the sprites each VBL...

 

the DLI (Rasterinterrupts) will be set to each zone where the next free sprite can be displayed without any overlapping...

 

sortsprx,y contain the virtual sprite positions after they have been sorted by y-pos.

 

 

what do you think? now it should be easy to flicker through the display stack for each zone as the CUE table contains the virtual sprites per zone...

Link to comment
Share on other sites

i think this works better:

 

;DLI zone 1
mva sortsprx  stack
mva sortsprx+1	stack+1
mva sortsprx+2	stack+2
mva sortsprx+3	stack+3
sta ll+1
ldy #4
loop	lda sortspry,y
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue	;saves for the VBL how many sprites are per zone
txa
tay
;DLI zone 2
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,y
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+1	;saves for the VBL how many sprites are per zone
txa
tay
;DLI zone 3
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,y
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+2	;saves for the VBL how many sprites are per zone
txa
tay
;DLI zone 4
mva sortsprx,x  stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
mva sortsprx,x	stack,x+
sta ll+1
loop	lda sortspry,y
sec
ll	sbc #[next spr]
cmp #8  ;vertical size of sprite
bcs no_overlap	;if y2-y1<8 then they do overlap
lda sortsprx,x
sta stack,x
inx
cpx #max_sprites
bcc loop
no_overlap stx cue+3	;saves for the VBL how many sprites are per zone
...



the VBL can now flicker through the display stack and prepare the DLI flags to handle the display properly.
Of course it must copy the sprite data in the correct player/missle area but this should be no
problem at all as we move data in to the players in the order 4,3,2,1,4,3,2,1 etc... --> MS Pac Man Atari 800.

Link to comment
Share on other sites

it makes the code more compact so your mentioned "pseudo code" :)

 

mva sortsprx,x stack,x+

 

 

should be assembled to

 

lda sortsprx,x

sta stack,x

inx

 

btw. the code was written in notepad and wasn't tested or assembled. it grew just in my head this morning...

Link to comment
Share on other sites

Here's the full list of XASM assembler non-standard 6502 syntax "pseudo-commands" and the real 6502 code they generate. Maybe it should be called a compiler rather than an assembler!:

 

 

PSEUDO-COMMANDS

Pseudo-commands are built-in macros.

 

ADD - addition without carry

If you have ever programmed a 6502, you must have noticed that you had to use a CLC before ADC for every simple addition.

xasm can do it for you. ADD replaces two instructions: CLC and ADC.

SUB - subtraction

It is SEC and SBC.

RCC, RCS, REQ, RMI, RNE, RPL, RVC, RVS - conditional repeat

These are branches to the previous instruction. They take no operand, because the branch target is the address of previously assembled instruction.

Example:

ldx #0

mva:rne $500,x $600,x+

The example code copies memory $500-$5ff to $600-$6ff. Here is the same written with standard 6502 commands only:

ldx #0

loop lda $500,x

sta $600,x

inx

bne loop

SCC, SCS, SEQ, SMI, SNE, SPL, SVC, SVS - conditional skip

These are branches over the next instructions. No operand is required, because the target is the address of the instruction following the next instruction.

Example:

lda #40

add:sta $80

scc:inc $81

In the above example the word-sized variable $80 is incremented by 40.

JCC, JCS, JEQ, JMI, JNE, JPL, JVC, JVS - conditional jumps

These are a kind of 'long' branches. While standard branches (such as BNE) have range of -128..+127, these jumps have range of all 64 kB.

Example:

jne dest

is equivalent to:

seq:jmp dest

INW - increment word

Increments a 16-bit word in the memory.

Example:

inw dest

is equivalent to:

inc dest

sne:inc dest+1

MVA, MVX, MVY - move byte using accumulator, X or Y

Each of these pseudo-commands requires two operands and substitutes two commands:

mva source dest = lda source : sta dest

mvx source dest = ldx source : stx dest

mvy source dest = ldy source : sty dest

MWA, MWX, MWY - move word using accumulator, X or Y

These pseudo-commands require two operands and are combinations of two MV*'s: one to move the low byte, and the other to move the high byte.

You can't use indirect nor pseudo addressing mode with MW*. Destination must be an absolute address (optionally indexed).

When source is also absolute, an mw* source dest will be:

mv* source dest

mv* source+1 dest+1

When source is an immediate, an mw* #immed dest will be:

mv* <immed dest

mv* >immed dest+1

When <immed equals >immed and immed is not forward-referenced, xasm uses an optimization:

mv* <immed dest

st* dest+1

If possible, MWX and MWY use increment/decrement commands. E.g. mwx #1 dest is assembled as:

ldx #1

stx dest

dex

stx dest+1

Edited by Sheddy
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...