Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Joystick Port 2, Sprites, and ML
2010-07-26 13:04
MisterMSK
Account closed

Registered: Jul 2009
Posts: 37
Joystick Port 2, Sprites, and ML

Hi All,

Working with some code in ACME and was wondering if anyone knows an easy way to create 'stops'(preventing the sprite from looping on the screen) and having the sprite go all the way across the right side of the screen? I am using sprite 2 and joy port 2. Also, how would you do diagonals?

Here is the code I am using:
joystick clc 
    lda $dc00 
    lsr 
    bcc up 
    lsr 
    bcc down 
    lsr 
    bcc left 
    lsr 
    bcc right 
    jmp joystick 


up ldx $D005
      dex
      stx $D005
      jmp pauseit

down ldx $D005
      inx
      stx $D005
      jmp pauseit


left ldx $D004
      dex
      stx $D004
      jmp pauseit

right ldx $D004
      inx
      stx $D004
      jmp pauseit

pauseit ldx #1  ; 1 millisecond pause 
         lda #128
loop1 cmp $d012      ;check if the raster has reached line 128 
         bne loop1      ;no, so keep checking 
loop2 cmp $d012      ;if it has you want to make sure you dont catch it more than once per frame 
         beq loop2      ;so wait till it isn't 0 any more 
         dex 
         bne loop1      ;loop round 60*4 times
         jmp joystick
2010-07-26 13:29
JackAsser

Registered: Jun 2002
Posts: 2014
Regarding sprite position you have to realize that a sprite's x-position is 9-bit, not 8-bit. Bit 9 for all sprites are bit-packed into the $d010 register. Easiest is to treat your sprites as 16-bit (from the top of my head untested but u get the idea):

xpos_lo: .byte 0,0,0,0,0,0,0,0
xpos_hi: .byte 0,0,0,0,0,0,0,0
ypos:    .byte 0,0,0,0,0,0,0,0

; Call placeSprite to position sprite index x.
placeSprite:
   ; y = x*2
   txa
   asl
   tay

   ; Place y position and lo-part of x position is trivial.
   lda ypos,x
   sta $d001,y
   lda xpos_lo,x
   sta $d000,y

   ; Handle $d010 by first clearing the bit for the sprite
   lda $d010
   and bittab_inv,x

   ; The set the bit IF xpos_hi != 0
   ldy xpos_hi,x
   beq :+
      ora bittab,x
   :
   sta $d010
   
   rts

bittab: .byte $01,$02,$04,$08,$10,$20,$40,$80
bittab_inv: .byte !$01, !$02, !$04, !$08, !$10, !$20, !$40, !$80



Regarding joystick control using the above:
ldx #0; sprite to control

lda $dc00
sta TMP

lsr TMP
bcs :+
   inc ypos,x
:
lsr TMP
bcs :+
   dec ypos,x
:
lsr TMP
bcs :+
   clc
   lda xpos_lo,x
   adc #1
   sta xpos_lo,x
   lda xpos_hi,x
   adc #0
   sta xpos_hi,x
:
lsr TMP
bcs :+
   sec
   lda xpos_lo,x
   sbc #1
   sta xpos_lo,x
   lda xpos_hi,x
   sbc #0
   sta xpos_hi,x
:

jsr placeSprite


Hope that helps...
2010-07-26 17:14
SIDWAVE
Account closed

Registered: Apr 2002
Posts: 2238
its a bit more complicated than that, with expanded sprites.
when going left, to hide them under the border, d010 must be 1 and xpos 247 and downwards, to completely get rid of the sprite under left border..
2010-07-26 18:12
Trap

Registered: Jul 2010
Posts: 223
With the code you lay out, the easiest would be to do a check for out of bound position before you change the sprite position. Example:

right ldx $D004
inx
cmp #$ff
beq pauseit
stx $D004
jmp pauseit

Same principle for other boundaries.
Definitely go with 16bit for xpos, but since you didn't mention it I assume it isn't an issue.

A bit off topic, but you may want to change your $d012 check to somewhere off-screen to avoid tearing of the sprite when it moves. Move to #$ff or #$00 maybe.

Last time I coded is almost 20 years ago, so you'll have to excuse me if I am not up to speed on the lastest'n'greatest way of doing things :)

Trap
2010-07-27 15:32
MisterMSK
Account closed

Registered: Jul 2009
Posts: 37
Thanks. I actually found a bad way to do it but it kinda works.
left  lda $D004
      cmp #$00
      beq left2
      jmp left3
left2 lda $D010
      cmp #$00
      beq left3
      ldx #$00
      stx $D010
      ldx #$FF
      stx $D004
      jmp left3
left3 lda $D010
       cmp #$00
       bne left9
       lda $D004
       cmp #$1A
       beq pauseit
       jmp left9
left9 ldx $D004
      dex
      stx $D004
      jmp pauseit

right lda $D004
      cmp #$FF
      beq right2
      jmp right3
right2 lda $D010
      cmp #$04
      beq right3
      ldx #$04
      stx $D010
      ldx #$00
      stx $D004
      jmp right3
