;ENHANCING YOUR GAME ;THIS IS AN EXAMPLE TUTORIAL FOR YOU TO ;LEARN HOW TO CREATE YOUR OWN 2 PLAYER ;SHOOT'EM UP, WHICH INCLUDES JOYSTICK ;CONTROL, A SCORE SYSTEM, ETC. ÁLSO NOW ;INCLUDING BITMAP GRAPHICS AND A RASTER ;SPLIT. ;LET'S SETUP THE PERAMETERS FOR OUR ;GAME. ÔHESE ARE THE PLAYER POSITIONS. PLR1_X = $0340 ;PLAYER 1 X-POSITION PLR1_Y = $0341 ;PLAYER 1 Y-POSITION PLR2_X = $0342 ;PLAYER 2 X-POSITION PLR2_Y = $0343 ;PLAYER 2 Y-POSITION ;YOUR PARAMETERS FOR THE PLAYER BULLETS PLR1B_X = $0344 ;PLAYER 1 BULLET-XPOS PLR1B_Y = $0345 ;PLAYER 1 BULLET-YPOS PLR2B_X = $0346 ;PLAYER 2 BULLET-XPOS PLR2B_Y = $0347 ;PLAYER 2 BULLET-YPOS ;COLLISIONS PARAMETERS PLR1COL = $0350 ;VALUE STORAGE FOR P1 PLR2COL = $0354 ;VALUE STORAGE FOR P2 ;BULLET LOCKUP ROUTINES PLR1LOCKUP = $0360 ;LOCKUP FOR PLAYERS PLR2LOCKUP = $0361 ;SHOOTING ;FIRST OF ALL, INSERT MUSIC DATA AT $1000; ;REMEMBER TO EXTRACT PRG FILES FROM D64 ;INTO THE SAME FOLDER AS THIS CODE. *=$1000-2 .BINARY "MUSIC.PRG" ;DASM USE INCBIN, ACME USE !BIN OR !BINARY ;wE NEED TO CREATE A JUMP START FOR THIS ;EXAMPLE, SO WE WILL CREATE OUR OWN JUMP ;ADDRESS WHERE IT DOES NOT OVERLAP DATA ;WHICH HAD BEEN LOADED. *= $2400 ;DASM USERS, PLEASE USE ; ; PROCESSOR 6502 ; ORG $2400 ;INSTEAD OF * = $2400 START SEI ;SET IRQ FLAG ;CLEAR THE SCREEN WITHOUT JSR $E544 LDX #$00 ;ÃALLS A ROUTINE CLEAR LDA #$20 ;TO FILL THE WHOLE STA $0400,X ;SCREEN WITH #$20, STA $0500,X ;WHICH IS THE STA $0600,X ;BLANK SPACE STA $06E8,X ;ROUTINE. ;WE HAVE ADDED THE COLOUR DATA FROM ;$5800-$5BE8 AS IT IS THE COLOUR DATA ;TO DISPLAY THE VIDCOM PICTURE COLOURS LDA $5800,X STA $D800,X LDA $5900,X STA $D900,X LDA $5A00,X STA $DA00,X LDA $5AE8,X STA $DAE8,X INX BNE CLEAR ;YOU SHOULD BE FAMILIAR WITH THE NEXT ;EXAMPLE CODE. ÉF NOT THEN LOOK AT THE ;EARLIER CHAPTERS OF Á$$ÅÍÂÌÅ ÉÔ! LDA #$00 STA $D020 STA $D021 LDA #$16 STA $D018 LDA #$1B STA $D011 LDA #$FF STA $D015 STA $D01C;SWITCH ON MULTICOLOR LDA #$0B STA $D025 ;MULTICOLOR 1 LDA #$0C STA $D026 ;MULTICOLOR 2 ;NOW HERE WE CREATE THE SPRITE OBJECTS, ;WHERE OUR SPRITES HAVE BEEN RELOCATED ;TO $5000 SO WE CAN DISPLAY THE SPRITES ;USING $DD00 BANK #$02 LDA #$01 STA $5FF8 ;ÐLAYER 1 SHIP LDA #$02 STA $5FF9 ;ÐLAYER 1 BULLET LDA #$00 STA $5FFA ;ÐLAYER 2 SHIP LDA #$02 STA $5FFB ;ÐLAYER 2 BULLET ;THIS IS WHERE WE SETUP THE COLOURS OF ;THE TWO PLAYERS AND BULLETS. LDA #$0A ;ÃOLOUR PINK STA $D027 ;ÐLAYER 1 STA $D028 ;ÐLAYER 1 BULLET LDA #$07 ;ÃOLOUR YELLOW STA $D029 ;ÐLAYER 2 STA $D02A ;ÐLAYER 2 BULLET ;THIS IS A DIFFERENT ROUTINE, AS NOW THE ;DEFAULT SPRITE POSITIONS ARE COPIED TO ;THE DECLARED PARAMETERS. LDA $D000 ;ÔHIS IS A METHOD STA PLR1_X ;OF COPYING AND LDA $D001 ;PASTING THE SPRITE STA PLR1_Y ;POSITIONS SO THAT LDA $D002 ;YOU CAN USE THIS STA PLR1B_X ;TO PROGRAM THE LDA $D003 ;SPRITES POSITIONS STA PLR1B_Y ;LATER ON IN THE LDA $D004 ;ROUTINES, FOR A STA PLR2_X ;MUCH FASTER LDA $D005 ;AND DECENT STA PLR2_Y ;MOVEMENT FOR ALL LDA $D006 ;THE SPRITES IN STA PLR2B_X ;THIS GAME. LDA $D007 STA PLR2B_Y ;NOW WE REPOSITION THE TWO PLAYERS AND ;PUT THE BULLETS INTO ZERO LDA #$42 ;ÁLL THIS IS THE STA PLR1_Y ;REPOSITIONING THE LDA #$18 ;TWO PLAYER SHIPS, STA PLR1_X ;BY USING THE 'X' LDA #$E0 ;POSITIONS AND THE STA PLR2_Y ;'Y' POSITIONS, LDA #$98 ;AS SIMPLE AS THAT STA PLR2_X ;:) LDA #$00 ;ÁLL BULLETS ARE STA PLR1B_X ;REPOSITIONED TO STA PLR1B_Y ;THE ZERO VALUE STA PLR2B_X ;YET AGAIN 'X' AND STA PLR2B_Y ;'Y' POSITIONS ;SETUP THE SCOREBOARD LDA #$30 ;×E PUT ZERO ON: STA $0400 ;FIRST LINE LDA #$02 ;PAINT FIRST LINE STA $D800 ;RED LDA #$30 ;ZERO PUT ON STA $0427 ;FIRST LINE AS LAST LDA #$07 ;PAINT CHARACTER STA $D827 ;YELLOW ;NOW FOR THE MAIN BODY OF THIS PROGRAM ;THE ÉNTERRUPT FLAG, BUT WE WONT USE ;ÊÍÐ $ÅÁ81 OR ÊÍÐ $ÅÁ31, AS NO KEYBOARD ;CONTROL WILL BE REQUIRED LDA #INT ; INTO AN IRQ RASTER LDY #$00 ; INTERRUPT VALUE AND STA $0314 ; ZERO THE RASTERLINE STX $0315 ; STY $D012 LDA #$7F ; KEEP THE SCREEN ON LDX #$1B ; AND CONTINUE THE STA $DC0D ; MAIN INTERRUPT STX $D011 ; READ LDA #$00 ;INITIALISE MUSIC TAX ;ACCORDING TO TUNE TAY ;NUMBER JSR $1000 ; LDA #$01 STA $D019 ;IRQ IS TURNED ON STA $D01A ;---------------- LDA $DC0D ;COPY $DCOD TO $DD0D STA $DD0D ;TO HAVE THE IRQ ;WORKING PROPERLY. CLI ;CLEAR IR FLAG LOOP JMP LOOP ;JUMP TO THE LOOP ;ÏUR MAIN INTERRUPT INT ASL $D019 ;KEEP $A019 RUNNING ;CALL ROUTINES TO EXECUTE THE 2 RASTER ;SPLITS JSR SPLITS ;CALL ROUTINE TO EXPAND AND RECONVERT ;SPRITE POSITIONS JSR EXPAND ;CALL ROUTINE TO READ JOYSTICK PORT 2 ;FOR PLAYER 1 AND PLAYER 2 JSR READ1UP JSR READ2UP ;CALL ROUTINE FOR BULLET MOVEMENTS JSR BULLMOVE ;CALL ROUTINE FOR COLLISION DETECTION ;AND PLAYER 1 AND PLAYER 2 BULLET TO ;PLAYER COLLISION. JSR DETECT JSR P1COL JSR P2COL ;AND FINALLY PLAY THE MUSIC JSR $1003 ;PLAY MUSIC PLA ; ÁN IRQ LOOP ROUTINE. TAY ; PLA ; THIS WILL KEEP ALL THE TAX ; JSR ROUTINES PLAYING PLA ; WITHOUT USING JMP $EA7E RTI ; ;EXPAND AND RECOVER THE SPRITE POSITION EXPAND LDA PLR1_Y ;COPY PLAYER Y STA $D001 ;TO EXACT POSITION LDA PLR1B_Y ;COPY BULLET 1 Y STA $D003 ;TO EXACT POSITION LDA PLR2_Y ;THE SAME GOES STA $D005 ;WITH THIS ROUTINE LDA PLR2B_Y ;BUT INSTEAD IT STA $D007 ;WORKS WITH P2. LDA PLR1_X ;COPY PLAYER X ASL A ;CALCULATE 64 ROR $D010 ;EXPAND X POS. STA $D000 ;PUT AT EXACT XPOS LDA PLR1B_X ;COPY BULLET ASL A ;AND DO THE SAME ROR $D010 ;AS WITH THE STA $D002 ;PLAYER. LDA PLR2_X ; ASL A ;ÁLL THIS IS THE ROR $D010 ;SAME EXCEPT THAT STA $D004 ;IT WILL WORK WITH LDA PLR2B_X ;PLAYER 2 AND THE ASL A ;PLAYER 2 BULLET ROR $D010 ;INSTEAD. STA $D006 ; RTS ; ;READ JOYSTICK CONTROL FOR PLAYER1 READ1UP LDA $DC00 ;READ PORT 2 LSR A ;JOYSTICK UP LSR A ;JOYSTICK DOWN LEFT1 LSR A ;JOYSTICK LEFT BCS RIGHT1 LDX PLR1_X ;MOVE PLAYER 1 DEX ;LEFT ACROSS SCREEN DEX ;USING 2 FOR SPEED CPX #$0E ;DOES THE PLAYER BCS SET1 ;MOVE FURTHER THAN LDX #$0E ;$0E, IF SO THEN SET1 STX PLR1_X ;STOP. ÅLSE CONTINUE RIGHT1 LSR A ;JOYSTICK RIGHT BCS FIRE1 LDX PLR1_X ;MOVE PLAYER 1 INX ;RIGHT ACROSS SCREEN INX ;USING THE SAME CPX #$9A ;SPEED. ÉF PLAYER BCC SET2 ;EXCEEDS $9A, THEN LDX #$9A ;MAKE THE PLAYER SET2 STX PLR1_X ;STOP. FIRE1 LSR A ;FIREBUTTON BCS NOJOY1 LDA PLR1LOCKUP ;IS PLAYER FIRE CMP #$00 ;CONTROL BNE NOJOY1 ;UNLOCKED. IF SO LDA #$01 ;THEN LOCK FIRE STA PLR1LOCKUP ;AND POSITION LDX PLR1_X ;THE BULLET X STX PLR1B_X ;AND Y POSITIONS LDX PLR1_Y ;EXACTLY AT THE STX PLR1B_Y ;SAME AREAS AS ;THE PLAYER. NOJOY1 RTS ;READ JOYSTICK CONTROL FOR ÐLAYER 2 ;(JOYSTICK PORT 1) READ2UP LDA $DC01 ;READ JOY PORT 1 LSR A ;UP LSR A ;DOWN ;PLEASE READ THE LEFT2 LSR A ;LEFT ;PLAYER 1 BCS RIGHT2 ;JOYSTICK CONTROL LDX PLR2_X ;AS THIS ROUTINE DEX ;IS EXACTLY THE DEX ;SAME AS THE CPX #$0E ;PLAYER 1 CONTROLS BCS SET1_1 ;BUT WORKS FOR LDX #$0E ;PLAYER 2. SET1_1 STX PLR2_X RIGHT2 LSR A BCS FIRE2 LDX PLR2_X INX INX CPX #$9A BCC SET1_2 LDX #$9A SET1_2 STX PLR2_X FIRE2 LSR A BCS NOJOY2 LDA PLR2LOCKUP CMP #$00 BNE NOJOY2 LDA #$01 STA PLR2LOCKUP LDX PLR2_X STX PLR2B_X LDX PLR2_Y STX PLR2B_Y NOJOY2 RTS ;CALL BULLET ROUTINES BULLMOVE LDX PLR1B_Y ;THE BULLET MOVES INX ;BUT IF IT HITS INX ;$Æ6+ IT WILL STOP INX ;OFF SCREEN ELSE INX ;IF BELOW THAT INX ;LIMIT, THE BULLET INX ;/ MOVES ON, ELSE CPX #$F6 ;BULLET OFF SCREEN BCC REPSBUL1 LDA #$00 ;TURN OFF THE STA PLR1LOCKUP ;FIRE LOCKUP LDX #$F6 REPSBUL1 STX PLR1B_Y LDX PLR2B_Y ;THE BULLET MOVES DEX ;UP BUT IF IT HITS DEX ;$0Ã- IT WILL STOP DEX ;OFF SCREEN, ELSE DEX ;IF BELOW THAT DEX ;LIMIT, THE BULLET DEX ;/ MOVES ON. ELSE CPX #$06 ;BULLET OFF SCREEN BCS REPSBUL2 LDA #$00 ;TURN OFF THE STA PLR2LOCKUP ;FIRE LOCKUP LDX #$06 REPSBUL2 STX PLR2B_Y RTS ;SETUP COLLISION DETECTION FOR PLAYER 1 ;AND PLAYER 2 DETECT LDA PLR1_X ;CALCULATE SEC ;THE STORAGE SBC #$06 ;VALUES FOR STA PLR1COL+$00 ;THE EXACT CLC ;POSITIONS OF ADC #$0C ;PLAYER 1, SO STA PLR1COL+$01 ;THAT WHEN THE LDA PLR1_Y ;OPPONENTS' SEC ;BULLET HITS SBC #$0C ;THE PLAYER, STA PLR1COL+$02 ;IT HAS TO BE CLC ;IN THE EXACT ADC #$18 ;POSITION OF STA PLR1COL+$03 ;PLAYER 1. LDA PLR2_X ;THE SAME SEC ;CALCULATIONS SBC #$06 ;FOR PLAYER 2 STA PLR2COL+$00 ;BULLET TO CLC ;PLAYER ADC #$0C ;COLLISION. STA PLR2COL+$01 LDA PLR2_Y SEC SBC #$0C STA PLR2COL+$02 CLC ADC #$18 STA PLR2COL+$03 RTS ;CHECK PLAYER 1 BULLET COLLISION ON ;PLAYER 2 SHIP P2COL LDA PLR1B_X ;IS THE BULLET CMP PLR2COL+$00 ;AT THE CORRECT BCC MISSP2 ;POSITION WHERE CMP PLR2COL+$01 ;THE PLAYER IS? BCS MISSP2 ; LDA PLR1B_Y ;IF NOT THEN CMP PLR2COL+$02 ;THE BULLET BCC MISSP2 ;MISSES THE CMP PLR2COL+$03 ;PLAYER. BCS MISSP2 ; LDA #$F6 ;ELSE MOVE STA PLR1B_Y ;BULLET OFF LDA #$00 ;SCREEN, TURN STA PLR1LOCKUP ;OFF FIRE LOCK INC $0400 ;ADD 1 POINT LDA $0400 ;CHECK SCORE CMP #$3A ;IS IT OVER 9? BNE MISSP2 ;IF NOT THEN ;MISS, ELSE JMP VICTORY1 ;JUMP TO WIN MISSP2 RTS ;CHECK PLAYER2 BULLET ON PLAYER 1 SHIP P1COL LDA PLR2B_X ;DOES THE CMP PLR1COL+$00 ;BULLET HIT BCC MISSP1 ;THE PLAYER IN CMP PLR1COL+$01 ;EXACT POSITION BCS MISSP1 ;OF THE PLAYER LDA PLR2B_Y ;SHIP? ÉF SO CMP PLR1COL+$02 ;THEN CONTINUE BCC MISSP1 ;ELSE JUMP TO CMP PLR1COL+$03 ;MISSP1 BCS MISSP1 LDA #$06 STA PLR2B_Y LDA #$00 STA PLR2LOCKUP INC $0427 ;ÁDD 1 POINT LDA $0427 ;CHECK SCORE CMP #$3A ;IS IT OVER '9' BNE MISSP1 ;IF SO THEN JMP VICTORY2 ;PLAYER2 WINS MISSP1 RTS VICTORY1 SEI ;STOP ALL IRQS LDA #$00 ;TURN OFF ALL STA $D015 ;THE SPRITES LDX #$00 ;CALL A ROUTINE WIN1 LDA VIC1,X ;TO DISPLAY STA $0400,X ;PLAYER1 WINS LDA #$01 ;MESSAGE AND STA $D800,X ;PAINT THE INX ;MESSAGE WHITE CPX #$28 ;AND DISPLAY BNE WIN1 ;AS 40 CHARS JMP SPACE ;JUMP TO SPACE ;PROMPT VICTORY2 SEI ; LOOK AT LDA #$00 ; 'VICTORY1' STA $D015 ;SAME FUNCTION LDX #$00 ;THIS ROUTINE WIN2 LDA VIC2,X ;DOES EXACTLY STA $0400,X ;THE SAME, BUT LDA #$01 ;IT READS THE STA $D800,X ;TEXT FROM INX ;VIC2 SO THAT CPX #$28 ;PLAYER 2 WINS BNE WIN2 ;THE GAME JMP SPACE ;YOU KNOW THIS ;IF NOT THEN ;LOOK AT THE ;PREVIOUS ;'JMP SPACE' ;PROMPT SPACE LDA #$1B STA $D011 LDA #$03 STA $DD00 LDA #$08 STA $D016 LDA #$16 STA $D018 LDX #$00 ;ANOTHER TEXT SETSPC LDA SPC,X ;DISPLAY STA $07C0,X ;ROUTINE. THIS LDA #$03 ;TIME POSITION STA $DBC0,X ;THE TEXT AT INX ;THE BOTTOM OF CPX #$28 ;THE SCREEN AS BNE SETSPC ;40 CHARS HITSPACE LDA #$80 ;CREATE A RASTER CMP $D012 ;RASTER CONTROL BNE RASTER ;TO CONTINUE JSR $1003 ;PLAYING MUSIC LDA $DC01 ;READ SPACE BAR CMP #$EF ;IF NOT PRESSED BNE RASTER ;THEN JUMP TO ;THE RASTER TO ;CONTINUE ;THE ÓÐÁÃÅ READ ;ROUTINE AND ;PLAY MUSIC JMP START ;RESTART GAME ;YOUR TEXT DISPLAY DATA TABLES. ;ACME CROSS ASS USERS, PLEASE CHANGE .TEXT TO !TEXT ;DASM USERS, PLEASE CHANGE .TEXT TO DC.B ;TASS USERS, .TEXT IS ALRIGHT! ;PLAYER 1 VICTORY VIC1 .TEXT "PLAYER 1 PROVES THAT" .TEXT " PLAYER 2 IS A LOSER" ;ÐLAYER 2 VICTORY VIC2 .TEXT "PLAYER 2 PROVES THAT" .TEXT " PLAYER 1 IS A LOSER" ;ÓPACEBAR PROMPT MESSAGE SPC .TEXT " PRESS THE SPACEBAR" .TEXT " FOR ANOTHER GAME! " SPLITS LDA #$00 SPLIT1 CMP $D012 BNE SPLIT1 LDA #$14 STA $D018 LDA #$1B STA $D011 LDA #$03 STA $DD00 LDA #$08 STA $D016 LDA #$00 STA $D015 LDA #$3A SPLIT2 CMP $D012 BNE SPLIT2 NOP ;IRON OUT FLICKERING RASTER NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP LDA #$78 STA $D018 LDA #$3B STA $D011 LDA #$02 STA $DD00 LDA #$18 STA $D016 LDA #$FF STA $D015 RTS ;NOTE. IF YOU ARE USING A CROSS ASSEMBLER, YOU WILL NEED TO EXTRACT THE PROGRAM DATA FROM THE .D64 ;UNDERNEATH THE EXAMPLE GAME AND ADD BINARY COMMANDS. ;ONLY USE THIS IF YOU KNOW WHAT BINARY/PRG FILES TO ADD. ;ACME USERS, PLEASE USE !BINARY OR !BIN PROMPT INSTEAD OF INCBIN SPRITE DATA * = $4000-2 BINARY "SPRITES.PRG" VIDCOM PICTURE * = $5800-2 BINARY "B.PICTURE.PRG" ;END