Re: [stella] Confused newbie...

Subject: Re: [stella] Confused newbie...
From: Kevin Lipe <kevin.lipe@xxxxxxxxx>
Date: Thu, 7 Oct 2004 00:32:37 -0500
OK... I've been beating myself over the head about all of this for
about four hours and still havent gotten Phred to display on the top
floorline and move around, which is what I've been aiming for.

I figured I should probably quit while I'm ahead and ask just how I'm
supposed to do all of this... I'm using the code from Kirk Israel's
2600 101 for the basic computations of which joystick direction is
pressed, mainly because I understand how it works.

Another thing that I haven't seen mentioned in any tutorials is... I'm
wanting to use Y as a scanline counter but all of the loops in the
code (which I guess wouldn't be there in a finalized game because all
of the scanlines would be taken by calculations) use DEX... and having
a DEY and a DEX together in the same loop keeping track of scanlines
really messes with the BNE's and then nothing will display at all...

In this source I've added the number/letter graphics (numbers courtesy
of Cosmic Ark) for my hex-counter level display and a preliminary
sprite for Phred because I was trying to get him to work. I've
attached my code and a binary that makes my pretty playfield and the
bottom row of the Phred sprite... wow. This is totally exasperating
and I have the utmost respect for anyone who write playable games for
this system because... I thought I understood it from the tutorials
but apparently I just thought I did...

Plus, Thomas I added your code from the post above, and though I know
my posLst is incomplete at this point, I think it's working because
there's an HMOVE bar in the side of the playfield now, and I just
threw some code together to display the sprite, which also didnt work.

Sorry I need to be lead through this like a toddler on a leash.

~ Kevin

On Wed, 6 Oct 2004 18:18:38 -0500, Kevin Lipe <kevin.lipe@xxxxxxxxx> wrote:
> Thanks... the only place on this screen that the sprites can't go are
> the far left and far right pixels of the playfield, which are the
> walls of the five-level thing... so would I just remove the smallest
> and largest values from posLst and make that work?
> 
> Also, in your code you reference the posLst, list of horizontal
> positions... what would this look like? I don't understand how to make
> such a list in my code.
> 
> Thanks for all the help, I'm now on my way to having a game, or at
> least a moving sprite :)
> 
> ~ Kevin
> 
> 
> 
> 
> On Wed, 6 Oct 2004 09:23:49 +0200, Thomas Jentzsch <tjentzsch@xxxxxx> wrote:
> > Kevin Lipe wrote:
> > > What would be the best way to position sprites and such in a kernel
> > > for the game concept I was talking about in the above thread? Attached
> > > is the code I've got right now, which just makes a really pretty
> > > playfield and nothing else.
> >
> > I suppose you want to reposition your sprites *inside* the kernel, right?
> >
> > The most simple code for this would look like this:
> >   ldx   index    ; the current sprite index
> >   lda   posLst,x ; a list containing all horizontal positions (0..159)
> >   sta   WSYNC
> > ----------------
> >   sec            ; 2
> > .wait:
> >   sbc   #15      ; 2
> >   bcs   .wait    ; 2/3
> >   eor   #$07     ; 2
> >   asl            ; 2
> >   asl            ; 2
> >   asl            ; 2
> >   asl            ; 2
> >   sta   HMP0     ; 3
> >   sta.w RESP0    ; 4  @23+n*5
> >   sta   WSYNC    ; 3
> > ----------------
> >   sta   HMOVE
> >
> > This is however a general solution, which allows positioning sprite 0 across
> > the whole screen and uses one whole scanline
> >
> > For your kernel you may need something more specialized, e.g.
> > - objects cannot move accross the whole screen, so you can free some
> >   cycles for other kernel stuff
> > - you don't have that much free time inside your kernel, then you should
> >   calculate the fine and coarse positioning values outside the kernel. This
> >   saves a few cycles and allows additional tricks (e.g. two different codes
> >   for positioning objects on the left and right, giving you more free cycles
> >   for other stuff)
> > - ...
> >
> > So this can get quite complicated later, but for a start I suppose using
> > something like the code above.
> >
> > Have fun!
> > Thomas
> > _______________________________________________________
> > Thomas Jentzsch         | *** Every bit is sacred ! ***
> > tjentzsch at web dot de |
> > ____________________________________________________
> > Aufnehmen, abschicken, nah sein - So einfach ist
> > WEB.DE Video-Mail: http://freemail.web.de/?mc=021200
> >
> >
> >
> >
> > Archives (includes files) at http://www.biglist.com/lists/stella/archives/
> > Unsub & more at http://stella.biglist.com
> > --+----------------------------------------------------------------
> > You are subscribed as: kevin.lipe@xxxxxxxxx
> > To unsubscribe, send email to:
> >   stella-unsub-191764@xxxxxxxxxxxxxxxxxx
> > Or go to:
> >   http://stella.biglist.com/unsub/stella/kevin.lipe@xxxxxxxxx
> > --+--
> >
> >
>
	LIST OFF 
