revolution-x/GXSCORE.ASM

2077 lines
50 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

.MLIB "GXMACS.LIB"
.FILE "GXSCORE.ASM"
.TITLE " <<< GENERATION X -- SCORING ROUTINES >>>"
.WIDTH 132
.OPTION B,D,L,T
.MNOLIST
**************************************************************************
* *
* COPYRIGHT (C) 1992 MIDWAY MANUFACTURING COMPANY. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
* GET THE SYSTEM STUFF
.INCLUDE "GX.INC"
.INCLUDE "GXSTRING.H"
.INCLUDE "IMGTBL.GLO"
.INCLUDE "GXSCORE.TBL"
.DEF UPDSL, OUTLIVES, OUTSCR, SUBLIFE
.DEF SCORE_GAME_OVER
.DEF SCORPROC, LEVEL_UPDATE
.DEF SCORE_IF_ACTIVE
.DEF G_CRED, G_CREDONLY
.DEF MARQUEE
.DEF AWARD_EXTRAS
.DEF FLASH_PSTATUS, PLAYER_SHIELD
*SYMBOLS IN GX.ASM
.REF ALLOW_CONTINUE
*SYMBOLS IN GXPOWER.ASM
.REF DO_HEADS_UP
*SYMBOLS IN GXRAM.ASM
.REF BTIME
*SYMBOLS IN GXPALL.ASM
.REF PALSET
*SYMBOLS IN GXCOIN.ASM
.REF CR_BOTH
***** from GXD.ASM
.REF OBJ_CONST_MULTI
***** from GXWARREN.ASM
.REF C_OCONST
.BSS CANSTRT,16
.bss filler,16 ; to keep long word aligned
**** .BSS HISEEN,16 ; HOW MANY "HI"S IN A ROW
STATUS_FLASH_COLOR .EQU 2929H ;CONSTANT COLOR FOR HIT FLASH
.EVEN
.TEXT
**************************************************************************
* *
* SCORPROC - SIMPLE SCORE PROCESS FOR FLASHING PRESS START *
* *
* ENTRY : *
* A11 POINTER TO PLAYER DATA AREA *
* *
* RETURNS : *
* NEVER EXITS *
* *
* NOTE : *
* A8 MESSAGE PART FLAG *
* A9 CURRENTLY ACTIVE PALETTE *
* *
**************************************************************************
SCORPROC:
CLR A8 ; MESSAGE PART 0
SCORPLP2
CALLA CR_BOTH
MOVE A2,@CANSTRT,W ; START/CONTINUE FLAG
MOVE @NPLAYERS,A11,W ; NUMBER OF PLAYERS
MOVI P1DATA,A2 ; ALWAYS ASSUME AT LEAST 1 PLAYER
SP_LP
CALLR SCORMESS
ADDI PDSIZE,A2
DEC A11
JRNN SP_LP
SLEEP 40
NOT A8 ; FLIP MESSAGE
JRUC SCORPLP2 ; PLOT IT AGAIN, SAM
**************************************************************************
* *
* SCORMESS FIGURE OUT WHAT MESSAGE TO PUT IN THE SCORE BOX *
* *
* ENTRY *
* A2 : POINTER TO CURRENT PLAYER BANK *
* A8 : 0 IF FIRST PART OF MESSAGE, ~0 IF SECOND PART *
* A9 : COLOR TO USE IN PALETTE *
* *
* RETURN *
* NOTHING *
* *
**************************************************************************
SCORMESS:
MMTM SP,A2,A8,A9,A10,A11
SCORMRETRY:
MOVK 1,A11 ; ASSUME IN STORY MODE
MOVE @GAME_STATE,A0,W
CMPI INAMODE,A0
JREQ SCORMAMODE
CLR A11 ; NOT IN ATTRACT MODE
MOVE *A2(PDEAD),A0,W ; CHECK FOR DEAD MESSAGE
JRNZ SCORM3
MOVE *A2(POBJ),A0,L ; CHECK TO SEE IF HAS OBJECT
JRNZ SCORMRET
MOVE *A2(PENTER),A0,W ; CHECK FOR ENTERING
JRNZ SCORMRET
SCORMAMODE
MOVE A8,A8 ; CHECK SEQUENCER
JRNZ SCORM1 ; WORKING ON SECOND MESSAGE
MOVE A11,A11 ;ARE WE IN ATTRACT MODE?
JRNZ SCD_START_CREDITS ;BR = ALWAYS CHECK FOR STARTING CREDS
MOVE *A2(PSCORE),A3,L ;PLAYERS FIRST TIME PLAYING?
JRNZ SCO1 ;BR = NO
SCD_START_CREDITS
MOVE @CANSTRT,A0,W ;DOES HE HAVE ENOUGH TO START?
ANDI 1,A0
JRZ SCOPOOR ;BR = NO, TELL HIM HE NEEDS MORE
*THIS IS WHERE WE TO PLAYER SPECIFIC MESSAGES OF APPROPRIATE
SCDNAME
MOVI T1PRESS,A8
JRUC SCORMGO
SCO1
CALLA ALLOW_CONTINUE
JRZ SCORM_GAME_OVER
MOVE @CANSTRT,A0,W
ANDI 2,A0
JRNZ SCDNAME ; BR = YES, ENOUGH CONTINUE CREDITS
SCOPOOR
MOVI T1INSERT,A8 ; INSERT COIN
JRUC SCORMGO
SCORM1
MOVI T1TOPLAY,A8 ; "TO PLAY"
JRUC SCORMGO
SCORM_GAME_OVER
MOVK 2,A0
MOVE A0,*A2(PDEAD),W
SCORM3 ; A0 CONTAINS PDEAD HERE
CMPI 1,A0,W ; CHECK FOR BLANK
JRZ SCORMRET ; NOTHING TO PLOT
CMPI 2,A0,W ; GAME OVER PLOTTED
JRZ SCORM4
CLR A0
MOVE A0,*A2(PDEAD),W ; CLEAR PDEAD CONDITION
MOVK 1,A10 ; FORCE AN ERASE
JRUC SCORMRETRY
SCORM4
JRUC SCORMRET
; JRUC SCORMPAL ; BYPASS FLASHING COLOR
;
; PLOT THE MESSAGE IN A8 AT THE RIGHT LOCATION
;
SCORMGO
MOVI 0E0EH,A1
SLL 16,A1 ; THIS IS THE CONSTANT DRAW COLOR
MOVE *A2(PPALID),A0,L ; LOOKUP THE CURRENT PALETTE
CALLA FINDPAL ; MAKE SURE IT HAS A PALETTE
MOVX A0,A1
SCORMGOOBJ
MOVE *A2(PSCRAD),A3,L
ADDI SCRCTR,A3 ; START OF TEXT
MOVE *A8(IANIOFFX),A14,L
SUB A14,A3 ; ADJUST THE ANIMATION POINT
MOVE A8,A14
MOVI DMAWAL,A5 ; FLAGS
CALLR SETUP_DMAN
CALLA QDMAN2 ; OUTPUT THE SUCKER
SCORMRET
MMFM SP,A2,A8,A9,A10,A11
RETS
PDTAB .LONG P1DATA,P2DATA,P3DATA,0
CENSORED_TIME .EQU 120
**************************************************************************
* *
* SCORE_GAME_OVER - PROCESS TO PLACE "GAME OVER" MESSAGE IN THE *
* PLAYERS SCORE BOX. *
* A11 = PTR TO PLAYER DATA *
* *
**************************************************************************
SCORE_GAME_OVER
MOVE *A11(PDEAD),A0,W ;IS THE PLAYER DEAD?
JRZ SGO_DIE ;BR = NOT ANYMORE
MOVE @CURPLYRS,A0,W
JRZ SGO_NO_HEADS
MOVE A11,A2
MOVI CENSORED_TAB_3P,A0
MOVI CENSORED_TAB_2P,A1
CALLA DO_HEADS_UP
SGO_NO_HEADS
SLEEP CENSORED_TIME
CALLA ALLOW_CONTINUE
JRZ SGO_DIE
CALLA ALLOW_CONTINUE
JRZ SGO_DIE
MOVE *A11(PDEAD),A0,W ;IS THE PLAYER DEAD?
JRZ SGO_DIE ;BR = NOT ANYMORE
MOVK 3,A0 ; PAUSE DONE, LET SCORPROC SYNC UP
MOVE A0,*A11(PDEAD),W
SGO_DIE:
DIE
*
*"CENSORED" HEADS_UP DISPLAY for a 3-player model
*
CENSORED_TAB_3P
.WORD 0F5H, CENSORED_TIME
.LONG RED_CENSORED_INIT, YEL_CENSORED_INIT, BLUE3_CENSORED_INIT
*
*"CENSORED" HEADS_UP DISPLAY for a 2-player model
*
CENSORED_TAB_2P
.WORD 0F5H, CENSORED_TIME
.LONG RED_CENSORED_INIT, BLUE2_CENSORED_INIT
RED_CENSORED_INIT
.byte 1, 0, 0, 1 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long P_CENSORR ;IMGPAL
.WORD OID_P1HUP,0
LWWWW CENSORR, DMAWNZ, M_NOSCALE|M_SCRNOBJ, 0 , 0
YEL_CENSORED_INIT
.byte 1, 0, 0, 1 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long P_CENSORY ;IMGPAL
.WORD OID_P2HUP,0
LWWWW CENSORY, DMAWNZ, M_NOSCALE|M_SCRNOBJ, 0 , 0
BLUE3_CENSORED_INIT
.byte 1, 0, 0, 1 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long P_CENSORB ;IMGPAL
.WORD OID_P3HUP,0
LWWWW CENSORB, DMAWNZ, M_NOSCALE|M_SCRNOBJ, 0 , 0
BLUE2_CENSORED_INIT
.byte 1, 0, 0, 1 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long P_CENSORB ;IMGPAL
.WORD OID_P2HUP,0
LWWWW CENSORB, DMAWNZ, M_NOSCALE|M_SCRNOBJ, 0 , 0
**************************************************************************
* *
* SCORAREA - OUTPUT THE SCORE AREA AND UPDATE ALL PLAYER STATUS *
* *
**************************************************************************
SCORAREA
CALLR UPSTAT ;UPDATE PLAYERS STATUS
; CALLR MARQUEE
RETS
**************************************************************************
* *
* MARQUEE - OUTPUT THE MARQUEE, THIS INCLUDES THE CREDIT/ISLAND MESSAGE *
* *
**************************************************************************
MARQUEE:
RETS
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A14
MOVI MARQTAB,A0
CLR A6
JRUC SSOUT1
**************************************************************************
* *
* G_CRED - OUTPUT "CREDITS: xx" DURING GAMEPLAY *
* A8 = PTR CREDITS STRING, READY FOR STRINGER *
* *
**************************************************************************
*ENTRY TO JUST REFRESH THE CREDIT'S NOT THE BUY-IN TIMER
G_CREDONLY
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11
JRUC G_CREDG
*ENTRY CALLED EVERY TIME A COIN IS PUT IN
G_CRED:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11
MOVI PID_BUYIN,A0
CALLA EXISTP_ALL
JRZ G_CREDG ;THERE IS NO BUY IN AT THIS TIME
MOVIM BUYTIME,@BTIME,W ;RESET THE BUY-IN TIME
MOVE A0,A4
MOVI OID_BTIME,A0
CALLA EXISTOBJ_ALL
JRZ G_CREDG ;THERE'S NO PHYSICAL TIMER AS OF YET
MOVE A4,A0
MOVI BUYTICK,A11
CALLA PUTA11 ;RESET THE TICK TIMER
*ENTRYPOINT JUST TO UPDATE THE CREDITS MESSAGE
G_CREDG
MOVE @GAME_STATE,A0,W
CMPI INDIAG,A0
JREQ G_CRED_X
CMPI INAMODE,A0
JREQ G_CRED_X
CMPI ININTRO,A0
JREQ G_CRED_X
CMPI INEPILOG,A0
JREQ G_CRED_X
MOVE A8,A14
CREDIT_LP
MOVB *A14,A4
JRZ G_CRED_X ;BR = ERROR IN CREDIT STRING
CMPI 20H,A4
JREQ CREDIT_FOUND
ADDK 8,A14
JRUC CREDIT_LP
CREDIT_FOUND
ADDK 8,A14 ;RID 'O SPACE
MOVB *A14,A4 ;ARE THE CREDITS NON-EXISTANT?
JRZ G_CRED_X ;BR = YES
CMPI 20H,A4
JREQ CREDIT_FOUND
MOVI CRDBOX,A3 ;ERASE CURRENT CREDIT MESSAGE
MOVI CRDSIZE,A4
CLR A1
CALLA FILLAREA2
MOVI RD5FONT,A11 ;SET DA SHIT UP
MOVK 1,A10
MOVI CRDBOX+CRDTXT,A9
MOVI 0F0F0101H,A5
CLR A0
CLR B1
JSRP STRCNRM2 ;LET IT RIP
G_CRED_X:
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11
RETS
.IF GERMAN
CREDIT_MESS:
MESS_MAC RD5FONT,1,0,0,01010000H,STRCNRM2,0
.STRING "KRED",0
.EVEN
FREE_MESS:
MESS_MAC RD5FONT,1,0,0,0F0F0101H,STRCNRM2,0
.STRING "FREI",0
.EVEN
.ELSE
CREDIT_MESS:
MESS_MAC RD5FONT,1,0,0,01010000H,STRCNRM2,0
.STRING "CRED",0
.EVEN
FREE_MESS:
MESS_MAC RD5FONT,1,0,0,0F0F0101H,STRCNRM2,0
.STRING "FREE",0
.EVEN
.ENDIF
**************************************************************************
* *
* SSOUT *
* *
* Output some Score/Status area pieces via a table. *
* First entry, is area to blank before plotting. *
* *
* A0 = Ptr to table *
* A2 = Player this belongs to. (0 = No player) *
* A6 = Offset to add to each piece (DAG for BLNKAREA). *
* *
* Returns: *
* A0 = Pointing to next word after table *
* *
**************************************************************************
SSOUT:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
SSOUT1:
MOVE *A0+,A4,L
JRZ SSOUT_BLANK_SKIP
MOVE A6,A3
MOVI ERASECOL*10000H,A1
CALLA FILLAREA2
SSOUT_BLANK_SKIP:
CLR A1 ;CONSTANT:PALETTE
MOVI DMAWNZ,A5 ;DRAW
SLL 16,A5
MOVE A2,A2
JRZ SSO_NOPLAYER ;BR = No player association
MOVE A0,A7
MOVE *A2(PPALID),A0,L
CALLA FINDPAL
MOVX A0,A1 ;Correct [Constant,Palette]
MOVI [0100H,0100H],A0 ;SCALE IS 1:1
MOVE *A7+,A8,L
SSO_P_LOOP
MOVE *A8(ISIZE),A2,L ;GRAB THE UNSCALED SIZE
MOVE *A8(ICTRL),A14,W ;GET BPP AND COMPRESSION
SLL 16,A14
OR A14,A5
MOVE *A8(ISAG),A4,L
CALLA QDMAN2 ;Q THIS SUCKAH!
MOVE *A7+,A8,L
JRNZ SSO_P_LOOP
JRUC SSO_X
SSO_NOPLAYER
MOVE *A0+,A7,L ;KICK IT OFF COUSIN
SSOUTL:
MOVE *A0+,A3,L
ADDXY A6,A3
CALLA DTIME2 ;DO IT
MOVE *A0+,A7,L ;GET THE NEXT
JRNZ SSOUTL ;BR = DO IT AGAIN
SSO_X
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
RETS
MARQTAB
.LONG 0
.LONG 0
P1SCOREAREA:
.LONG PBOXSIZ
.LONG BOX1d
.LONG [0,0]
.LONG 0
P2SCOREAREA:
.LONG PBOXSIZ
.LONG BOX2d
.LONG [0,0]
.LONG 0
P3SCOREAREA:
.LONG PBOXSIZ
.LONG BOX3d
.LONG [0,0]
.LONG 0
*
*UPDATE ALL PLAYER STATUS AREAS
UPSTAT
MMTM SP,A2,A7
ALLPLYR UPDSL ;USES A7
MMFM SP,A2,A7
RETS
*
*UPDATE THE PLAYERS SCORE,LIVES & WHATEVER ELSE.
*A2 = PLAYER DATA STRUCTURE
UPDSL
MMTM SP,A0,A1
CALLA PSENCL ;FIRST RE-INIT THE AREA
MOVE *A2(PSCORE),A0,L ;GET THE SCORE IN A0
CALLR OUTSCR ;AND OUTPUT IT
CALLR OUT_BOMBS
MOVE *A2(POBJ),A0,L
JRZ UPDSL_X
*DO THE FOLLOWING ONLY WHEN THE PLAYER IS ALIVE
; CALLR OUTGUN
; CALLR OUTENERGYWORD
CALLR OUTLIVES
; CALLR OUTGUNWORD
UPDSL_X:
MMFM SP,A0,A1
RETS
**************************************************************************
* *
* PSENCL - CREATE THE PLAYER SCORE ENCLOSURE *
* A2 = PLAYER DATA *
* *
**************************************************************************
PSENCL:
MMTM SP,A0,A6
MOVE *A2(PSCRAD),A6,L
CMPI P1DATA,A2
JRNE PSENCL_CKP2
MOVI P1SCOREAREA,A0
JRUC PSENCL_BUILD
PSENCL_CKP2:
CMPI P2DATA,A2
JRNE PSENCL_CKP3
MOVI P2SCOREAREA,A0
JRUC PSENCL_BUILD
PSENCL_CKP3:
CMPI P3DATA,A2
JRNE PSENCL_X
MOVI P3SCOREAREA,A0
PSENCL_BUILD:
CALLR SSOUT
PSENCL_X:
MMFM SP,A0,A6
RETS
**************************************************************************
* *
* BCDADD - ADD TWO BCD VALUES *
* A0 = 8 DIGIT BCD VALUE *
* A1 = 8 DIGIT BCD VALUE *
* RETURNS *
* A0 = 8 DIGIT BCD RESULT *
* NOTE: PACKED BCD FORMAT 4-BITS/ DIGIT *
* *
**************************************************************************
BCDADD:
MMTM SP,A1,A3,A4,A5,A6
MOVK 8,A5 ;DO 8 DIGITS
CLRC ;CLEAR THE CARRY
MOVK 0Ah,A6
BCDLP:
MOVK 0Fh,A3
MOVK 0Fh,A4
AND A1,A3 ;MASK GARBAGE
AND A0,A4
ADDC A3,A4
CMP A6,A4 ;NEED TO ADJUST?
JRLO BCDAD1
ADDK 6,A4
SRL 4,A0
SLL 28,A4
ADD A4,A0
SRL 4,A1
SETC
DSJS A5,BCDLP
JRUC BCDADX
BCDAD1:
SRL 4,A0
SLL 28,A4
ADD A4,A0
SRL 4,A1
CLRC
DSJS A5,BCDLP
BCDADX:
MMFM SP,A1,A3,A4,A5,A6
RETS
**************************************************************************
* *
* SCORE - PLAYER SCORE ROUTINE *
* A1 = SCORE VALUE *
* A2 = PTR TO PLAYER DATA AREA (0 = NO PLAYER, NO SCORE) *
* *
**************************************************************************
SCORE:
PUSH A0
MOVE @GAME_STATE,A0,W
CMPI INAMODE,A0
JREQ SCOREX ;NO SCORING IN ATTRACT MODE
CMPI INGAMEOV,A0
JREQ SCOREX ;NO SCORING IN GAME OVER
MOVE A2,A2 ;IS THIS A FALSE ALARM?
JRZ SCOREX ;BR = YES
MOVE *A2(POBJ),A0,L
JRZ SCOREX ;NO PLAYER, NO SCORE
MOVE *A2(PSCORE),A0,L ;GET SCORE
ADD A1,A0 ;LET'S GO NORMAL
CALLR REPCK ;CHECK REPLAY
MOVE A0,*A2(PSCORE),L ;STORE SCORE
CALLR OUTSCR ;OUTPUT CURRENT PLAYER SCORE
SCOREX
PULLQ A0
RETS
**************************************************************************
* *
* SCORE_IF_ACTIVE - GIVE THE PLAYER THIS SCORE IFF HE IS ACTIVE. *
* A1 = BCD SCORE VALUE *
* A2 = PTR TO PLAYER DATA *
* *
**************************************************************************
SCORE_IF_ACTIVE:
PUSH A0
MOVE *A2(POBJ),A0,L
JRZ SCORE_IA_X
CALLR SCORE
SCORE_IA_X:
PULL A0
RETS
**************************************************************************
* *
* REPCK - CHECK TO SEE IF A PLAYER HAS SCORED A REPLAY AND IF SO *
* AWARD A NEW DUDE. *
* A0 = CURRENT PLAYER SCORE *
* A2 = PLAYER DATA AREA *
* RETURNS: *
* NOTHING *
* NOTE: DESTROYS A14 *
* *
**************************************************************************
REPCK
RETS
**** MMTM SP,A0,A1,A3,A4
**** MOVE *A2(PEXTRAS),A1,W
**** JRZ REPCKX ;BR = LAST ONE EXTINGUISHED
**** MOVE *A2(PNEXTREP),A1,L
**** JRZ REPCKX ;0 = NO EXTRA DUDES
**** CLR A3 ;KEEP COUNT OF HOW MANY LIVES WE OWE
**** MOVE A0,A4 ;KEEP THE SCORE HERE BECAUSE OF BCDADD
****REPCKLP:
**** CMP A1,A4 ;HAVE WE EXCEEDED THIS LEVEL?
**** JRLO REPCK_CASH_OUT ;BR = NO, CASH OUT
**** ADJUST ADJEXTRA ;GET EXTRA MAN EVERY ADJUSTMENT
**** ADD A0,A1
**** DECM *A2(PEXTRAS),W
**** JRNZ REPCK1
**** CLR A1 ;NO MORE REPLAYS JOE
****REPCK1
**** MOVE A1,*A2(PNEXTREP),L ;NEW REPLAY LEVEL
**** SOUND1 FREE_SND
**** MOVE A4,A0 ;RESTORE THE SCORE
**** INC A3 ;INCREMENT THE LIFE COUNT
**** MOVE A1,A1
**** JRNZ REPCKLP ;CHECK FOR MORE
****REPCK_CASH_OUT:
**** MOVE A3,A0
**** JRZ REPCKX ;WE OWE HIM NOTHING
**** CALLR ADDNLIFE ;PAY THE MAN
**** MOVE A0,A1
**** MOVI AUDDEARNED,A0
**** CALLA AUD ;COUNT IT OUT
****REPCKX:
**** MMFM SP,A0,A1,A3,A4
**** RETS
****FREE_SND
**** .WORD 0F3E0H,03CH,08012H,0 ;"WHOOP TE DOOO"
**************************************************************************
* *
* OUTSCRHI - OUTPUT SCORE TO SCREEN, ALWAYS BRIGHT *
* A0 = PLAYER SCORE *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
OUTSCRHI:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
MOVI 0D0D0000H,A1 ;BRIGHTEN THE SCENE
JRUC OUTSCRG
**************************************************************************
* *
* OUTSCRLO - OUTPUT SCORE TO SCREEN, ALWAYS DIM *
* A0 = PLAYER SCORE *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
OUTSCRLO:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8
MOVI 05050000H,A1 ;DIMMER COLOR
JRUC OUTSCRG
**************************************************************************
* *
* OUTSCR - OUTPUT SCORE TO SCREEN, BRIGHT OR DIM DEPENDING ON PLAYER *
* A0 = PLAYER SCORE *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
OUTSCR:
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9
MOVE @GAME_STATE,A14,W
CMPI INAMODE,A14
JREQ OUTSCRD
MOVE *A2(PENTER),A14,W
JRNZ OUTSCRH ;BR = PLAYER WILL ENTER SOON
MOVE *A2(POBJ),A14,L
JRZ OUTSCRD
OUTSCRH:
MOVI 0D0D0000H,A1 ;BRIGHTEN THE SCENE
JRUC OUTSCRG
OUTSCRD:
MOVI 05050000H,A1 ;DIMMER COLOR FOR NON-ACTIVE PLAYER
*
*OUTSCR - ENTRY POINT WITH FIXED CONSTANT COLOR IN A1
OUTSCRG:
MOVK 8,A3 ;DIGIT COUNT
CALLR SCORE_TO_DEC ;CONVERT THE NUMBER
MOVE A3,A6
MOVE *A2(PSCRAD),A3,L ;PLAYER SCORE AREA ADDRESS
ADDI PSCOREOF,A3
MOVI SCRSPC,A8 ;SPACING BETWEEN DIGITS
CLR A7 ;INIT BLANKING FLAG
MOVE A0,A5 ;STORE THE SCORE HERE
MOVE *A2(PPALID),A4,L
MOVE A4,A0
CALLA FINDPAL ;MAKE SURE IT HAS A PALETTE
JRNZ OUTSC01 ;BR = THERE EXISTS A PALETTE
MOVE A4,A0
CALLA GETFPAL ;MAKE A PALETTE EXIST
OUTSC01
MOVX A0,A1
MOVE A5,A9
MOVI DMAWNZ,A5 ;CONTROL REGISTER
*NOTE:A2 GETS DESTROYED UPON THE FIRST ITERATION OF THIS LOOP
OUTSCL:
MOVB *A9,A14 ;GET THE FIRST DIGIT
JRNE OUTSC1 ;NON-ZERO DIGIT
CMPI 2,A6
JRLS OUTSC1 ;LAST DIGITS - OUTPUT ANYWAY
MOVE A7,A7 ;BLANKING OVER?
JREQ OUTSC2 ;NO
OUTSC1:
INC A7 ;BLANKING IS OVER
SLL 7,A14 ;MULTIPLY BY 128
ADDI SNUM0,A14
CALLR SETUP_DMAN
CALLA QDMAN2 ;OUTPUT THE SUCKER
SRL 16,A5
OUTSC2:
ADDXY A8,A3 ;SPACE TO NEXT DIGIT
ADDK 8,A9 ;NEXT IN THE BUFFER
DSJ A6,OUTSCL
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9
RETS
**************************************************************************
* *
* OUT_BOMBS - OUTPUT THE NUMBER OF BOMBS CURRENTLY HELD BY *
* THIS PLAYER. *
* A2 = PLAYER DATA AREA *
* *
**************************************************************************
OUT_BOMBS
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A8,A9
MOVE *A2(PBOMB2),A0,W ;DOES HE HAVE A SPECIAL BOMB?
JRNZ OB_BOMB2 ;BR = YES
MOVE *A2(PBOMB1),A0,W ;DEFAULT NORMAL COUNT
OB_BOMB2
CMPI 999,A0 ;MAX DISPLAYABLE?
JRLS OB_SIZEOK ;BR = NO
MOVI 999,A0 ;DEFAULT ON MAX
OB_SIZEOK
MOVK 3,A3 ;DIGIT COUNT
CALLR SCORE_TO_DEC ;CONVERT THE NUMBER
MOVE A3,A6
MOVE A0,A3 ;STORE THE SCORE HERE
MOVE *A2(PPALID),A4,L
MOVE A4,A0
CALLA FINDPAL ;MAKE SURE IT HAS A PALETTE
JRNZ OB_01 ;BR = THERE EXISTS A PALETTE
MOVE A4,A0
CALLA GETFPAL ;MAKE A PALETTE EXIST
OB_01
MOVX A0,A1
MOVE A3,A9
MOVE *A2(PSCRAD),A3,L ;PLAYER SCORE AREA ADDRESS
ADDI PBOMBOF,A3
MOVI SCRSPC,A8 ;SPACING BETWEEN DIGITS
MOVI DMAWNZ,A5 ;CONTROL REGISTER
*NOTE:A2 GETS DESTROYED UPON THE FIRST ITERATION OF THIS LOOP
OB_LP
MOVB *A9,A14 ;GET THE FIRST DIGIT
SLL 7,A14 ;MULTIPLY BY 128
ADDI CNUM0,A14
CALLR SETUP_DMAN
CALLA QDMAN2 ;OUTPUT THE SUCKER
SRL 16,A5
ADDXY A8,A3 ;SPACE TO NEXT DIGIT
ADDK 8,A9 ;NEXT IN THE BUFFER
DSJ A6,OB_LP
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A8,A9
RETS
**************************************************************************
* *
* SETUP_DMAN - ROUTINE TO CORRECT OFFSET DUE TO MIRRORING FOR MANUAL *
* DMA'S (I.E. THOSE USING DMAN) *
* A14 = PTR TO IMAGE *
* A3 = UNFLIPPED DESTINATION *
* A5 = FLAGS FOR THIS DMA *
* RETURNS *
* A0 = SCALE [0100H,0100H] *
* A2 = OSIZE *
* A3 = [Y,X] DAG *
* A4 = SAG *
* A5 = [CONTROL,OFFSET] *
* *
**************************************************************************
SETUP_DMAN
MOVI [0100H,0100H],A0
MOVE *A14(ISIZE),A2,L ;GRAB THE UNSCALED SIZE
MOVE *A14(ICTRL),A4,W ;GET BPP AND COMPRESSION
OR A4,A5
SLL 16,A5
MOVE *A14(ISAG),A4,L
RETS
**************************************************************************
* *
* SCORE_TO_DEC - FORMAT A HEXADECIMAL # TO A DECIMAL STRING, LEAD ZERO *
* FILL IS USED. *
* A0 = HEXADECIMAL # *
* A3 = width, MINIMUM # OF CHARACTERS TO OUTPUT *
* RETURNS: *
* A0 = PTR TO STRING *
* *
**************************************************************************
SCORE_TO_DEC
MMTM SP,A1,A3,A4,A9
MOVE A3,A4
DEC A4
SLL 3,A4
ADDI STRNGRAM,A4 ;THIS IS OUR STORAGE BUFFER
MOVK 10,A9 ;DIVISOR FOR DECIMAL
MOVE A0,A1
SCTODEC2
CLR A0
DIVU A9,A0
MOVB A1,*A4 ;SAVE HERE
SUBK 8,A4
DEC A3 ;DECREMENT THE WIDTH
MOVE A0,A1
JRNZ SCTODEC2 ;BR = NOT DONE YET
MOVE A3,A3
JRZ SCTODEC3A ;WIDTH HAS BEEN FULFILLED
JRN SCTODEC3A ;THANX TI
CLR A1
SCTODEC31:
MOVB A1,*A4 ;STUFF THE LEADER
SUBK 8,A4
DSJS A3,SCTODEC31
SCTODEC3A:
MOVI STRNGRAM,A0 ;PASS THE NEW STRING BACK
MMFM SP,A1,A3,A4,A9
RETS
**************************************************************************
* *
* PLAYER LIFE ROUTINES *
* *
**************************************************************************
**************************************************************************
* *
* AWARD_EXTRAS - AWARD ONE EXTRA MAN TO ALL ACTIVE PLAYERS. *
* NOTE: CALL WITH JSRP *
* *
**************************************************************************
AWARD_EXTRAS
ALLPLYR AWEB
RETP
**************************************************************************
* *
* AWEB - AWARD ONE EXTRA MAN TO PLAYER IF ACTIVE AT THE *
* TIME OF CALLING. *
* A2 = PTR TO PLAYER DATA *
* *
**************************************************************************
AWEB
PUSH A0
MOVE *A2(POBJ),A0,L
JRZ AWEB_X
CALLR ADDLIFE
AWEB_X
PULL A0
RETS
**************************************************************************
* *
* ADD LIFE *
* A0 = # OF LIVES TO ADD *
* A2 = PLINDX=PLAYER DATA AREA *
* *
**************************************************************************
*
*ADD ONE LIFE
ADDLIFE:
MOVI [1,0],A0
*
*ADD N LIFE(VES)
ADDNLIFE
MOVE *A2(POBJ),A14,L ;IS THIS GUY ALIVE?
JRZ AL_XXX ;BR = NO, THEN DON'T ADD LIFE
MMTM SP,A0,A1,A3
MOVE *A2(PLIVES),A1,L ;CURRENT # OF LIVES
ADD A0,A1
MOVE A1,*A2(PLIVES),L
*** CALLR OUTLIVES
MMFM SP,A0,A1,A3
AL_XXX
RETS
**************************************************************************
* *
* SUBLIFE - SUBTRACT LIFE ENERGY FROM THE PLAYER. *
* A0 = ENERGY TO SUBTRACT [INT,FRAC] *
* A2 = PTR PLAYER DATA AREA *
* RETURN(S): *
* C = ENERGY DEPLETED *
* *
**************************************************************************
SUBLIFE:
MMTM SP,A0,A1,A5
.if BILL
; JRUC SL_CLRC
.endif
.IF NO_DEATH
JRUC SL_CLRC
.ENDIF
MOVE @GAME_STATE,A1,W
CMPI INAMODE,A1
JREQ SL_CLRC
MOVE *A2(PINVINCIBLE),A1,W ;IS THIS PLAYER INVINCIBLE?
JRNZ SL_CLRC ;BR = YES, NO SUBTRACTING
MOVE *A2(PSHIELD),A1,L ;Get current shield value
JRZ SUB_NORM ;BR = No shield
SUB A0,A1
JRGT SUB_STORE_SHIELD ;BR = More shield left
CLR A1
CALLR PLAYER_SHIELD_DONE
SUB_STORE_SHIELD
MOVE A1,*A2(PSHIELD),L ;Clear the shield value
JRUC SL_CLRC
SUB_NORM
MOVE *A2(PLIVES),A1,L ;GET REMAINING # OF LIVES
JRLE SUBLF1 ;WE'VE HIT BOTTOM
MOVE @BOSS_PUNISH,A14,W
JRZ SUB_PROTECT ;BR = HAVE MERCY ON THE PLAYER
SUB A0,A1 ;DO A STRAIGHT SUBTRACT OF LIFE
JRUC SUB_OK
SUB_PROTECT
MOVE *A2(PSECLIFE),A5,L
MOVE *A2(PTOTTIME),A14,W
MPYU A14,A5 ;ALLOWED TO LOSE THIS MUCH
SRL 16,A5
MOVE *A2(PINITLIFE),A14,W
SUB A5,A14 ;MIN LEVEL CURRENTLY ALLOWED
*A4 = INTEGER MINIMUM ENERGY
SLL 16,A14
SUB A0,A1
CMP A14,A1 ;DID WE GO LOWER THAN THE MINIMUM?
JRGE SUB_OK ;BR = NO, USE WHAT WE HAVE
MOVE A14,A1
*JUMP HERE WHEN YOU HAVE VALUE TO STUFF BACK
*A1 = LIFE VALUE
SUB_OK
MOVE A1,*A2(PLIVES),L
MOVE A1,A1 ;IS THAT IT?
JRLE SUBLF1 ;BR = YES
SL_CLRC
CLRC
JRUC SUBLFX
SUBLF1:
SETC
SUBLFX:
MMFM SP,A0,A1,A5
RETS
**************************************************************************
* *
* THE FOLLOWING IS THE BASIC LAYOUT OF THE PLAYERS LIFE AND *
* GUN STATUS OVERLAY. EACH PART IS A DIFFERENT OBJECT. ALL *
* OBJECT POINTERS ARE STORED IN PDATA. IF A PTR IS ZERO, THE *
* OBJECT CURRENTLY DOES NOT EXIST. *
* *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* <EFBFBD> <EFBFBD> *
* E E *
* N N *
* E E *
* R R *
* G G *
* Y Y *
* <EFBFBD> GUN:STUN <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GUN: KILL <EFBFBD> *
* *
**************************************************************************
**************************************************************************
* *
* OUTLIVES - OUTPUT PLAYER ENERGY BAR. *
* A2 = PTR TO PLAYER DATA AREA *
* RETURNS: *
* NOTHING *
* NOTE: TRASHES A14 *
* *
**************************************************************************
OUTLIVES:
MMTM SP,A0,A1,A2,A3,A4,A7,A8
MOVE *A2(PLIVES),A1,L ;CURRENT ENERGY LEVEL
JRUC OUTLIVES_G
*
*ENTRYPOINT FOR OUTLIVES, BUT PLOT LEVEL PASSED IN A1
*
OUTLIVES_A1
MMTM SP,A0,A1,A2,A3,A4,A7,A8
OUTLIVES_G
MOVE A1,*A2(PLASTLPLOT),L ;KEEP IT AS OUR LAST PLOT
MOVE @GAME_STATE,A14,W
CMPI INAMODE,A14
JREQ OUTENX ;NO ENERGY OUTPUT DURING ATTRACT MODE
MOVE *A2(POBJ),A14,L
JRZ OUTEN_DEL ;BR = NO LIFE BAR FOR DEAD GUY
MOVE A1,A1
JRZ OUTEN_DEL ;BR = NO ENERGY, DELETE THE OBJECT
CLR A4
MOVE *A2(PEBAROBJ),A8,L ;GET THE ENERGY BAR OBJECT
JRNZ OL_OBJEXISTS ;BR = GOOD, THE OBJECT EXISTS
MOVE A4,*A2(PECOLOR),W ;CLEAR THE CURRENT BAR COLOR VALUE
INC A4
MOVI PLIFEBAR_TAB,A3
CALLR MAKE_PSTATUS_MULTI ;CREATE THE STATUS OBJECT
JRZ OUTENX
CALLA OBJ_OFF
CALLA INSERT_OBJ
MOVE A8,*A2(PEBAROBJ),L
OL_OBJEXISTS
MOVE *A2(PENRGSIZ),A7,L ;GET # OF LIFE UNITS/ENERGY UNIT
DIVU A7,A1 ;A11 = LIVES/(LIVES/UNIT) = UNITS
MOVI NNRGUNIP,A7
CMP A7,A1 ;ARE WE WITHIN MAX SIZE?
JRLE OL_MAXOK ;BR = YES
MOVE A7,A1
JRUC OL_PLOT
OL_MAXOK
CMPI 4,A1 ;ARE WE GREATER THAN THE MIN GUN SIZE
JRGE OL_PLOT ;BR = YES
MOVK 4,A1 ;THIS SHALL BE THE MIN
OL_PLOT
MOVE A1,A3 ;KEEP THE NEW SIZE
SUB A1,A7
ABS A7 ;A7 = LEFT CLIP
SLL 8,A7
MOVE A7,*A8(OFSET),W
MOVE A4,A4 ;WAS THE OBJECT OFF?
JRZ OUTEN_COLORS ;BR = NO
CALLA OBJ_ON
*A3 = CURRENT VERTICAL SIZE OF LIFE BAR
OUTEN_COLORS
SRL 3,A3 ;DIVIDE SIZE BY 8
SLL 4,A3
MOVE A3,A0
ADDI ENERGY_COLORS,A0
MOVE *A0,A3
CMPM *A2(PECOLOR),A3,W ;ARE WE OF THE CORRECT COLOR?
JREQ OUTEN_COLORED
MOVE A3,*A2(PECOLOR),W ;KEEP THE LATEST COLOR CHANGE
MOVE A0,A1
CALLA GPLAYNUM
INC A0
SWAP A0,A1
SLL 8,A1
ORI 40,A1
MOVK 1,A2
CALLA PALSET
OUTEN_COLORED
OUTENX
MMFM SP,A0,A1,A2,A3,A4,A7,A8
RETS
*DELETE THE ENERGY BAR
OUTEN_DEL
CLR A3
MOVE *A2(PEBAROBJ),A8,L ;PLAYER SCORE ADDRESS
JRZ OUTEN_COLORS ;BR = ALREADY GONE
CALLA DELETE_OBJ
CLRM *A2(PEBAROBJ),L
JRUC OUTEN_COLORS
*
*PLAYERS LIFE GRADATION BARS
*
PLIFEBAR_TAB
.LONG P1LIFEBAR_INIT,P2LIFEBAR_INIT,P3LIFEBAR_INIT
P1LIFEBAR_INIT
.byte 2, 0, 0, 2 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long REDPLAYR, P_REDHIT ;PAL LIST
.word OID_P1, OM_COLL
.LONG DUMCOLL
LWWWW X1LIFEBAR1b, DMAWNZ|M_LRCLIP, M_SCRNOBJ, 0, OM_CFUNC
LW C_OCONST, STATUS_FLASH_COLOR
LWWWW PLAY_HIT1_R, DMAWNZ, M_SCRNOBJ|M_NOPARTANI|M_NODISP|M_NOSCALE, 0, OM_CFUNC
LW C_OCONST, 0101H
P2LIFEBAR_INIT
.byte 2, 0, 0, 2 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long YELPLAYR, P_YELHIT ;PAL LIST
.word OID_P2, OM_COLL
.LONG DUMCOLL
LWWWW X2LIFEBAR1b, DMAWNZ|M_LRCLIP, M_SCRNOBJ, 0, OM_CFUNC
LW C_OCONST, STATUS_FLASH_COLOR
LWWWW PLAY_HIT1_Y, DMAWNZ, M_SCRNOBJ|M_NOPARTANI|M_NODISP|M_NOSCALE, 0, OM_CFUNC
LW C_OCONST, 0101H
P3LIFEBAR_INIT
.byte 2, 0, 0, 2 ;OBJCNT, PRCCNT, IMGPALCNT, PALCNT
.long BLUPLAYR, P_BLUHIT ;PAL LIST
.word OID_P3, OM_COLL
.LONG DUMCOLL
LWWWW X3LIFEBAR1b, DMAWNZ|M_LRCLIP, M_SCRNOBJ, 0, OM_CFUNC
LW C_OCONST, STATUS_FLASH_COLOR
LWWWW PLAY_HIT1_B, DMAWNZ, M_SCRNOBJ|M_NOPARTANI|M_NODISP|M_NOSCALE, 0, OM_CFUNC
LW C_OCONST, 0101H
;P1LIFEBAR_INIT
; .LONG X1LIFEBAR1b,DUMCOLL
; .WORD OID_P1,DMAWNZ|M_LRCLIP,M_SCRNOBJ,0
; .LONG 0
;P2LIFEBAR_INIT
; .LONG X2LIFEBAR1b,DUMCOLL
; .WORD OID_P2,DMAWNZ|M_LRCLIP,M_SCRNOBJ,0
; .LONG 0
;P3LIFEBAR_INIT
; .LONG X3LIFEBAR1b,DUMCOLL
; .WORD OID_P3,DMAWNZ|M_LRCLIP,M_SCRNOBJ,0
; .LONG 0
ENERGY_COLORS
.word 07C00H,07C00H,07D20H,07DC0H,07E00H,07E60H
.word 07EE0H,07F60H,07FE0H,07FE8H,07FEEH,07FF3H
.word 07FFFH,07FFFH
**************************************************************************
* *
* OUTENERGYWORD - ROUTINE TO OUTPUT ENERGY WORD. *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
OUTENERGYWORD
rets
MMTM SP,A1,A3,A4,A7,A8
; MOVI T1ENERENE,A1
JRUC OUTED_G
**************************************************************************
* *
* OUTDANGERWORD - ROUTINE TO OUTPUT DANGER WORD. *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
OUTDANGERWORD
rets
MMTM SP,A1,A3,A4,A7,A8
; MOVI T1ENERDAN,A1
OUTED_G
CLR A7
MOVE *A2(PEWORDOBJ),A8,L ;GET THE ENERGY BAR OBJECT
JRNZ OED_OBJEXISTS ;BR = GOOD, THE OBJECT EXISTS
INC A7
MOVI PLIFEBAR_TAB,A3
CALLR MAKE_PSTATUS_MULTI ;CREATE THE STATUS OBJECT
JRZ OED_X
CALLA OBJ_OFF
CALLA INSERT_OBJ
MOVE A8,*A2(PEWORDOBJ),L
OED_OBJEXISTS
MOVE *A8(OFLAGS),A4,W
CALLA ANI
MOVE A7,A7
JRZ OED_X
CALLA OBJ_ON
OED_X
MMFM SP,A1,A3,A4,A7,A8
RETS
**************************************************************************
* *
* LEVEL_UPDATE - PROCESS TO UPDATE PLAYER LIFE AND GUN POWER LEVELS *
* AT A LEVEL RATE. *
* *
**************************************************************************
LEVEL_UPDATE
; ALLPLYR START_DW
LU_LP
ALLPLYR PLOT_LEVELS
SLOOP 3,LU_LP
*
*PLOT_LEVELS - SUBROUTINE FOR LEVEL_UPDATE ONLY, TRASHES ANY REGS
* IT USES.
*A2 = PTR TO PLAYER DATA AREA
*
PLOT_LEVELS
MOVE *A2(PLIVES),A0,L
MOVE *A2(PLASTLPLOT),A1,L
CMP A0,A1 ;IS THE LIFE LEVEL CORRECT?
JREQ PL_X ;BR = YES
SUB A1,A0
JRLT PL_DROPPING
*BAR RISING
CMPI [1,0],A0 ;SMALL JUMP?
JRLS PL_PADDL ;BR = YES
MOVI [1,0],A0 ;MELLOW PLOTAGE
JRUC PL_PADDL
*BAR DROPPING
PL_DROPPING
ABS A0
CMPI [1,0],A0 ;SMALL JUMP?
JRLS PL_ADDA0L ;BR = YES
CMPI [15,0],A0 ;BIG JUMP?
JRHS PL_ADDA0L ;BR = YES, PLOT IT
MOVI [1,0],A0 ;MELLOW PLOTAGE
PL_ADDA0L
NEG A0
PL_PADDL
ADD A0,A1
CALLR OUTLIVES_A1
PL_X
RETS
**************************************************************************
* *
* START_DW - ROUTINE TO START THE DANGER WATCH PROCESS FOR A PLAYER. *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
START_DW
MMTM SP,A0,A1,A7,A11
MOVE A2,A11
CREATE PID_IND,DANGER_WATCH
MMFM SP,A0,A1,A7,A11
RETS
*
*NUMBER OF LIFE UNITS LEFT AT WHICH THE PLAYER IS IN DANGER
*
DANGER_LEVEL .EQU 20
DANGER_MIN_SLEEP .EQU 6
**************************************************************************
* *
* DANGER_WATCH - PROCESS TO WATCH A PLAYERS LIFE LEVEL AND SCREAM *
* DANGER! IF HE IS LOW ON LIFE. *
* A11 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
DANGER_WATCH
MOVE A11,A2
CALLA GPLAYNUM
SLL 5,A0
ADDI DANGER_SOUND_TAB,A0
MOVE *A0,A9,L ;GET SOUND CALL TO MAKE
DW_PLAYER_WATCH
MOVE *A11(POBJ),A14,L
JRNZ DW_NORMAL_LP
SLOOP 5,DW_PLAYER_WATCH
DW_NORMAL_LP
MOVE *A11(PLIVES+16),A10,W ;GET THE CURRENT LIFE AMOUNT
CMPI DANGER_LEVEL,A10 ;TOO LOW?
JRLE DW_IN_DANGER ;BR = YES, HE'S IN DANGER
SLOOP 1,DW_NORMAL_LP
DW_IN_DANGER
SLEEP 1
MOVE A11,A2
**** MOVI NRGLOW_TAB,A0
**** CALLA DO_HEADS_UP ;PUT UP THE MESSAGE
**** CALLR OUTDANGERWORD ;PLOP THE WORD DANGER
MOVE *A11(PEWORDOBJ),A8,L
JRNZ DW_DWORD_OK
SLOOP 1,DW_NORMAL_LP
DW_DWORD_OK
CALLA OBJ_ON
MOVE *A11(PLIVES),A10,L ;IS THIS PLAYER GONE?
JRLE DW_PLAYER_WATCH ;BR = YES, NO MORE
SRL 16,A10
CMPI DANGER_MIN_SLEEP,A10 ;MINIMUM SLEEP TIME?
JRHS DW_DSLEEP_OK ;BR = NO
MOVK DANGER_MIN_SLEEP,A10 ;DEFAULT ON MINIMUM
DW_DSLEEP_OK
CMPI DANGER_LEVEL,A10 ;STILL IN DANGER?
JRHI DW_OUT_OF_DANGER ;BR = NO
MOVE @GAME_STATE,A14,W
CMPI INPLAY,A14
JRNE DW_SKIP_SND
MOVE A9,A0
; CALLA ONESND
DW_SKIP_SND
SLEEPR A10
CALLA OBJ_OFF
SLOOPR A10,DW_DWORD_OK
DW_OUT_OF_DANGER
MOVE A11,A2
**** CALLR OUTENERGYWORD ;PLOP THE WORD ENERGY
SLOOP 1,DW_NORMAL_LP
DANGER_SOUND_TAB
.LONG P1_DANGER_SND, P2_DANGER_SND
P1_DANGER_SND
.WORD 0F201H,1,08082H,0 ;PLAYER ONE DANGER SOUND
P2_DANGER_SND
.WORD 0F201H,1,08083H,0 ;PLAYER TWO DANGER SOUND
**************************************************************************
* *
* MAKE_PSTATUS_MULTI *
* *
* Make a player status object. Treats it as a multi-parter *
* *
* A2 = Ptr to player data area *
* A3 = Table of status obj init tables *
* *
* Returns: *
* Z = Could not create object (A8 = undefined) *
* NZ = Successfully created (A8 = Un-inserted object) *
* *
**************************************************************************
MAKE_PSTATUS_MULTI
MMTM SP,A0,A1,A3,A5
MMTM SP,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10
CALLA GPLAYNUM
MOVE @NPLAYERS,A14,W
DEC A14
JRGT MPM_3PLAY ;BR = This is a three player game
*
* This is a funky hack to make player 2, use player 3's colors when
* we are setup for a two-player max model. Thanx Jack!
*
CMPK 1,A0
JRNE MPM_3PLAY ;BR = This is not player 2
INC A0 ;Use player 3's colors
MPM_3PLAY
SLL 5,A0
ADD A3,A0
MOVE *A0,A5,L
MOVE A5,B0 ;Get the proper init table
CALLA MULTIMAKE
JRZ MPM_X ;BR = Object(s) not allocated
MOVE *A2(PSTATUSXY),A3,L
MOVE A8,A0
MPM_POS_LOOP
CALLA OBJTOPNT
MOVE *A0(OPARTS),A0,L
JRNZ MPM_POS_LOOP
MOVI (PIZPOS+1) << 16,A1
CALLA STORE_ZVAL
MOVE A8,A8
MPM_X
MMFM SP,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10
MMFM SP,A0,A1,A3,A5
RETS
**************************************************************************
* *
* FLASH_PSTATUS - FLASH THE PLAYERS STATUS BARS. *
* A2 = PTR TO PLAYER *
* *
**************************************************************************
FLASH_PSTATUS
MMTM SP,A1,A8
MOVE *A2(PEBAROBJ),A8,L
JRZ FP_EW
MOVB *A8(OFLAGS+B_ANIM-7),A14
JRN FP_EW ;BR = Already flashing
MOVI FS_UNFLASH,A1
CALLA STRT_ANIM
CALLA OBJ_CONST
MOVE *A2(PSHIELD),A14,L
JRNZ FP_EW ;BR = No HIT while shielded
MOVE *A8(OPARTS),A8,L ;Get the HIT object
ANDNIM M_NODISP,*A8(OFLAGS),W
CALLA OBJ_CONST
MOVI FS_HIT_DISSIPATE,A1
CALLA STRT_ANIM
FP_EW
; MOVE *A2(PEWORDOBJ),A8,L
; JRZ FP_GB
; CALLR FLASH_STAT
;FP_GB
; MOVE *A2(PGBAROBJ),A8,L
; JRZ FP_GW
; CALLA FLASH_STAT
;FP_GW
; MOVE *A2(PGWORDOBJ),A8,L
; JRZ FP_SFLASH
; CALLA FLASH_STAT
FP_SFLASH
MOVE *A2(PSCOREFLASH),A14,W ;ARE WE FLASHING THE SCORE AREA?
JRNZ FP_X ;BR = YES, DO NOT FLASH AGAIN
MOVE *A2(PDEAD),A14,W ;IS HE MARKED AS DEAD?
JRNZ FP_X ;BR = YES, DO NOT FLASH
MMTM SP,A0,A2,A3,A4,A5,A7,A11
MOVI STATUS_FLASH_COLOR,A1 ;MAKE SCORE AREA THIS COLOR
SLL 16,A1 ; THIS IS THE CONSTANT DRAW COLOR
MOVE *A2(PPALID),A0,L ; LOOKUP THE CURRENT PALETTE
CALLA FINDPAL ; MAKE SURE IT HAS A PALETTE
MOVX A0,A1
MOVE A1,A7
MOVE *A2(PSCRAD),A3,L ;GET THE SCORE ADDRESS
MOVI BOX1d,A1 ;THIS IS OUR REFERENCE IMAGE
MOVI DMACNZ,A5 ;WRITE CONSTANT COLOR ALWAYS
MOVE A2,A11 ;KEEP PLAYER PTR HERE
MOVE A1,A14
CALLR SETUP_DMAN
MOVE *A1(IANIOFFX),A14,L
MOVE A7,A1
ADDI SCRCTR,A3 ; START OF TEXT
SUB A14,A3 ; ADJUST THE ANIMATION POINT
CALLA QDMAN2 ; OUTPUT THE SUCKER
MOVKM 1,*A11(PSCOREFLASH),W
CREATE PID_INDE,SCORE_REPLOT
MMFM SP,A0,A2,A3,A4,A5,A7,A11
FP_X
MMFM SP,A1,A8
RETS
**************************************************************************
* *
* PLAYER_SHIELD *
* *
* Bring up the player shield message, in place of HIT. *
* *
* A2 = Ptr to player *
* *
**************************************************************************
PLAYER_SHIELD
MMTM SP,A1,A8
MOVE *A2(PEBAROBJ),A8,L
JRZ PS_X
MOVE *A8(OPARTS),A8,L ;Get the shield object
MOVI FS_SHIELD_START,A1
CALLA STRT_ANIM
PS_X
MMFM SP,A1,A8
RETS
**************************************************************************
* *
* PLAYER_SHIELD_DONE *
* *
* Turn off shield message and put back the HIT. *
* *
* A2 = Ptr to player *
* *
**************************************************************************
PLAYER_SHIELD_DONE
MMTM SP,A1,A8
MOVE *A2(PEBAROBJ),A8,L
JRZ PSD_X
MOVE *A8(OPARTS),A8,L ;Get the shield object
MOVI FS_HIT_START,A1
CALLA STRT_ANIM
PSD_X
MMFM SP,A1,A8
RETS
**************************************************************************
* *
* SCORE_REPLOT - PROCESS TO REPLOT THE PLAYERS SCORE AREA AFTER *
* 4 TICKS. *
* A11 = PTR TO PLAYER DATA *
* *
**************************************************************************
SCORE_REPLOT
SLEEP 4
MOVE A11,A2
CALLR UPDSL
CLRM *A2(PSCOREFLASH),W
DIE
**************************************************************************
* *
* FLASH_STAT - FLASH A STATUS OBJECT TO ITS CONSTANT COLOR. IF THE *
* STATUS OBJECT IS ALREADY ANIMATING THEN BAIL. *
* A1 = OCONST *
* *
**************************************************************************
FLASH_STAT:
PUSH A1
movb *A8(OFLAGS+B_ANIM-7),A14 ;already animating??
jrn FS_X ;YES
FlashIt
movi FS_UNFLASH,A1
calla STRT_ANIM
move *A8(OCTRL),A14,W
andni M_WRNONZ|M_WRZERO,A14 ;NO NORMAL WRITING
ori M_CONNON,A14 ;REPLACE ALL DATA
move A14,*A8(OCTRL),W
FS_X
PULLQ A1
rets
*
* FLASH ANIM SCRIPT
*
FS_UNFLASH
LW 1,4
LWL 1,1|AFunc,A_FS_UNFLASH_PULL
*
* HIT marker dissipates
*
FS_HIT_DISSIPATE
LW 1,2
LWL 1,2|AFunc,A_FS_UNFLASH
LWL 1,1|AFunc,OBJ_OFF
LWL 1,1|AFunc,PULL_ANIM
*
* "SHIELD UP" in place of hit
*
FS_SHIELD_START
LWL SHLDUP_R,1|AFunc,OBJ_ON
LWL 1,1|AFunc,A_FS_UNFLASH_PULL
*
* "HIT" marker resume
*
FS_HIT_START
LWL PLAY_HIT1_R,1|AFunc,OBJ_OFF
LWL 1,1|AFunc,A_FS_UNFLASH_PULL
**************************************************************************
* *
* A_FS_UNFLASH - ANIM FUNC TO UNFLASH A STATUS OBJECT. *
* *
**************************************************************************
A_FS_UNFLASH_PULL:
calla PULL_ANIM
A_FS_UNFLASH
move *A8(OCTRL),A1,W
ori M_WRNONZ,A1 ;Do Write Non-Zero Data
andni M_CONNON|M_CONZER,A1 ;Don't Replace ALL
move A1,*A8(OCTRL),W
rets
**************************************************************************
* *
* PRINT_SCORE - ROUTINE TO PLASTER A SCORE ON A GIVEN OBJECT. *
* *
* A1 = SCORE TO GIVE *
* A2 = PTR TO PLAYER RECIEVING *
* A8 = OBJECT TO PLASTER IT UPON *
* A9 = SCREEN OFFSET FROM CENTER OF OBJECT IN [Y,X] FORMAT *
* *
**************************************************************************
PRINT_SCORE:
MOVE A2,A2
JRZ PS_XXX
MMTM SP,A0,A1,A7,A8,A9,A10,A11
MOVE A1,A10
SRL 1,A1 ;SHIFT OUT FLAG
SLL 1,A1
CALLR SCORE ;AND GIVE SCORE
MOVE A2,A11 ;ALL IN PROPER PROCESS REGS
CREATE PID_INDE,SCOREOBJ
MMFM SP,A0,A1,A7,A8,A9,A10,A11
PS_XXX
RETS
**************************************************************************
* *
* SCOREOBJ - PROCESS TO CREATE A SCORE OBJECT THEN TAKE IT AWAY. *
* *
* A8 = OBJECT TO PLASTER IT UPON *
* A9 = SCREEN OFFSET FROM CENTER OF OBJECT IN [Y,X] FORMAT *
* A10 = SCORE TO AWARD (BIT 0 FLAGS UPWARD MOTION ON IMAGE) *
* A11 = PTR TO PLAYER DATA *
* *
**************************************************************************
SCOREOBJ:
MOVI SCORETAB,A3
JRUC SCOBJ_EXE
*
*SCORE2XOBJ - SAME AS SCOREOBJ EXCEPT USES A DIFFERENT LOOK-UP TABLE
SCORE2XOBJ:
MOVI SCORETAB2X,A3
JRUC SCOBJ_EXE
SCOBJ_EXE
MOVE A10,A14 ;KEEP THE SCORE HERE
SRA 1,A14 ;SHIFT OUT FLAG
SLL 1,A14
SO_SCLP:
MOVE *A3+,A4,L
JRZ SO_DIE ;THE SCORE IMAGE CANNOT BE FOUND
CMP A4,A14
JREQ SO_SFOUND ;BR = FOUND A SCORE
ADDK 32,A1
JRUC SO_SCLP ;SEARCH AGAIN
SO_SFOUND:
MOVI SCRIMGINIT,A5
CALLA CREATE_OBJ
JRZ SO_DIE ;BR=OOPS!
; MOVE *A8(OID),A14,W
; ANDI MASK_TYPE,A14
; CMPI TYPE_ENEMY & MASK_TYPE,A14
; JRNE SO_NOENEMY ;BR=NOT AN ENEMY
BTST 0,A10
JRZ SO_NOMO ;BR=DON'T MOVE
MOVI -010000H,A14
MOVE A14,*A0(OYVEL),L ;MOVIN' ON UP
;SO_NOENEMY
SO_NOMO
MOVE *A8(OZVAL),A7,L
DEC A7 ;PLACE SCORE IN FRONT OF OBJECT
MOVE A7,*A0(OZVAL),L
MOVE *A8(OCTRL),A4,W
CALLA GET_CPNTU ;GET UNIV POSITIONS: X IN A2, Y IN A1
MOVE A9,A14 ;CONVERT SCRN X OFFSET TO WORLD
SEXT A14,W
BTST B_FLIPH,A4
JRZ SO_NOFLIPH ;BR=NO H-FLIP
NEG A14
SO_NOFLIPH
SLL 15,A14
ADD A14,A2 ;ADD X OFFSET
MOVE A2,*A0(OXVAL),L
SRA 16,A9 ;CONVERT SCRN Y OFFSET TO WORLD
BTST B_FLIPV,A4
JRZ SO_NOFLIPV ;BR=NO V-FLIP
NEG A9
SO_NOFLIPV
SLL 15,A9
ADD A9,A1 ;ADD Y OFFSET
MOVE A1,*A0(OYVAL),L
MOVE *A3,A1,L ;GET THE IMAGE
MOVE A0,A8
MOVE *A11(PPALID),A0,L
CALLA CHANGE_PAL ;CHANGE TO THE CORRECT PALETTE
MOVE *A8(OCTRL),A4,W
CALLA ANI ;CHANGE THE SCORE IMAGE
;THIS CODE IS DIABLED
;
; MOVE *A8(OUSIZE),A0,L
; MOVE *A8(OUANIOFF),A1,L
;
; CMPI 0E0H << Z2SCALE,A7
; JRHI SO_NOT2X ;BR = NOT DOUBLE SCALE
;;THE FOLLOWING WILL NOT WORK IF WE HAVE NEGATIVE ANIMATION POINTS
; SLL 1,A0 ;MULTIPLY BY 2
; SLL 1,A1
; MOVI 080H,A2
; JRUC SO_SCALEOK
;SO_NOT2X
; CMPI 0200H << Z2SCALE,A7
; JRLO SO_SCALE1TO1 ;BR = NOT HALF SCALE
; MOVE A0,A3 ;DIVIDE BY 2
; SRL 1,A3
; ZEXT A0,W
; SRL 1,A0
; MOVY A3,A0
; MOVE A1,A3
; SRL 1,A3
; ZEXT A1,W
; SRL 1,A1
; MOVY A3,A1
; MOVI 0200H,A2
;SO_SCALEOK
; MOVE A0,*A8(OSIZE),L
; MOVE A1,*A8(OANIOFF),L
; MOVE A2,*A8(OSCALEX),W
; MOVE A2,*A8(OSCALEY),W
;SO_SCALE1TO1
CALLA INSERT_OBJ
SLEEP 60 ;PAUSE THE SCORE FOR A SECOND
CALLA DELETE_OBJ ;RID O' THE OBJECT
SO_DIE:
DIE
*
*GENERIC SCORE IMAGE INIT TABLE
SCRIMGINIT:
.LONG SCR1000,DUMCOLL
.WORD OID_JUNK,DMAWNZ,M_NOSCALE|M_NOPIXSCAN,0
.LONG 0
*
*TABLE OF BCD SCORES AND THEIR ASSOCIATED IMAGES
* .LONG SCORE, PTR TO IMAGE
* .LONG 0
SCORETAB
SCORETAB2X
.LONG 500,SCR500
.LONG 1000,SCR1000,2000,SCR2000,3000,SCR3000,4000,SCR4000
.LONG 5000,SCR5000,6000,SCR6000,7000,SCR7000,8000,SCR8000
.LONG 9000,SCR9000,10000,SCR10000,15000,SCR15000
.LONG 20000,SCR20000,25000,SCR25000,40000,SCR40000
.LONG 80000,SCR80000,0
.IF 0 ;This is the scrap heap
**************************************************************************
* *
* OUTGUN - OUTPUT PLAYER GUN ENERGY BAR. *
* A2 = PTR TO PLAYER DATA AREA *
* RETURNS: *
* NOTHING *
* NOTE: TRASHES A14 *
* *
**************************************************************************
OUTGUN
rets
MMTM SP,A1,A2,A3,A4,A5,A7,A8
MOVE *A2(PGUNPOWER),A1,W ;CURRENT GUN ENERGY LEVEL
JRUC OUTGUN_G
*
*ENTRYPOINT FOR OUTGUN, BUT PLOT LEVEL PASSED IN A1
*
OUTGUN_A1
MMTM SP,A1,A2,A3,A4,A5,A7,A8
OUTGUN_G
MOVE A1,*A2(PLASTGPLOT),W ;KEEP IT AS OUR LAST PLOT
MOVE @GAME_STATE,A3,W
CMPI INAMODE,A3
JREQ OUTGUNX ;NO ENERGY OUTPUT DURING AMODE
MOVE *A2(POBJ),A8,L
JRZ OUTGUN_DEL ;BR = NO GUN BAR FOR DEAD GUY
MOVE A1,A1
JRZ OUTGUN_DEL ;BR = NO GUN, DELETE THE OBJECT
CLR A4
MOVE *A2(PGBAROBJ),A8,L ;GET THE GUN BAR OBJECT
JRNZ OG_OBJEXISTS ;BR = GOOD, THE OBJECT EXISTS
INC A4
MOVI PGUNBAR_TAB,A3
CALLA MAKE_PSTATUS ;CREATE THE STATUS OBJECT
JRZ OUTGUNX
CALLA OBJ_OFF
CALLA INSERT_OBJ
MOVE A8,*A2(PGBAROBJ),L
OG_OBJEXISTS
MOVE *A2(PGUNMULT),A7,L ;GET GUN MULTIPLIER
MPYU A7,A1 ;MAKE OUR SIZE
SRL 16,A1 ;THIS IS THE HORIZONTAL SIZE WE NEED
JREQ OUTGUN_DEL ;BR = OOPS WENT TO ZERO
CMPI GUNENERGY,A1 ;ARE WE BIGGER THAN THE MAX
JRLS OG_SOK
MOVI GUNENERGY,A1 ;DEFAULT ON MAX
OG_SOK
MOVE *A8(OSIZEX),A3,W
SUB A1,A3
CMPI P1DATA,A2
JRNE OG_P2
MOVE A3,A2
CLR A3
JRUC OG_OBJCLIP
OG_P2
CLR A2
OG_OBJCLIP
CALLR CLIP_GUNBAR
MOVE A4,A4 ;WAS THE OBJECT OFF?
JRZ OUTGUNX ;BR = NO
CALLA OBJ_ON
OUTGUNX
MMFM SP,A1,A2,A3,A4,A5,A7,A8
RETS
*DELETE THE GUN BAR
OUTGUN_DEL
MOVE *A2(PGBAROBJ),A8,L ;GET GUN BAR OBJECT
JRZ OUTGUNX ;BR = ALREADY GONE
CALLA DELETE_OBJ
CLRM *A2(PGBAROBJ),L
JRUC OUTGUNX
*
*PLAYERS GUN GRADATION BARS
*
PGUNBAR_TAB
.LONG P1GUNBAR_INIT,P2GUNBAR_INIT
P1GUNBAR_INIT
.LONG T1GUNBAR,DUMCOLL
.WORD OID_JUNK,DMAWNZ|M_SCRNOBJ,0
.LONG 0
P2GUNBAR_INIT
.LONG T2GUNBAR,DUMCOLL
.WORD OID_JUNK,DMAWNZ|M_SCRNOBJ,0
.LONG 0
**************************************************************************
* *
* CLIP_GUNBAR - ROUTINE TO CLIP GUN BAR OBJECT *
* A2 = RIGHT CLIP (RELATIVE TO CURRENT SIZE) *
* A3 = LEFT CLIP (RELATIVE TO CURRENT SIZE) *
* A8 = OBJECT BLOCK *
* RETURNS *
* NOTHINE *
* *
**************************************************************************
CLIP_GUNBAR
MMTM SP,A0,A2,A3,A4,A9,A11,A12
MOVE A8,A0
MOVE *A8(OXPOS),A4,W
ADDI OFLAGS,A0 ;GET INDEX INTO OBJECT STRUCTURE
* A9= VS:HS
* A11= SAG
* A12= OFFSET:FLAGS
MMFM A0,A9,A11,A12
*
*CLIP THE SAG, HS, AND ADJUST OFFSET
*
MOVE @NO_MIRROR,A14,W
JRZ CGB_MIRROR
ADD A3,A2 ;RC+LC
MOVE A9,A14
SUB A2,A14
SEXT A14 ;DID WE GO TOO FART?
JRGT CGB_NM_SOK
MOVK 1,A14 ;MIN SIZE
CGB_NM_SOK
*** SUB A2,A9 ;DECREASE OBJECT SIZE ACCORDINGLY
MOVX A14,A9
ADD A3,A4 ;ADD LEFT CLIP TO X POSITION
BTST B_FLIPH,A12 ;TEST WHILE NOT MIRRORED
JREQ CGB_NOFLIP
JRUC CGB_FLIPPED
CGB_MIRROR
SWAP A2,A3 ;SWAP LEFT AND RIGHT CLIP FOR MIRROR
ADD A2,A4 ;ADD LEFT CLIP TO X POSITION
ADD A3,A2 ;RC+LC
MOVE A9,A14
SUB A2,A14
SEXT A14 ;DID WE GO TOO FART?
JRGT CGB_M_SOK
MOVK 1,A14 ;MIN SIZE
CGB_M_SOK
*** SUB A2,A9 ;DECREASE OBJECT SIZE ACCORDINGLY
MOVX A14,A9
BTST B_FLIPH,A12 ;TEST WHILE MIRRORING
JRNE CGB_NOFLIP
CGB_FLIPPED
NEG A2 ;NEGATE RC+LC
NEG A3 ;NEGATE LC
CGB_NOFLIP
SLL 3,A3
ADD A3,A11 ;ADD TO SAG
SLL 16,A2
ADDXY A2,A12 ;CHANGE THE OFFSET
PUSHST
DINT
MMTM A0,A9,A11,A12
MOVE A4,*A8(OXPOS),W
POPST
MMFM SP,A0,A2,A3,A4,A9,A11,A12
RETS
**************************************************************************
* *
* OUTGUNWORD - ROUTINE TO OUTPUT THE GUN WORD OBJECT. *
* A2 = PTR TO PLAYER DATA AREA *
* *
**************************************************************************
OUTGUNWORD
rets
MMTM SP,A3,A8
MOVE *A2(PGWORDOBJ),A8,L ;GET THE CURRENT GUN WORD OBJECT
JRNZ OGW_X ;BR = GOOD, THE OBJECT EXISTS
MOVI PGUNWORD_TAB,A3
CALLA MAKE_PSTATUS ;CREATE THE STATUS OBJECT
JRZ OGW_X
CALLA INSERT_OBJ
MOVE A8,*A2(PGWORDOBJ),L
OGW_X
MMFM SP,A3,A8
RETS
*
*TABLE OF PLAYER GUN WORD INIT TABLES
*
PGUNWORD_TAB
.LONG P1GUNWORD_INIT,P2GUNWORD_INIT
*
*PLAYER GUN WORD INIT TABLES
*
P1GUNWORD_INIT
.LONG T1GUNGUN,DUMCOLL
.WORD OID_JUNK,DMAWNZ|M_SCRNOBJ,0
.LONG 0
P2GUNWORD_INIT
.LONG T2GUNGUN,DUMCOLL
.WORD OID_JUNK,DMAWNZ|M_SCRNOBJ,0
.LONG 0
*
* This goes on the end of PLOT_LEVELS
PL_GUN
MOVE *A2(PGUNPOWER),A0,W
MOVE *A2(PLASTGPLOT),A1,W
CMP A0,A1 ;IS THE GUN LEVEL CORRECT?
JREQ PL_DONE ;BR = YES
SUB A1,A0
MOVE A0,A14
ABS A0
CMPI 1,A0
JRLS PL_ADDA0G
MOVK 1,A0
PL_ADDA0G
MOVE A14,A14
JRNN PL_PADDG
NEG A0
PL_PADDG
ADD A0,A1
CALLR OUTGUN_A1
PL_DONE
RETS
.ENDIF
.END