Jump to content
IGNORED

48-pixel moving sprite revisited


Hornpipe2

Recommended Posts

bigmove.asm is a great bit of code but unfortunately I had problems with it: it uses 'lazy' horizontal positioning code to move the sprite left and right. That makes it pretty much useless for anything I wanted. I was having problems pasting bigmove.asm code into my existing kernel, so I thought I should just update bigmove to use 'normal' positioning and then graft my existing kernel onto a known-working example.

 

So, here is bigmove3.asm, which has been rewritten slightly to use a couple extra RAM bytes and do the usual dynamic positioning during VBLANK. Hopefully someone can find a use for it - I know I have... ;)

 

Optimizations abound of course, since P1 is always locked 8 pixels behind P0. I thought perhaps I should hit RESP1 immediately after RESP0 and then HMOVE one pixel to the left, skipping the loop and saving one byte of RAM - but every 16th pixel will cause overflow problems and I hadn't found an elegant way around that. I suppose one way is to just burn an extra scanline with

 

...
Jiggle  dey
      bpl Jiggle

      sta RESP0
      sta RESP1

      sta WSYNC
      sta HMOVE
; no changing HM regs within 24 cycles of HMOVE!
jsr Ret
jsr Ret
lda #$10 ; let's move P1 sprite left 1 pixel!
sta HMCLR ; does HMOVE reset HM regs to 0?
sta HMP1
      sta WSYNC
      sta HMOVE

      JMP     VblankLoop
Ret	rts

 

Anyway, have at it!

bigmove3.asm.txt

bigmove3.bin

Edited by Hornpipe2
Link to comment
Share on other sites

For a big moving sprite to work properly, the code must include a delay that gets within a cycle of a known position. Thus, any RESPx at that spot will be known within two pixels. I would think the cleanest approach would be to use a variable delay so that RESP0/RESP1 will occur right where they should, and then and then have a big 'wait' block which hits HMOVE once at something resembling the right place. There's actually a fair bit of tolerance on when HMOVE is hit, so the code wouldn't have to be overly complicated.

 

Something like:

  lda #0
 clc
lp:
 adc #24
 cmp playerpos
 bcs lp
 sta HMOVE
lp2:
 sbc #24
 cmp #176
 bcs lp2

should be able to hit the HMOVE in the right place while having constant total execution time.

Link to comment
Share on other sites

Here's the code that positions both sprites adjacent in Seawolf:

 

	LDA xPos,X
STA WSYNC
.wait
SBC #$0F	  ; Battlezone calculate/wait
BCS .wait	 ; 2 in 1 magic !
AND #$0F	  ; Manuels "forget about EOR/ASL
TAX		; nonsense" magic :-)
LDA hmovetab,X;
STA HMP1	  ; Fine Position sprite 1
SBC #$0F	  ; carry is clear, so subtract $0F instead of $10
STA HMP0	  ; Fine Position 1 pixel corrected sprite 2
STA RESP0	 ;
STA RESP1	 ;
STA WSYNC	 ;
STA HMOVE	 ; Begin repositioning scannline
.
.
.
hmovetab
.byte $80,$70,$60,$50,$40,$30,$20,$10,$00
.byte $F0,$E0,$D0,$C0,$B0,$A0,$90

Link to comment
Share on other sites

EDIT: I was having problems using that code but now it's fixed - needed a CLC somewhere around LDA XPosition,X or else everything was getting shifted right 1 pixel when movement happened. New source and binary attached. This looks like it will be exactly what I need, thanks!

 

EDIT2: Is there a good way to generate DelayPTR on-the-fly? I think it's just 'divide XPosition by 3, store #JNDelay+36-quotient in DelayPTR'?

 

Who knows a fast divide-by-3?

bigmove3.asm.txt

bigmove3.bin

Edited by Hornpipe2
Link to comment
Share on other sites

Again a snippet from Seawolf. I remember I was using a table before that, which is certainly the ultimate solution regarding speed. In the end of the project I found that I have enough time for caculating the values, reclaiming the space for the table.

 

This is just showing the concept. It did the job for my ships, but needs tweaking for other cases:

 

; Do the math. The following calculates this formula:
; Y = 211 - int((X+2)/3)

LDX #SHIP_STRIPES-1
CalculateDelay
LDY #$01
LDA xPos,X
CLC
ADC #02
SEC

DivideBy3
DEY
SBC #$03
BCS DivideBy3
TYA
ADC #<JNDELAY+46
STA xDelay,X
DEX
BPL CalculateDelay

Link to comment
Share on other sites

AND #$0F ; Manuels "forget about EOR/ASL

TAX ; nonsense" magic :-)

 

If you can put the motion table in the last 15 bytes of a page, that will let you save two cycles. You can also save two cycles without being so restrictive of the table address if X contains a known value whose four LSB's are all set (if X contains $nF, then use "SBX #$n1").

Link to comment
Share on other sites

TAX	 ; nonsense" magic :-)

 

But what does it do! lol :D

 

Together with the line above it, it forms a sentence :P

 

" AND #$0F ; Manuels "forget about EOR/ASL TAX ; nonsense" magic :-) " doesn't make much sense tho!

 

The punctuation is horrid too!

 

srsly.

 

--

Mord

:D

Link to comment
Share on other sites

I was desperately needing those two cycles in the repositioning code area back then ;)

 

If you're positioning multiple sprites but don't need Y as a loop variable, you could save even more cycles by preloading A with 255, loading X with the desired position, and using SBX instead of SBC within the loop. That would leave the X register all set to load the HMxx value into Y.

Link to comment
Share on other sites

" AND #$0F ; Manuels "forget about EOR/ASL TAX ; nonsense" magic :-) " doesn't make much sense tho!

 

Hm... where's that flamethrower...

 

Careful with those, you could poke someone's eye out! :)

 

 

--

Mord

This is why I shouldn't post immediately before and after bed. ;)

Link to comment
Share on other sites

I was desperately needing those two cycles in the repositioning code area back then ;)

 

If you're positioning multiple sprites but don't need Y as a loop variable, you could save even more cycles by preloading A with 255, loading X with the desired position, and using SBX instead of SBC within the loop. That would leave the X register all set to load the HMxx value into Y.

Ooooh...have to look into that!

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