Jump to content
IGNORED

Newbie trying to figure out horizontal movement. Like a space invaders base/ship.


Recommended Posts

So, I am doing some asm, up to the point of putting my sprite/ship on the screen at the bottom, like in space invaders.

 

I can get it to move left, right... but I can't for the life of me figure out how to figure out the screen limits for the ship.. and per my code, my ship is stopping at weird points on the screen.

 

The more I tweak it, I get things like fluttering sprites... then I adjust things like the height of my sprite through the drawing of my bitmap loop.  (Its 8, with a 9th row of blank)

but sometimes I make the drawing loop 8, sometimes 9, to get it to move smooth.  Not sure what is affecting it.  

 

I get that coding on the 2600 is a challenge.. but what is the best way to simplify it for us Newbies that are trying to understand, but need a little more explanation with things like horizontal movement...

Are other retro consoles this challenging?  C64/Atari400/800/nes, etc..

Link to comment
Share on other sites

                processor 6502              ; Default stuff
                include  "vcs.h"            ; Default stuff
                include  "macro.h"          ; Default stuff
 
;###################Cleanup tasks & variables################
    seg.u Variables
    org $80
 
Player0XPos                      byte   ; sprite X coordinate
 
    seg Code
    org $F000
reset
; Clear RAM and all TIA registers
    ldx #0
    lda #0
Clear          
    sta 0,x
    inx
    bne Clear
 
BACKCOLOR            = $94             ; define a symbol to represent a TIA color value (NTSC) $82 is Drk blue
                lda #$C2                ; greenw playfield color
                sta COLUPF              ; sets color value to PF
 
                lda #$62                ;color purple
                sta COLUP0              ;set color to player 0
                lda #39
                sta Player0XPos     ; initialize player X coordinate        
;################END Cleanup Tasks and variables#################
 
;##################PLAYFIELD REFLECT OPTION##############
reflect:
    ldx #%00000001 ; CTRLPF register (D0 is the reflect flag)
    stx CTRLPF
;##################### End PLAYFIELD REFLECT OPTION #####
 
;###########SET BACKGROUND####################            
background:
    lda #BACKCOLOR                    ; load the value from the symbol 'blue' into (a)
    sta COLUBK                          ; store (a) into the TIA background color register
;############END BACKGROUND###################
 
;#########DRAW THAT SCREEN!###################
 
StartFrame:                             ; start of new frame @ top of screen (Runs WYSYNC 3 times)
        ldx #%00000000
        stx PF0
        stx PF1
        stx PF2
 
    lda #2
    sta VBLANK     ; turn VBLANK on
    sta VSYNC      ; turn VSYNC on
    REPEAT 3
        sta WSYNC  ; three VSYNC scanlines
    REPEND
    lda #0
    sta VSYNC      ; turn VSYNC off                                       ; start of vertical blank processing
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set player horizontal position while we are in the VBLANK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    lda Player0XPos     ; load register A with desired X position
    and #$7F       ; same as AND 01111111, forces bit 7 to zero
                   ; keeping the value inside A always positive
 
    sec            ; set carry flag before subtraction
 
    sta WSYNC      ; wait for next scanline
    sta HMCLR      ; clear old horizontal position values
 
DivideLoop:
    sbc #15        ; Subtract 15 from A
    bcs DivideLoop ; loop while carry flag is still set
    eor #7         ; adjust the remainder in A between -8 and 7
    asl            ; shift left by 4, as HMP0 uses only 4 bits
    asl
    asl
    asl
    sta HMP0       ; set fine position value
    sta RESP0      ; reset rough position
    sta WSYNC      ; wait for next scanline
    sta HMOVE      ; apply the fine position offset
 
;-----------END OF 3 VSYNC LINES Now draw VERTICAL BLANK (37-2 Lines)
    REPEAT 35
        sta WSYNC
    REPEND
 
    lda #0
    sta VBLANK     ; turn VBLANK off