;============================================================================
; P H R E D
; aka "Killer Cosmic Space Mutants"
; 
; (c)2004 Kevin Lipe
;============================================================================
; COMPILE WITH:
; dasm source.asm -f3 -v5 -osource.bin
;============================================================================

	processor 6502
	include vcs.h
	include macro.h


	LIST ON
;===============================================================================
; Build Number, incremented on every major update.
;
BUILD					= 31
;
;===============================================================================

;===============================================================================
; A S S E M B L E R   S W I T C H E S
;===============================================================================

NTSC                    = 0
PAL                     = 1

COMPILE_VERSION         = NTSC      	; change this to compile for different
    		                        ; regions

FILL_OPT		= 1		; fills the optimized space with NOPs
   
;============================================================================
; T I A   C O N S T A N T S
;============================================================================

HMOVE_L7          =  $70
HMOVE_L6          =  $60
HMOVE_L5          =  $50
HMOVE_L4          =  $40
HMOVE_L3          =  $30
HMOVE_L2          =  $20
HMOVE_L1          =  $10
HMOVE_0           =  $00
HMOVE_R1          =  $F0
HMOVE_R2          =  $E0
HMOVE_R3          =  $D0
HMOVE_R4          =  $C0
HMOVE_R5          =  $B0
HMOVE_R6          =  $A0
HMOVE_R7          =  $90
HMOVE_R8          =  $80

; values for ENAMx and ENABL
DISABLE_BM        = %00
ENABLE_BM         = %10

; values for NUSIZx
ONE_COPY          = %000
DOUBLE_SIZE       = %101
QUAD_SIZE         = %111
MSBL_SIZE1        = %000000
MSBL_SIZE2        = %010000
MSBL_SIZE4        = %100000
MSBL_SIZE8        = %110000

; values for REFPx
NO_REFLECT        = %0000
REFLECT           = %1000

; mask for SWCHB
P1_DIFF_MASK      = %10000000
BW_MASK           = %00001000       ; black and white bit
SELECT_MASK       = %00000010
RESET_MASK        = %00000001

; SWCHA joystick bits
MOVE_RIGHT        = %1000
MOVE_LEFT         = %0100
MOVE_DOWN         = %0010
MOVE_UP           = %0001
NO_MOVE           = %11111111

; general constants
SCREEN_WIDTH	  = 160			; width of screen, in pixels
NUM_DIGITS	  = 4			; number of digits in the score

;============================================================================
; U S E R   C O N S T A N T S
;============================================================================

; frame time values   
VBLANK_TIME          = $2C

; color constants
BLACK          = $00
WHITE          = $0E

GREEN_BLUE     = $A0
RED            = $30
YELLOW         = $1E
GREEN          = $C0
BLUE           = $90
LIGHT_BLUE     = $80
PURPLE         = $60
BROWN          = $E0

; game state values
SYSTEM_POWERUP       = %00001010
GAME_RUNNING         = %11111111 

; illegal opcodes allowed
NO_ILLEGAL_OPCODES = 0

;============================================================================
; R A M ( Z P )   V A R I A B L E S
;============================================================================

; CTRLPF shadow copy
CTRLPF_shadow 		= $80

