| |
Digger
Registered: Mar 2005 Posts: 437 |
Movable sprites over chunky FLI
I need to have a freely moving block (2x2, 3x3 or 4x4) of sprites positioned above chunky FLI routine (badline triggered every 4 lines).
Could you suggest on how to approach it?
There's a part by Xbow with sprite block freely flying over FLI:
https://youtu.be/Y0O7zmD7MDE?t=209
Cheers! |
|
| |
Digger
Registered: Mar 2005 Posts: 437 |
I looked at it with C64 Debugger and I saw a “moving window” technique where on each frame the FLI routine is started from a different place in the code, so sprites’ Y pos and pointers are executed at the right place. Pretty smart.
Looking into combining this with a timer routine that triggers every 4 lines but I see this uber complicated... |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
I suspect the simplest approach would be to have blank sprites above and below the block, so the sprite DMA cycles are the same every line regardless of the block position. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
https://youtu.be/_Z9rlP7XMuk?t=646
I am doing it here. :-)
yes its a complicated solution. spaceship is 4x2 sprites, so there are 2 kind of fli nmi routines: 4 sprites over or not.
then I have code to find out which nmi should be 4 sprites over and which normal, and there is a table of nmi's generated, which the nmi's read up to decide what kind of nmi will be next. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
;helper tables to determine which char lines are covered by sprites
; each table represents a consecutive char row
; row1-2-3 relative to sprite y coord
; to be looked up by y/8
; so if sprite y = 0 then char rows 0,1,2 have sprite over them
; ff = not covered by sprite
helper1 .byte $00,$01,$01,$01,$01,$01,$01,$01
helper2 .byte $01,$02,$02,$02,$02,$02,$02,$02
helper3 .byte $02,$ff,$ff,$ff,$03,$03,$03,$03
setnmivectors tax
lsr
lsr
lsr
sta zp ;/8
txa
and #$07
tay
lda helper1,y
clc
adc zp
tax
lda #<nmispr
sta nmilo+0,x
lda #>nmispr
sta nmihi+0,x
lda helper2,y
clc
adc zp
tax
lda #<nmispr
sta nmilo+0,x
lda #>nmispr
sta nmihi+0,x
lda helper3,y
bmi skip ;in some cases only 2 char rows are covered no need for 3rd
clc
adc zp
tax
lda #<nmispr
sta nmilo+0,x
lda #>nmispr
sta nmihi+0,x
skip
rts
lda falconsinus,x
clc
falconyoffset adc #180 ;88
sta falcony
sec
sbc #4
pha
jsr setnmivectors ;setup nmi vector table
pla
clc
adc #21
jsr setnmivectors |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
note that the nmi vector table is reset to "no sprites present" before calling setnmivectors which will change them to sprites are present routines where needed based on the caller A ( = y coo of a sprite ) |
| |
Digger
Registered: Mar 2005 Posts: 437 |
Thx Oswald, but that's beyond my comprehension, will probably try a more regular chunky FLI with IRQs and what CJam suggested. Seems I've got enough rastertime left to burn some extra cycles.
btw. How do you calculate that comanche/voxel flight? |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Hmm, should be possible with the usual 4x4-FLI-IRQs (mind: two consequtive 4x4-FLI-lines set in one irq) that are triggered on a non-sprite-cycle...
@Digger: will send a pm/mail;) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Hmm, should be possible with the usual 4x4-FLI-IRQs (mind: two consequtive 4x4-FLI-lines set in one irq) that are triggered on a non-sprite-cycle...
@Digger: will send a pm/mail;)
I dont get this, but made me think, with if code would check via CIA timers if sprites are present (timer would run more cycles if sprites steal cycles), and pick 4x4 routine automagically based on that ? as sprite dma starts 1 line earlier could work, but only if not all sprites are present.
by clever setup timer value could be used directly to set nmi routine addrss. so just lda timer sta nmivector.
voila done :)
@digger, its complicated, dont wanna rail off the topic :) basicly works like any voxel engine, but the heightmap is an on the fly calculated plasma. |
| |
HCL
Registered: Feb 2003 Posts: 728 |
I think The Wild Bunch is what you're looking for. There is a 4x4-effect towards the end of the demo, but don't rush it, the rest of the demo is worth watching also :) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: I think The Wild Bunch is what you're looking for. There is a 4x4-effect towards the end of the demo, but don't rush it, the rest of the demo is worth watching also :)
Exactly. What I did there was to let the multiplexer fill in a table of delay values so that I could compensate properly.
The main problem is that even though timer magic let you do the FLI-$d011 properly, random sprite DMA fucks that up. The $d011-write has to be done 1 cycle after sprite fetches, so you really can't auto-stabalize it.
Since all my sprites are at least in pairs of two, not many combinations of timing could exists (4! = 24). So the multiplexer knows - per raster line - exactly how many sprites are active, and fills a table properly. |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
My idea was in the direction like Oswald stated in his last post.
So in a nutshell:
- use 25 irqs
- set up a timer irq that fires every 8 rasterlines, irq trigger on rasterline 3 (mod8, i.e. of every char) on a non-sprite-cycle
- proceed with your favourite dejitter routine to cycle-align a 2nd dejitter routine...
- ...which "takes care" of the different sprite configs on that line (0, or 2-4) (see example code below)
- set $D011 to $34 (or $3C) exactly @cycle#11 of rasterline 4 (mod8)
- set $D011 to $30 (or $38) directly afterwards
The example code (mainly for the second dejittering mentioned above) would look as follows:
LDX #$3C
LDA #19
SEC
SBC $DC04 (or any timer that's still free to use)
STA bra+1
bra:
BCS xx
JMP next
next:
LDA #$A9
LDA #$A9
LDA #$A9
LDA #$A9
STX $D011
LDX #$38
STX $D011
This routine needs a little extra care, like
- the timer-irq trigger must happen at a cycle cycle >14 and <55 on rasterline 3 (mod8) of every char SUCH THAT after the first dejitter routine the [SBC $DC04] has its last read cycle @cycle#55
- the $DC04-timer must be configured SUCH THAT it gives value #19 on cycle 55 (the timer for the irq can be used for this, too, but that [LDA #val : SEC : SBC timer] must then be adjusted accordingly)
- the X-values plus the STX-Opcodes in the snipplet above are for setting the badlines, the rest is for dejittering
- the routine goes bork if more than 4 sprites are needed on one line
- all the sprite blocks must be configured SUCH THAT they always begin with sprite0 and use the next sprite numbers as needed, i.e. sprite0+1, sprite0+1+2 or sprite0+1+2+3
This should do the trick. |