;----------------------------End Of Top 'Blank' Areas------------------------------
;---------------------DRAW SCREEN ROUTINE - draw 192 lines-----------------------
 
;------------------- Initialize X for 192 scanlines------------------------------
 
     REPEAT 184
        sta WSYNC  ; wait for 60 empty scanlines
    REPEND
 
        ldy 9      ; counter to draw 8 rows of bitmap
DrawBitmap:
    lda Player0Bitmap,Y ; load player bitmap slice of data
    sta GRP0       ; set graphics for player 0 slice
 
    lda P0Color,Y  ; load player color from lookup table
    sta COLUP0     ; set color for player 0 slice
 
    sta WSYNC      ; wait for next scanline
 
   dey
    bne DrawBitmap ; repeat next scanline until finished
 
    lda #0
    sta GRP0       ; disable P0 bitmap graphics
 
;----------------------End Player0 Bitmap-------------
 
    ldx #%00000000
    stx PF0
    stx PF1
    stx PF2





 
; -------------------------------------------END OF PLAYFIELD---------------
 
;------------------------- generate 30 scanlines of overscan bottom of screen (no changes needed here)----
 
;   ldx #0                              ; uses loop of 30 times to complete
overscan:    
    lda #2  
    sta VBLANK                          ; turn on vblank for overscann
    REPEAT 30
        sta WSYNC
    REPEND
 
CheckP0Left:
    lda #%01000000
    bit SWCHA
    bne CheckP0Right
    dec Player0XPos
            cmp Player0XPos,5
            bne CheckP0Right
             inc Player0XPos
               
 
CheckP0Right:
    lda #%10000000
    bit SWCHA
    bne NoInput
    inc Player0XPos
        cmp Player0XPos,50
        bne NoInput
        dec Player0XPos


 
skipincrease:
 
skipdecrease:
 
NoInput:
    ; fallback when no input was performed
 
    ldx #%00000000
    stx PF0
    stx PF1
    stx PF2


 
    jmp StartFrame                    ; frame is completed, branch back up to the 'startFrame' label
;############################## end of screen draw  LOOPS BACK TO StartFrame ##################


 
;########### BITMAPS ##########################################################################
;--------------Player 0 bitmap----------------
;   org $FFE8
Player0Bitmap:
    .byte %00000000 ;
    .byte %10000001 ;
    .byte %01011010 ;
    .byte %10100101 ;
    .byte %00011000 ;
    .byte %00011000 ;
    .byte %00011000 ;
    .byte %00011000 ;
    .byte %00011000 ;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lookup table for the player colors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
P0Color:
    byte #$00
    byte #$62
    byte #$56
    byte #$44
    byte #$44
    byte #$44
    byte #$44
    byte #$44
    byte #$44
 
;############# END OF BITMAPS #################################################################
 
; ---------------------------DEFAULT END OF PROGRAM JUNK
;   org $fffa  
    org $FFFC                         ; set origin to last 6 bytes of 4k rom
 
irq:
                .word reset                 ; NMI  ($FFFA) (Default stuff)
                .word reset                 ; RESET ($FFFC) (Default stuff)
                .word reset                 ; IRQ ($FFFE) (Default stuff)




 
Link to comment
Share on other sites

You have an extra compare in your left and right positioning adjustments, can you explain the purpose?

 

In the future, please post code as text in code tags:

image.thumb.png.6ff892c4096b97ffb750107b3d003907.png

 

Makes it much easier for those trying to help.

Link to comment
Share on other sites

On 1/14/2024 at 11:10 AM, bent_pin said:

You have an extra compare in your left and right positioning adjustments, can you explain the purpose?

 

In the future, please post code as text in code tags:

image.thumb.png.6ff892c4096b97ffb750107b3d003907.png

 

Makes it much easier for those trying to help.

After the joystick position check, the first compare just lowers the value for moving the sprite...  The second compare says that if it crosses a certain point, to increase by one, so that it cant keep moving left.  (Stops at left side of screen for example.)

 