; score / level counter = $81 and $82
SCORE 			= $81
ScoreLo 		= SCORE
ScoreHi 		= SCORE + 1

; frame counter (preliminary... this might need to be more complex)
FrameCount 		= $83

; Sprite index... current player being displayed
Index			= $84

; 2600 101 stuff
YPosFromBot		= $85
VisiblePlayerLine = $86

;===============================================================================
; M A C R O S
;===============================================================================

  MAC FILL_NOP
    IF FILL_OPT
      REPEAT {1}
         NOP
      REPEND
    ENDIF
  ENDM

;============================================================================
; R O M   C O D E
;============================================================================

	SEG Bank0
	ORG $F000
   
Reset
		CLEAN_START 

;------------------------------------------------
; Once-only initialisation...

		lda #YELLOW		; player 0 color = yellow
		sta COLUP0

		lda #RED		; player 1 color = red
		sta COLUP1

		lda #%00000001      	; Set both shadow copy and CTRLPF to "mirror" mode.
		sta CTRLPF_shadow
		sta CTRLPF 

		lda #$00		; clear playfield registers
		sta PF0
		sta PF1
		sta PF2
		
		lda #$01		; sets level/score to 1
		sta SCORE

		lda #0			; sets framecounter to zero
		sta FrameCount
;---------------------------------------

StartOfFrame				
; Start of new frame
; Start of vertical blank processing

		lda #0
		sta VBLANK

		lda #2
		sta VSYNC

		sta WSYNC
		inc FrameCount		 ; increments framecounter every VSync period
		
		sta WSYNC
                
		sta WSYNC                ; 3 scanlines of VSYNC signal
		
		lda #0
		sta VSYNC


               
;------------------------------------------------
; 37 scanlines of vertical blank...
           
;Main Computations; check down, up, left, right
;general idea is to do a BIT compare to see if
;a certain direction is pressed, and skip the value
;change if so

;
;Not the most effecient code, but gets the job done,
;including diagonal movement
;

; for up and down, we INC or DEC
; the Y Position

		lda #%00010000	;Down?
		bit SWCHA
		bne SkipMoveDown
		inc YPosFromBot
SkipMoveDown

		lda #%00100000	;Up?
		bit SWCHA
		bne SkipMoveUp
		dec YPosFromBot
SkipMoveUp

; for left and right, we're gonna
; set the horizontal speed, and then do
; a single HMOVE.  We'll use X to hold the
; horizontal speed, then store it in the
; appropriate register

;assume horiz speed will be zero
		ldx #0

		lda #%01000000	;Left?
		bit SWCHA
		bne SkipMoveLeft
		ldx #$10	;a 1 in the left nibble means go left

; moving left, so we need the mirror image
		lda #%00001000   ;a 1 in D3 of REFP0 says make it mirror
		sta REFP0

SkipMoveLeft
		lda #%10000000	;Right?
		bit SWCHA
		bne SkipMoveRight
		ldx #$F0	;a -1 in the left nibble means go right...

; moving right, cancel any mirrorimage
		lda #%00000000
		sta REFP0
SkipMoveRight

		stx HMP0	;set the move for player 0, not the missile like last time...

	;just a review...comparisons of numbers always seem a little backwards to me,
	;since it's easier to load up the accumulator with the test value, and then
	;compare that value to what's in the register we're interested.
	;in this case, we want to see if D7 of CXM1P (meaning Player 0 hit
	; missile 1) is on. So we put 10000000 into the Accumulator,
	;then use BIT to compare it to the value in CXM1P

		lda #%10000000
		bit CXP0FB
		beq NoCollision	;skip if not hitting...
		lda YPosFromBot	;must be a hit! load in the YPos...
		sta YPosFromBot	;and store it again... just an example.
NoCollision
		sta CXCLR	;reset the collision detection for next time
		sta WSYNC

;-------------------------
		ldx #36
VerticalBlank	sta WSYNC
		dex
		bne VerticalBlank

;------------------------------------------------
; The visible part 

		ldx #15
ScoreArea	sta WSYNC
		dex
		bne ScoreArea