right3 lda $D010
       cmp #$04
       bne right9
       lda $D004
       cmp #$40
       beq pauseit
       jmp right9
right9 ldx $D004
      inx
      stx $D004
      jmp pauseit


the only problem is how do i only subtract or add 4 to $d010 instead of setting it to a specific value?
2010-07-27 17:07
JackAsser

Registered: Jun 2002
Posts: 2014
@MisterMSK: Brrrrr... :) Do it right and you won't have that type of questions.
2010-07-27 17:33
TWW

Registered: Jul 2009
Posts: 545
Quote: Thanks. I actually found a bad way to do it but it kinda works.
left  lda $D004
      cmp #$00
      beq left2
      jmp left3
left2 lda $D010
      cmp #$00
      beq left3
      ldx #$00
      stx $D010
      ldx #$FF
      stx $D004
      jmp left3
left3 lda $D010
       cmp #$00
       bne left9
       lda $D004
       cmp #$1A
       beq pauseit
       jmp left9
left9 ldx $D004
      dex
      stx $D004
      jmp pauseit

right lda $D004
      cmp #$FF
      beq right2
      jmp right3
right2 lda $D010
      cmp #$04
      beq right3
      ldx #$04
      stx $D010
      ldx #$00
      stx $D004
      jmp right3
right3 lda $D010
       cmp #$04
       bne right9
       lda $D004
       cmp #$40
       beq pauseit
       jmp right9
right9 ldx $D004
      inx
      stx $D004
      jmp pauseit


the only problem is how do i only subtract or add 4 to $d010 instead of setting it to a specific value?


left:

lda $d010
and #$00000100
beq NotAbove //Check if the sprite x position is over the 256 limit?

lda $d004 //Read current position (Which we know is larger then 256 border)
sec
sbc #speed //How fast do you want it to move
sta $d004 //Store new position (Which is correct even if you cross the 256 boundry!)
bcs NoBoundryCross
lda $d010
eor #%00000100
sta $d010 //Flipp $d010 if the boundry was crossed
NoBoundryCross:
rts

NotAbove: //The sprite position is less then 256 limit

lda $d004
sec
sbc #speed
cmp #LeftBoundry (#$18 if my memory serves me right)
bcs NoCrossBoundry
lda #LeftBoundry
NoCrossBoundry:
sta $d004
rts
// No need to do anything with $d010 here since we ain't going to cross it (Unless you experience problems like mentioned earlier with expanded sprites)!


Then you do something simmular for the Right movement.

Vertical is much easier since you don't need to worry about the 256 limit!

Regarding both vertical and horisontal movement you need to change the way your joystick routine is set up;

lda $dc00 //You don't need to clear carry here!
sta $02

lsr $02
bcc NoUp
jsr Up

Noup:
lsr $02
bcc NoDown
jsr Down

NoDown:
lsr $02


... etc

Which alowes you to detect several joystick movements at once.

ps I haven't tested this code so some branches or such might need tweaking. And yes I am sure this can be done in a more delicate way but I think this is ok for principals.
2010-07-27 20:17
Fresh

Registered: Jan 2005
Posts: 101
My two cents:
- box freely resizable
- left border fix
The box I've chosen allows a full stretched sprite to move freely in display area and to hide behind the borders

X1	equ 480
X2	equ 344
Y1	equ 8
Y2	equ 250

UpdateSprite
	Lda $d010
	Sta $fd
	Tax
	Eor #(X1>>8)
	Sta $fb
	Txa 
	Eor #(X2>>8)
	Sta $fc
	Lda $dc00	; Load Joy Port 2
	Ldx $d000	; Load X
	Ldy $d001	; Load Y		
	Lsr		; Test UP bit
	Bcs Down
	Cpy #Y1
	Beq Down
	Dey		
Down	Lsr		; Test DOWN bit
	Bcs Left
	Cpy #Y2
	Beq Left		
	Iny
Left	Lsr		; Test LEFT bit
	Bcs Right
	Cpx #(X1&$FF)	; Check left boundary
	Bne DoLeft
	Lda $FB		; Check highest bit
	Beq exit
DoLeft	Dex 
	Cpx #$ff	; Test underflow
	Bne Right		
	Lda $FD		; Fix left border
	Bne toggle
	Ldx #$F7
	Bne toggle
Right	Lsr		; Test RIGHT bit
	Bcs exit
	Cpx #(X2&$FF)	; Check right boundary
	Bne DoRight
	Lda $FC		; Check highest bit
	Beq exit
DoRight	Inx
	Beq toggle	; Test overflow
	Cpx #$F8
	Bne exit
	Lda $FD		; Fix left border
	Beq exit
	Ldx #$00
toggle	Lda $d010	; Toggle highest bit
	Eor #$01
	Sta $d010
exit	Sty $d001	; Save Y
	Stx $d000	; Save X
	Rts

RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
McMeatLoaf
d0c
ΛΛdZ
Acidchild/Padua
Guests online: 107
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top NTSC-Fixers
1 Pudwerx  (10)
2 Booze  (9.7)
3 Stormbringer  (9.7)
4 Fungus  (9.6)
5 Grim Reaper  (9.3)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.141 sec.