Link to comment
Share on other sites

33 minutes ago, dgrams2000 said:

The second compare says that if it crosses a certain point, to increase by one, so that it cant keep moving left.

I thought that is what you were trying to do. That is not what you've done, though.

cmp Player0XPos,50
; cmp followed by a memory ZP memory address,offset
; compares what is in the accumulator to what is in the memory address + offset
; same flags as sbc with the same values
; Player0XPos address = $80
; $80 + 50 = 178 or $B2
; This instruction compares value in ZP$B2 to value in accumulator
; Value currently in accumulator is bitmask #%10000000 or -128

 

To compare the Player0XPos to 50, you need to load that value into the accumulator first, then use compare with the immediate value of 50.

lda Player0Pos
cmp #50
Link to comment
Share on other sites

47 minutes ago, bent_pin said:

I thought that is what you were trying to do. That is not what you've done, though.

cmp Player0XPos,50
; cmp followed by a memory ZP memory address,offset
; compares what is in the accumulator to what is in the memory address + offset
; same flags as sbc with the same values
; Player0XPos address = $80
; $80 + 50 = 178 or $B2
; This instruction compares value in ZP$B2 to value in accumulator
; Value currently in accumulator is bitmask #%10000000 or -128

 

To compare the Player0XPos to 50, you need to load that value into the accumulator first, then use compare with the immediate value of 50.

lda Player0Pos
cmp #50
CheckP0Left:
    lda #%01000000
    bit SWCHA
    bne CheckP0Right
    dec Player0XPos
    lda Player0XPos
    cmp #13
    bne CheckP0Right
    inc Player0XPos
               
CheckP0Right:
    lda #%10000000
    bit SWCHA
    bne NoInput
    inc Player0XPos
    lda Player0XPos
    cmp #124
    bne NoInput
    dec Player0XPos

Interesting.  That sound like a crucial thing that I did not know about.  Looks like that worked.  I can now move my ship accurately across the bottom, stopping at certain points.

 

Seems like you just cant plug in any old positions to compare against..  Like in my example above, If I change the left side to CMP #10, My sprite jumps all over moving left and right.  If it is CMP #13.. works fine.   I am guessing this has something to do with the fine tuning the object in a certain area (-8 to +7 pixels)  and that your numbers have to match up somewhere within that.   But anyways.. yes, it is working.  Thank you for the tip!  I will have about a bazillion more questions soon, I am sure.  haha

Edited by dgrams2000
Link to comment
Share on other sites

17 minutes ago, dgrams2000 said:

After the compare is done, should the accumulator get blanked out then?

Typically, I begin each operation by loading values into registers. As such, I see no reason in particular to clear values from registers. I usually assume that they've got garbage in them unless I'm intentionally carrying values through as part of an algorithm.

Link to comment
Share on other sites

2 minutes ago, bent_pin said:

Typically, I begin each operation by loading values into registers. As such, I see no reason in particular to clear values from registers. I usually assume that they've got garbage in them unless I'm intentionally carrying values through as part of an algorithm.

Makes sense.   

Link to comment
Share on other sites

28 minutes ago, dgrams2000 said:

Seems like you just cant plug in any old positions to compare against..  Like in my example above, If I change the left side to CMP #10, My sprite jumps all over moving left and right.  If it is CMP #13.. works fine.   I am guessing this has something to do with the fine tuning the object in a certain area (-8 to +7 pixels)  and that your numbers have to match up somewhere within that.   But anyways.. yes, it is working.  Thank you for the tip!  I will have about a bazillion more questions soon, I am sure.  haha

That's because of the type of branch that you are using. You are only checking for equality when you should be checking for a range. Try this one on your own. Think of what types of flags can branches that there are. Try just the left edge to begin with. You can use the carry flag and if you subtract a border value from the position value and that subtraction crosses the zero barrier, the carry flag will be cleared.

 

If you get the left side working, check back for a tip on the right side.

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