TopLine		lda #LIGHT_BLUE		; makes the playfield blue (normal color)
		sta COLUPF

		lda #%11111111
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC

		lda #%00010000          ; PF0 is mirrored <--- direction, low 4 bits ignored
		sta PF0
		lda #0
		sta PF1
		sta PF2

		ldx #31
FirstFloor	sta WSYNC		; empty space for the first level
		dex		
		bne FirstFloor

FirstFloorLine	lda #%11111111		; floor of the first level
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC

		lda #%00010000          
		sta PF0
		lda #0
		sta PF1
		sta PF2

		lda HexA
		sta GRP0

		lda #0
		sta Index
		
		ldx Index    ; the current sprite index
		lda posLst,x ; a list containing all horizontal positions (0..159)
		sta WSYNC
;--------------------------------
 		sec            ; 2
.wait:
		sbc #15        ; 2
 		bcs .wait      ; 2/3
		eor #$07       ; 2
 		asl            ; 2
 		asl            ; 2
 		asl            ; 2
 		asl            ; 2
 		sta HMP0       ; 3
 		sta.w RESP0    ; 4  @23+n*5
 		sta WSYNC      ; 3
;------------------------------
 		sta   HMOVE

		ldx #30
SecondFloor	sta WSYNC
		dex			; empty space for second level
		bne SecondFloor

SecondFloorLine	lda #%11111111		; floor of the second level
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC

		lda #%00010000          
		sta PF0
		lda #0
		sta PF1
		sta PF2

		ldx #31
ThirdFloor	sta WSYNC		; empty space for third level
		dex			
		bne ThirdFloor

ThirdFloorLine	lda #%11111111		; floor of the third level
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC

		lda #%00010000
		sta PF0
		lda #0
		sta PF1
		sta PF2

		ldx #31
		lda Phred0
FourthFloor	sta WSYNC		; empty space for fourth level 
		sta GRP0
		sta RESP0
		lda Phred0 + 1
		dex			
		bne FourthFloor

FourthFloorLine	lda #%11111111		; floor of the fourth level
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC
	
		lda #%00010000
		sta PF0
		lda #0
		sta PF1
		sta PF2	

		ldx #31
FifthFloor	sta WSYNC		; empty space for fifth level 
		dex
		bne FifthFloor

FifthFloorLine	lda #%11111111		; floor of the fifth level
		sta PF0
		sta PF1
		sta PF2
		sta WSYNC

BottomField	lda #0
		sta PF0
		sta PF1
		sta PF2

		ldx #8
BottomCycle	sta WSYNC
		dex
		bne BottomCycle		
;------------------------------------------------
		lda #%01000010
		sta VBLANK           ; end of screen - enter blanking

    ; 30 scanlines of overscan...

		ldx #30
oScan 	sta WSYNC
		dex
		bne oScan

		jmp StartOfFrame 
;------------------------------------------------


;============================================================================
; R O M   D A T A
;============================================================================

posLst:								; List of horizontal positions
	.byte #0
	.byte #1
	.byte #2
	.byte #3
	.byte #4
	.byte #5
	.byte #6
	.byte #7
	.byte #8
	.byte #9
	.byte #10
	.byte #11
	.byte #12
	.byte #13
	.byte #14
Zero:
    .byte %00000000 ; |        |
    .byte %00111110 ; |  XXXXX |
    .byte %00100110 ; |  X  XX |
    .byte %00100110 ; |  X  XX |
    .byte %00100110 ; |  X  XX |
    .byte %00100110 ; |  X  XX |
    .byte %00100110 ; |  X  XX |
    .byte %00100010 ; |  X   X |
    .byte %00100010 ; |  X   X |
    .byte %00111110 ; |  XXXXX |
One:
    .byte %00000000 ; |        |
    .byte %00011000 ; |   XX   |
    .byte %00011000 ; |   XX   |
    .byte %00011000 ; |   XX   |
    .byte %00011000 ; |   XX   |
    .byte %00011000 ; |   XX   |
    .byte %00001000 ; |    X   |
    .byte %00001000 ; |    X   |
    .byte %00001000 ; |    X   |
    .byte %00001000 ; |    X   |
