| | oziphantom
Registered: Oct 2014 Posts: 502 |
Cycle Excact Timings and moving sprites
What fancy techniques to people have for handling the need for cycle exact timing for effects and then having sprites move over it?
I'm thinking of having side borders partially open in places which then may or may not have a number of sprites over. My current thinking is to have sets of 4 clock burners per sprite with a d015 sprite value per line when then looks up a num sprites per line value table per line that then indexes into a Branch offset table. so
lda SpritesValue,x
tay
lda ValueToNumBitsSetLUT,y
tay
lda BranchOffsetTable,y
sta BranchOffset
BranchOffset = *+1
bne $00
lda $00,x
lda $00,x
lda $00,x
lda $00,x ; I think 4 sprites will be enough
38 col
40 col
check num lines and loop
BranchOffsetTable 01,03,05,07,09 ; can't remember at the moment it if needs to be 1 or 0
but I might be over complicating it... |
|
... 13 posts hidden. Click here to view all posts.... |
| | Pex Mahoney Tufvesson
Registered: Sep 2003 Posts: 54 |
@HCL: Yes, d017 in 1990 was probably lame (what do I know, I was into Amiga stuff then). But at least I thought I was cool when I did d017-stretching in 1988 in Skruv ... long before you were born, kiddo. :P ;)
---
Have a noise night!
http://mahoney.c64.org |
| | chatGPZ
Registered: Dec 2001 Posts: 11445 |
finally some decent arguments! =D |
| | HCL
Registered: Feb 2003 Posts: 728 |
Damnit.. <word> :P |
| | TWW
Registered: Jul 2009 Posts: 547 |
Code inside IRQ (positions the color bar split dead center):
ldy #$08
ldx #63
clc
Loop:
dec $d016
sty $d016
lda DYSP_DelayTableZP,x
sta SMC+1
SMC:
bcc *+2
and #$29
and #$29
and #$29
and #$29
and #$29
and #$29
and #$29
and #$29
and $ea
nop
lda CollTable1ZP,x
sta $d021
lda D11Table,x
sta $d011
dex
bpl Loop
Update timing table (after updating spirte positions):
CalculateDelayTableDYSP:
.pc = * "DYSP Delay Table"
// Initialize table
ldx #63
lda #$00 // 00 = no spirtes
!: sta DYSP_DelayTableZP,x
dex
bpl !-
.const kfactor = 1
// Fill in location of the sprites into the table (first and last+1 pixel)
lda $d001
sec
sbc #OffsetY
tax
lda #%00000001
sta DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d003
sec
sbc #OffsetY
tax
lda #%00000010
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%00000010
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d005
sec
sbc #OffsetY
tax
lda #%00000100
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%00000100
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d007
sec
sbc #OffsetY
tax
lda #%00001000
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%00001000
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d009
sec
sbc #OffsetY
tax
lda #%00010000
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%00010000
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d00b
sec
sbc #OffsetY
tax
lda #%00100000
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%00100000
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d00d
sec
sbc #OffsetY
tax
lda #%01000000
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%01000000
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
lda $d00f
sec
sbc #OffsetY
tax
lda #%10000000
ora DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor,x
lda #%10000000
ora DYSP_DelayTableZP+kfactor+21,x
sta DYSP_DelayTableZP+kfactor+21,x
// EOR Fill the spritemasks
lda #$00
.for (var i = 0 ; i < 64 ; i++) {
eor DYSP_DelayTableZP+i
sta DYSP_DelayTableZP+i
}
// Replace spritemasks with timing values
.for (var i = 0 ; i < 64 ; i++) {
ldx DYSP_DelayTableZP+i
lda TimingTable,x
sta DYSP_DelayTableZP+i
}
// Flipp Table
.for (var i = 0 ; i < 32 ; i++) {
lda DYSP_DelayTableZP+i+0
ldy DYSP_DelayTableZP+63-i
sty DYSP_DelayTableZP+i+0
sta DYSP_DelayTableZP+63-i
}
rts
A bit messy but does the trick (No need to flip the table but I was trying to squeeze cycles inside the IRQ Loop). Then all You need is the actual timing values which you simply brute force with a testprogram (spritemask + adjustable value tool of some sort). |
| | oziphantom
Registered: Oct 2014 Posts: 502 |
A lot of the docs are vague on Side borders. But from the timings it seems you can't do it on a bad line, which means you can't have chars and open side borders on the same row... also seems that vertical scrolling is out as the VIC displays black when you shift the screen up and down right? |
| | tlr
Registered: Sep 2003 Posts: 1798 |
Quote: A lot of the docs are vague on Side borders. But from the timings it seems you can't do it on a bad line, which means you can't have chars and open side borders on the same row... also seems that vertical scrolling is out as the VIC displays black when you shift the screen up and down right?
Not true. You can have 4 sprites with open sideborder on a badline.
What do you mean by vertical scrolling, $d011 Y-scroll? Sure you can, it just moves the badlines. |
| | ChristopherJam
Registered: Aug 2004 Posts: 1418 |
Nice work, TWW!
May I suggest replacing
lda $d001
sec
sbc #OffsetY
tax
lda #%00000001
sta DYSP_DelayTableZP+kfactor,x
sta DYSP_DelayTableZP+kfactor+21,x
with
ldx $d001
lda #%00000001
sta DYSP_DelayTableZP+kfactor-OffsetY,x
sta DYSP_DelayTableZP+kfactor+21-OffsetY,x
(might have to add $10000 to those addresses if OffsetY is greater than DYSP_DelayTableZP+1, which will add a couple of cycles to the stores, but still faster than subtracting OffsetY from X)
Should be able to save a few cycles off the second sprite's boundary plots too, by doing a CPX $d001 and selecting either %10 or %11 for the mask, then storing directly instead of lda/eor/sta
(edit - scratch that, won't work if the first two sprites are exactly 21 lines apart) |
| | tlr
Registered: Sep 2003 Posts: 1798 |
Quoting ChristopherJam(might have to add $10000 to those addresses if OffsetY is greater than DYSP_DelayTableZP+1, which will add a couple of cycles to the stores, but still faster than subtracting OffsetY from X)
It won't add cycles. zp,x doesn't have page boundary handling. It just wraps around in zp.
What you do is just take &$ff on the address to utilize that. |
| | ChristopherJam
Registered: Aug 2004 Posts: 1418 |
Quoting tlr
It won't add cycles. zp,x doesn't have page boundary handling. It just wraps around in zp.
What you do is just take &$ff on the address to utilize that.
Excellent point! |
| | oziphantom
Registered: Oct 2014 Posts: 502 |
Opening sideborders in the bottom border seems to work fine, but as I try and move the code to the top border, i.e Y=20, the sprites shown down the bottom of the screen where the border does open and at the top of the screen but the border is closed... Does it not work in the top border? |
Previous - 1 | 2 | 3 - Next | |