Two:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01111110 ; | XXXXXX |
    .byte %00000010 ; |      X |
    .byte %00000010 ; |      X |
    .byte %01000010 ; | X    X |
    .byte %01111110 ; | XXXXXX |
Three:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00111100 ; |  XXXX  |
    .byte %00000100 ; |     X  |
    .byte %01000100 ; | X   X  |
    .byte %01111100 ; | XXXXX  |
Four:
    .byte %00000000 ; |        |
    .byte %00001100 ; |    XX  |
    .byte %00001100 ; |    XX  |
    .byte %00001100 ; |    XX  |
    .byte %01111110 ; | XXXXXX |
    .byte %01000100 ; | X   X  |
    .byte %01000100 ; | X   X  |
    .byte %01000100 ; | X   X  |
    .byte %01000100 ; | X   X  |
    .byte %01000100 ; | X   X  |
Five:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %01111110 ; | XXXXXX |
    .byte %01000000 ; | X      |
    .byte %01000000 ; | X      |
    .byte %01111110 ; | XXXXXX |
Six:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %01111110 ; | XXXXXX |
    .byte %01000000 ; | X      |
    .byte %01000000 ; | X      |
    .byte %01000010 ; | X    X |
    .byte %01111110 ; | XXXXXX |
Seven:
    .byte %00000000 ; |        |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000010 ; |      X |
    .byte %00111110 ; |  XXXXX |
Eight:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %01000110 ; | X   XX |
    .byte %01100110 ; | XX  XX |
    .byte %00111100 ; |  XXXX  |
    .byte %00100100 ; |  X  X  |
    .byte %00100100 ; |  X  X  |
    .byte %00111100 ; |  XXXX  |
Nine:
    .byte %00000000 ; |        |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00000110 ; |     XX |
    .byte %00111110 ; |  XXXXX |
    .byte %00100010 ; |  X   X |
    .byte %00100010 ; |  X   X |
    .byte %00100010 ; |  X   X |
    .byte %00111110 ; |  XXXXX |
HexA:
    .byte %00000000 ; |        |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01111100 ; | XXXXX  |
    .byte %01001000 ; | X  X   |
    .byte %01001000 ; | X  X   |
    .byte %01001000 ; | X  X   |
    .byte %01111000 ; | XXXX   |
HexB:
    .byte %00000000 ; |        |
    .byte %01111100 ; | XXXXX  |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01111100 ; | XXXXX  |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01111100 ; | XXXXX  |
HexC:
    .byte %00000000 ; |        |
    .byte %00111110 ; |  XXXXX |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %00111110 ; |  XXXXX |
HexD:
    .byte %00000000 ; |        |
    .byte %01111100 ; | XXXXX  |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01100010 ; | XX   X |
    .byte %01111100 ; | XXXXX  |
HexE:
    .byte %00000000 ; |        |
    .byte %01111110 ; | XXXXXX |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01111100 ; | XXXXX  |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01111110 ; | XXXXXX |
HexF:
    .byte %00000000 ; |        |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01111100 ; | XXXXX  |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01100000 ; | XX     |
    .byte %01111110 ; | XXXXXX |
Blank:
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |
    .byte %00000000 ; |        |

Phred0: ; just a quick idea of what Phred might end up looking like, just for the sake of 
		; getting something together that looks kinda like Phred for use in the sprite 
		; positioning code writing process...
	.byte %01100110 ; | XX  XX |
	.byte %01100110 ; | XX  XX |
	.byte %00111100 ; |  XXXX  |
	.byte %01111110 ; | XXXXXX |
	.byte %01111110 ; | XXXXXX |
	.byte %01111110 ; | XXXXXX |
	.byte %00111100 ; |  XXXX  |
	.byte %00111100 ; |  XXXX  |
	



;===============================================================================
; V E C T O R S
;===============================================================================

        ORG $FFFA

InterruptVectors

	.word Reset           ; NMI
        .word Reset           ; RESET
        .word Reset           ; IRQ
	END   

Attachment: phred.bin
Description: application/macbinary

Current Thread