total-carnage/BAKGND.ASV

1224 lines
27 KiB
Plaintext
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.

.FILE 'BAKGND.ASM'
.TITLE "BACKGROUND HANDLERS"
**************************************************************************
* *
* COPYRIGHT (C) 1988 WILLIAMS ELECTRONICS GAMES, INC. *
* ALL RIGHTS RESERVED. *
* *
**************************************************************************
.OPTION B,D,L
.MNOLIST
* GET THE SYSTEM STUFF
.INCLUDE "MPROC.EQU" ;MPROC EQUATES
.INCLUDE "DISP.EQU" ;DISPLAY PROCESSOR EQUATES
.INCLUDE "\VIDEO\SYS\GSP.INC" ;GSP ASSEMBLER EQUATES
.INCLUDE "\VIDEO\SYS\SYS.INC" ;ZUNIT SYSTEM EQUATES
.INCLUDE "\VIDEO\SYS\MACROS.HDR" ;MACROS, YEAH!
.INCLUDE "BGNDTBL.GLO" ;BACKGROUND EQUATES
.INCLUDE "GAME.EQU"
;*BACKGROUND SYSTEM STUFF
.GLOBAL BAKBITS,BAKMODS,BAKLST,BGND_UD1
*GLOBALS IN THIS FILE
*RAM EQUATES
.GLOBL FREEPAL,GETBPAL
.REF ANI_FLAG,ARWOFF,PCNT,DROPBMB,TARGET_NUM,ANI_HSTG,RANDPER
.REF ANI_EYES,ANI_HD,ANI_LARM,ANI_RARM,ANI_TYP,ANI_MTH,ANI_STAT
.REF CRATEMAN,SEND_GROUP,BLOW_RCTR,SPATH,KPLARM,INTRO
.REF ANI_STEEL
.REF TANKON
.REF SOLDR,SOLDRD,SOLDRDL
.REF STRT_GPIT
.BSS BGNDPALTBL,32,1
.BSS MOD_POS,32,1
.BSS BAKBITS,10000
; .BSS BAK2BITS,1000
.BSS BAKMODS,32
; .BSS BAK2MODS,32
.TEXT
*BACKGROUND UPDATER EQUATES
BLSTSTRT .EQU >8000
BLSTEND .EQU >8001
************* LOCAL CONSTANTS FOR UPD **************
DISP_PAD .SET >00200020 ; Y:X
;DISP_PAD .SET >00000000 ; Y:X
WIDEST_BLOCK .SET 250
;* MUST KEEP THE SIZE OF THESE STRUCTURES A MULTIPLE OF 16
MAP_ZFLAGSPAL .SET 0
MAP_PAL .SET 0 ;SIZE 4 - PALETTE SELECT
MAP_FLAGS .SET 4 ;SIZE 4 - BIT 0 HFLIP, BIT 1 YFLIP
MAP_Z .SET 8 ;SIZE 8
MAP_X .SET 16 ;SIZE 16
MAP_Y .SET 32 ;SIZE 16
MAP_HDR .SET 48 ;SIZE 16 - OFFSET IN LONG WORDS FROM BLOCK_HDR_TBL
; BITS 12-15 ARE BITS 4-7 OF PAL
; MAP_HDR SET TO >FFFF IF BLOCK IS NOT ALLOCATED
BLOCK_SIZE .SET 64 ;* IF CHANGED MUST GET RID OF SHIFTS BY 6
;* Offsets for a BLOCK HDR structure
MAP_SIZE .SET 0
MAP_W .SET 0 ;SIZE 16 ; THESE FIELDS CAN'T BE CHANGED
MAP_H .SET 16 ;SIZE 16 ; BECAUSE THEY ARE USED AS THE
MAP_DATAPTR .SET 32 ;SIZE 32 ;
BLOCK_HDR_SIZE .SET 64
;* OFFSETS FOR A BLOCK HDR STRUCTURE
;MAP_SIZE .SET 0
;MAP_W .SET 0 ;SIZE 16 ; THESE FIELDS CAN'T BE CHANGED
;MAP_H .SET 16 ;SIZE 16 ; BECAUSE THEY ARE USED AS THE
;MAP_ANIMOFF .SET 32 ;SIZE 32 ; OIMG BLOCK HEADER
;MAP_DATAPTR .SET 64 ;SIZE 32 ;
;BLOCK_HDR_SIZE .SET 96
************************************************************************
BGNDHGHT:
;PARMS A0 - XPOS FOR WHICH HEIGHT OF BACKGROUND NEEDS TO BE DETERMINED
;RETURNS A0 -
; MINIMUM YPOS (MAX HEIGHT) OF PRIMARY BACKGROUND WHICH OVERLAPS
; SPECIFIED XPOS
; A0 = 0 IF XPOS IS INVALID
;* SCAN A MODULE LIST TO FIND OUT WHICH MODULE CONTAINS BLOCKS
;* WHICH NEED TO BE CHECKED
MMTM SP,A1,A2,A3,A4,A7,A8,A9,A10,A11
MOVE A0,A1
CLR A10 ;INIT PACKED Y:X STARTING POSITION
CLR A11
MOVE @BAKMODS,A0,L ;* A0- PTR TO THE MODULE LIST
MODLP0:
MOVE *A0+,A8,L ;LOAD MODULE PTR
CMPI >FFFFFFFF,A8
JRZ MODX0 ;END OF THE MODULE TBL
MOVE *A8+,A9,L ;LOAD PACKED Y:X SIZE
MOVE *A0+,A3,W ;X START POSITION
ZEXT A3,W
CMPI BLSTSTRT,A3
JRNZ NOTLSTSTRTX
MOVE A11,A3
SUBXY A9,A3
JRUC GOTNEWX0
NOTLSTSTRTX:
CMPI BLSTEND,A3
JRNZ GOTNEWX0
MOVE A11,A3
GOTNEWX0:
MOVE *A0+,A4,W ;Y START POSITION
ZEXT A4,W
CMPI BLSTSTRT,A4
JRNZ NOTLSTSTRTY
MOVE A11,A4
SUBXY A9,A4
JRUC GOTNEWY0
NOTLSTSTRTY:
CMPI BLSTEND,A4
JRNZ NOTLSTENDY
MOVE A11,A4
JRUC GOTNEWY0
NOTLSTENDY:
SLL 16,A4
GOTNEWY0:
MOVY A4,A3
MOVE A3,A10
; CMPXY A10,A1
; JRV MODX0 ;JUMP TO EXIT LOOP IF MOD START X > X SOUGHT
;IF MOD END X < X SOUGHT KEEP SEARCHING MOD LIST
MOVE A10,A11
ADDXY A9,A11 ;A11 IS MODULE Y:X END
MOVE *A8+,A9,W ;LOAD # OF BLOCKS
ADD A9,A7 ;A7 IS NEW BAKBITS PTR
CMPXY A11,A1
JRNV MODLP0 ;SKIP IF AX < BX
MOVE A10,A0
SRL 16,A0
JRUC GOTHGHT
MODX0:
CLR A0
GOTHGHT:
MMFM SP,A1,A2,A3,A4,A7,A8,A9,A10,A11
RETS
************************************************************************
**************************** BSRCH1STXB ********************************
BSRCH1STXB:
;*** PARMS
; A0 - X COORDINATE OF A BLOCK
; A1 - START OF BACKGROUND BLOCK TABLE
; A2 - END OF BLOCK TABLE
;*** RETURNS
; A0 - ADDRESS OF FIRST BLOCK WITH X COORDINATE >= PARM
; IF NEW X IS HIGHEST RETURNS NEXT EMPTY BLOCK
; IF NO BLOCKS WITH >= X, RETURN 0
;* A0 = X VAL BEING SEARCHED FOR
;* A1 = BLOCK TABLE BASE + OFFSET TO X VAL
;* A14 - THRESHHOLD FOR SWITCHING FROM BINARY TO LINEAR SEARCH
;* A9 = LOW # -- # GREATEST BACKGROUND BLOCK
;* A10 = MID # -- (HIGH + LOW) >> 1
;* A2 = HIGH # -- # OF LOWEST BACKGROUND BLOCK
MMTM SP,A1,A2,A8,A9,A10
CLR A9 ;* SET LOW = 0
SUB A1,A2
SRL 6,A2 ;* DIV BY SIZE OF BLOCK (64)
ADDI MAP_X,A1 ;* BLOCK TBL BASE + X OFFSET
MOVK 5,A14 ;* THRESHHOLD FOR SWITCHING FROM BINARY TO LINEAR SEARCH
BSRCH:
MOVE A2,A10
SUB A9,A10 ;* IF (HIGH - LOW) <= 5 FINISH WITH LINEAR SEARCH
CMP A14,A10
JRLE LSRCH
SRL 1,A10
ADD A9,A10
;* GET MID->X
MOVE A10,A8
SLL 6,A8 ;* MULTIPLY BY BLOCK SIZE (64)
ADD A1,A8
MOVE *A8,A8,W ;* GET X COOR OF THE BLOCK
CMP A0,A8
JRLT BLOW
MOVE A10,A2 ;* HIGH = MID
JRUC BSRCH
BLOW:
MOVE A10,A9 ;* LOW = MID
JRUC BSRCH
LSRCH:
;* FINISH WITH A LINEAR SEARCH OF BLOCK TABLE FROM LOW TO HIGH
;* ENDING WITH FIRST BLOCK X COOR THAT IS >= A0
;* A0 = X VAL BEING SEARCHED FOR
;* A9 = LOW ADDRESS -- PTS TO X OFFSET OF BLOCK
;* A2 = HIGH ADDRESS -- PTS TO X OFFSET OF BLOCK
SLL 6,A9 ;* LOW BLOCK # TO LOW BLOCK OFFSET
SLL 6,A2 ;* HIGH BLOCK # TO HIGH BLOCK OFFSET
ADD A1,A9
ADD A1,A2
MOVI BLOCK_SIZE,A8
LSRCHLP:
MOVE *A9,A10,W ;* X COOR
CMP A0,A10
JRGE GOTB ;* IF LOW->X >= A0 GOTO FOUND
ADD A8,A9
CMP A2,A9
JRLE LSRCHLP
;* BLOCK NOT FOUND, RETURN 0
CLR A0
JRUC BSRCHDONE
GOTB:
;* RETURN A PTR TO THE BLOCK
MOVE A9,A0
SUBI MAP_X,A0
BSRCHDONE:
MMFM SP,A1,A2,A8,A9,A10
RETS
**************************** BSRCH1STXB ********************************
*********************** BAK END *******************************
;* SCAN A MODULE LIST AND RETURN THE PACKED Y:X END POINT
;PARMS
;A0 - MODULE LIST
;RETURNS
;A0 - PACKED Y:X END OF WAVE
BAK_END:
MMTM SP,A3,A4,A8,A9,A10,A11
CLR A10 ;CLR PACKED Y:X STARTING POSITION
CLR A11
WEMODLP:
MOVE *A0+,A8,L ;LOAD MODULE PTR
CMPI >FFFFFFFF,A8
JRZ WEMODX ;END OF THE MODULE TBL
MOVE *A8+,A9,L ;LOAD PACKED Y:X SIZE
MOVE *A0+,A3,W ;X START POSITION
ZEXT A3,W
CMPI BLSTSTRT,A3
JRNZ WENOTLASTSTARTX
MOVE A11,A3
SUBXY A9,A3
JRUC WEGOTNEWX
WENOTLASTSTARTX:
CMPI BLSTEND,A3
JRNZ WEGOTNEWX
MOVE A11,A3
WEGOTNEWX:
MOVE *A0+,A4,W ;Y START POSITION
ZEXT A4,W
CMPI BLSTSTRT,A4
JRNZ WENOTLASTSTARTY
MOVE A11,A4
SUBXY A9,A4
JRUC WEGOTNEWY
WENOTLASTSTARTY:
CMPI BLSTEND,A4
JRNZ WENOTLASTENDY
MOVE A11,A4
JRUC WEGOTNEWY
WENOTLASTENDY:
SLL 16,A4
WEGOTNEWY:
MOVY A4,A3
MOVE A3,A10
MOVE A10,A11
ADDXY A9,A11 ;A11 IS MODULE Y:X END
JRUC WEMODLP
WEMODX:
MOVE A11,A0
MMFM SP,A3,A4,A8,A9,A10,A11
RETS
***********************************************************************
*********************** BAK START *******************************
;* SCAN A MODULE LIST AND RETURN THE PACKED Y:X STARTING POINT
;PARMS
;A0 - MODULE LIST
;RETURNS
;A0 - PACKED Y:X START OF WAVE
BAK_STRT:
MMTM SP,A3,A4,A8,A9,A11
CLR A11
MOVE *A0+,A8,L ;LOAD MODULE PTR
CMPI >FFFFFFFF,A8
JRZ WSMODX ;END OF THE MODULE TBL
MOVE *A8+,A9,L ;LOAD PACKED Y:X SIZE
MOVE *A0+,A3,W ;X START POSITION
ZEXT A3,W
CMPI BLSTSTRT,A3
JRNZ WSNOTLASTSTARTX
MOVE A11,A3
SUBXY A9,A3
JRUC WSGOTNEWX
WSNOTLASTSTARTX:
CMPI BLSTEND,A3
JRNZ WSGOTNEWX
MOVE A11,A3
WSGOTNEWX:
MOVE *A0+,A4,W ;Y START POSITION
ZEXT A4,W
CMPI BLSTSTRT,A4
JRNZ WSNOTLASTSTARTY
MOVE A11,A4
SUBXY A9,A4
JRUC WSGOTNEWY
WSNOTLASTSTARTY:
CMPI BLSTEND,A4
JRNZ WSNOTLASTENDY
MOVE A11,A4
JRUC WSGOTNEWY
WSNOTLASTENDY:
SLL 16,A4
WSGOTNEWY:
MOVY A4,A3
MOVE A3,A0
WSMODX:
MMFM SP,A3,A4,A8,A9,A11
RETS
***********************************************************************
**************** U P D A T E D I S P L I S T **********************
* DELETES ALL DISPLAY OBJECTS WHICH ARE NOT ON THE SCREEN
* INSURES ALL BACKGROUND BLOCKS ON SCREEN ARE ON THE DISP LIST
BGND_UD1:
* CALL TO UPDATE MAIN BACKGROUND
* INPUT, WORLDTL, SCRNTL, SCRNLR, BAKLST, BAKBITS, BAKMODS
* THIS PROTECTS DISP_MOD AND DISP_DEL TOO!
MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
MMTM SP,B0
;* GET COORS OF AREA TO BE PUT ON DISPLAY LIST.
MOVE @WORLDTL,A3,1
MOVE A3,A4
MOVE @SCRNTL,A0,1
ADDXY A0,A3
MOVE @SCRNLR,A0,1
ADDXY A0,A4
MOVI DISP_PAD,A0
SUBXY A0,A3 ;A3 - DISP_TL
ADDXY A0,A4 ;A4 - DISP_LR
MOVI BAKLST,A8 ;A8 - BAKGROUND LIST
CALLR DISP_DEL
;* DETERMINE WHICH MODULE
MOVE @BAKMODS,A0,L ;A0- PTR TO THE MODULE LIST
MOVI INSBOBJ,B0 ;B0 - WHICH INSERT ROUTINE
MOVI BAKBITS,A7 ;A7 - BIT TABLE FOR BLOCK BEING ON DISP LIST
CALLR DISP_MOD
MMFM SP,B0
MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
RETS
;BGND_UD2: ;* CALL TO UPDATE SECONDARY BACKGROUND
;* INPUT, BAK2TLX, BAK2TLY, SCRNTL, SCRNLR, BAK2LST, BAK2BITS, BAK2MODS
; MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
; MMTM SP,B0
; ;* GET COORS OF AREA TO BE PUT ON DISPLAY LIST.
; MOVE @BAK2TLX+16,A3,W
; MOVE @BAK2TLY+16,A0,W
; SLL 16,A0
; MOVY A0,A3
; MOVE A3,A4
; MOVE @SCRNTL,A0,L
; ADDXY A0,A3
; MOVE @SCRNLR,A0,L
; ADDXY A0,A4
; MOVI DISP_PAD,A0
; SUBXY A0,A3 ;A3 = DISP_TL
; ADDXY A0,A4 ;A4 = DISP_LR
; MOVI BAK2LST,A8 ;A8 - BAKGROUND LIST
; CALLR DISP_DEL
; MOVI INSB2OBJ,B0 ;B0 - WHICH INSERT ROUTINE
; MOVE @BAK2MODS,A0,L ;* A0- PTR TO THE MODULE LIST
; MOVI BAK2BITS,A7
; CALLR DISP_MOD
; MMFM SP,B0
; MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14
; RETS
***********************************************************************
*********************** D I S P M O D *******************************
;* SCAN A MODULE LIST TO FIND OUT WHICH MODULES CONTAIN BLOCKS
;* WHICH NEED TO BE CHECKED FOR ADDITION TO THE DISPLAY LIST.
; B0 - WHICH INSERT ROUTINE
; A0 - MODULE LIST
; A3 - DISP_TL
; A4 - DISP_LR
; A7 - BAKBITS ;A7 - BIT TABLE FOR BLOCK BEING ON DISP LIST
;PARMS FOR DISP_ADD
; A1 - BACKGROUND BLOCK TABLE
; A2 - END OF BACKGROUND BLOCK TABLE
; A5 - BACKGROUND HDR TABLE
; A9 - MODULE START POSITION Y:X
; A10 - PTR TO PALETTE TABLE FOR NEW BLOCK
; ;PASSED FROM ABOVE
; A3 - DISP_TL
; A4 - DISP_LR
; A6 - WHICH BAKGROUND INSERT ROUTINE PRIMARY|SECONDARY
; A7 - BIT TABLE FOR BLOCK BEING ON DISP LIST
;* CALLER IS RESPONSIBLE FOR PUSHING AND POPPING ALL A-REGISTERS
DISP_MOD:
CLR A9 ;INIT Y:X STARTING POSITION
CLR A11 ;ENDING Y:X POS
MOVE A7,A6 ;A6 WILL POINT TO BAKBITS AFTER MOD
MODLP:
SKDADD:
MOVE A6,A7
MOVE *A0+,A8,L ;LOAD MODULE PTR
CMPI >FFFFFFFF,A8
JRZ MODX ;END OF THE MODULE TBL
MOVE *A8+,A10,L ;LOAD Y:X SIZE
MOVE *A0+,A14,W ;X START POSITION
ZEXT A14,W
; CMPI BLSTSTRT,A14
; JRNZ NOTLASTSTARTX
; MOVE A11,A14
; SUBXY A10,A14
; JRUC GOTNEWX
;NOTLASTSTARTX:
; CMPI BLSTEND,A14
; JRNZ GOTNEWX
; MOVE A11,A14
;GOTNEWX:
MOVE *A0+,A5,W ;Y START POSITION
ZEXT A5,W
; CMPI BLSTSTRT,A5
; JRNZ NOTLASTSTARTY
; MOVE A11,A5
; SUBXY A10,A5
; JRUC GOTNEWY
;NOTLASTSTARTY:
; CMPI BLSTEND,A5
; JRNZ NOTLASTENDY
; MOVE A11,A5
; JRUC GOTNEWY
;NOTLASTENDY:
SLL 16,A5
;GOTNEWY:
MOVY A5,A14
MOVE A14,A9
MOVE A9,A11
ADDXY A10,A11 ;A11 IS MODULE Y:X END
MOVE *A8+,A10,W ;LOAD # OF BLOCKS
ADD A10,A6 ;A6 IS NEW BAKBITS PTR
; CMPXY A9,A4
; JRXLE MODX ;JUMP TO EXIT LOOP IF MOD START X > SCREEN END X
CMPXY A3,A11
JRXLT SKDADD ;SKIP IF MOD X END < TL X
JRYLT SKDADD ;SKIP IF MOD Y END < TL Y
CMPXY A9,A4
JRXLT SKDADD ;USE THIS IF MODULES AREN'T SORTED LFT TO RGT
;JUMP TO IF MOD START X > SCREEN END X
JRYLT SKDADD ;SKIP IF MOD Y START > BR Y
MOVE *A8+,A1,L ;A1-BLOCK TABLE
MOVE A10,A2
SLL 6,A2 ;EACH BLOCK IS 4 WORDS LONG
ADD A1,A2 ;A2-BLOCK TABLE END
MOVE *A8+,A5,L ;A5-HDRS
MOVE *A8+,A10,L ;A10-PAL TBL
SUBXY A9,A3
SUBXY A9,A4
CALLR DISP_ADD
ADDXY A9,A3
ADDXY A9,A4
JRUC MODLP
MODX:
RETS
***********************************************************************
*********************** D I S P A D D *******************************
* THIS FUNCTION ADDS ALL MODULE BLOCKS IN THE GIVEN RANGE OF MODULE
* RELATIVE COORS TO THE DISPLAY LIST.
* THE BOUNDRIES ARE INCLUDED IN THE GROUP TO ADD.
DISP_ADD:
;*** PARMS:
; B0 - WHICH BAKGROUND INSERT ROUTINE PRIMARY|SECONDARY
; A5 - BACKGROUND HDR TABLE
; A7 - BIT TABLE FOR BLOCK BEING ON DISP LIST
; A9 - MODULE START POSITION Y:X
; A10 - PTR TO PALETTE TABLE FOR NEW BLOCK
; A1 - BACKGROUND BLOCK TABLE
; A2 - END OF BACKGROUND BLOCK TABLE
; A3 - DISP_TL - RELATIVE TO THE MODULE START POS
; A4 - DISP_LR - "
;*** RETURNS NOTHING
;THRASHES A1,A8,A14
MMTM SP,A0,A6,A7,A11
;* FIND FIRST UNIVERSE BLOCK WITH AN X COOR >= A9
MOVX A3,A0
SEXT A0,W
SUBI WIDEST_BLOCK,A0
;A0 - X COORDINATE OF A BLOCK
;A1 - START OF BACKGROUND BLOCK TABLE
;A2 - END OF BLOCK TABLE
CALLR BSRCH1STXB
;A0 IS NOW THE ADDRESS OF A BLOCK
JRZ DADONE ;* NO BLOCKS WITH GTR XCOOR
MOVI BLOCK_SIZE,A6
MOVE A0,A8
SUB A1,A8 ;* SUBTRACT OFF START OF TABLE
SRL 6,A8 ;* DIVIDE BY BLOCK SIZE (64)
ADD A7,A8 ;* A8 - PTR TO BIT WHICH INDICATES BLOCK ON LIST
SUBK 8,A8 ;* AFTER INC A8, USE MOVB *A8 TO LOAD SIGN BIT
SUB A6,A0 ;SUBTRACT BLOCK SIZE
BSCANLP0:
INC A8
ADD A6,A0 ;* GET NEXT BLOCK
;* CHECK IF THERE ARE NO MORE BGND BLOCKS
CMP A2,A0
JRGE DADONE
;* IF BLOCK ALREADY ON DISPLAY LIST TRY AGAIN
MOVB *A8,A11
JRN BSCANLP0
;* CHECK IF X TO BIG
MOVE *A0(MAP_X),A11,W
CMPXY A3,A11
JRXGE BSCAN1 ;* JUMP IF BLOCKX >= TL X
;* LOAD MAP HEADER
MOVE *A0(MAP_HDR),A14,W
SLL 20,A14 ;* ONLY WANT BOTTOM 12 BITS, TOP 4 ARE PAL BITS
SRL 15,A14 ;* LEAVES B9 << 5 == LONG WORD OFFSET
ADD A5,A14 ;* A14 NOW PTS TO BLOCK HDR
;* CHECK IF RIGHT END OF BLOCK HANGS ONTO SCREEN
MOVE *A14,A1,W ;A1 IS NOW THE WIDTH OF THE BLOCK
ADD A11,A1
CMPXY A3,A1 ;* RIGHT END OF BLOCK DOESN'T HANG ON TO SCREEN
JRXLT BSCANLP0 ;* JUMP IF BLOCK X+W < TL X
;* IF YCOOR TO BIG TRY AGAIN
MOVE *A0(MAP_Y),A1,0
SLL 16,A1
CMPXY A1,A4
JRYLT BSCANLP0 ;* JUMP IF BLOCK Y > BR Y
;* IF YCOOR+HEIGHT TO SMALL TRY AGAIN
MOVE *A14(MAP_H),A11,0
SLL 16,A11
ADD A11,A1
CMPXY A3,A1
JRYLT BSCANLP0 ;* JUMP IF BLOCK Y+H < TL Y
MOVE A0,A7
CALLR ADDBLOCK ;THRASHES A1,A14
JRNC BSCANLP0
JRUC DADONE ;* WAS UNABLE TO ADD BLOCK - NO BLOCKS LEFT
BSCAN1:
DEC A8 ;* BIT PTR FOR BLOCK ON DISP LIST
SUB A6,A0 ;SUBTRACT OFF BLOCK SIZE
BSCANLP1:
INC A8
ADD A6,A0 ;GET NEXT BLOCK
;* CHECK IF THERE ARE NO MORE BGND BLOCKS
CMP A2,A0
JRGE DADONE
;* IF BLOCK ALREADY ON DISPLAY LIST TRY AGAIN
MOVB *A8,A11
JRN BSCANLP1
;* IF YCOOR TO BIG TRY AGAIN
MOVE *A0(MAP_Y),A1,W
SLL 16,A1
CMPXY A1,A4
JRYLT BSCANLP1 ;* JUMP IF BLOCK Y > BR Y
;* IF YCOOR+HEIGHT TO SMALL TRY AGAIN
MOVE *A0(MAP_HDR),A14,W
SLL 20,A14 ;* ONLY WANT BOTTOM 12 BITS, TOP 4 ARE PAL BITS
SRL 15,A14 ;* LEAVES B9 << 5 == LONG WORD OFFSET
ADD A5,A14 ;* B9 NOW PTS TO BLOCK HDR
MOVE *A14(MAP_H),A11,W
SLL 16,A11
ADD A11,A1
CMPXY A3,A1
JRYLT BSCANLP1 ;* JUMP IF BLOCK Y+H < TL Y
;* IF XCOOR TO BIG QUIT
MOVE *A0(MAP_X),A1,W
CMPXY A1,A4
JRXLT DADONE ;* JUMP IF BLOCK X > BR X
MOVE A0,A7
CALLR ADDBLOCK
JRNC BSCANLP1
DADONE:
MMFM SP,A0,A6,A7,A11
RETS
***********************************************************************
***********************************************************************
ADDBLOCK:
;* PARMS
; B0 - WHICH INS ROUTINE
; A5 - BASE OF BACKGROUND BLOCK HDR
; A7 - PTR TO BACKGROUND BLOCK
; A8 - PTR TO BIT MAP FOR BLOCK ON DISP LIST
; A9 - MODULE START POSITION Y:X
; A10 - PTR TO PALETTE TABLE FOR NEW BLOCK
;* RETURNS CARRY SET IF GETOBJ FAILS...
;* ALSO DESTROYS A1,A14 BUT THEY ARE USED AS TEMPS IN DISP_ADD
MMTM SP,A0,A2,A3,A4
CALLA GETOBJ
JRZ ADDX
;* SET BIT IN BITMAP FOR BLOCK ON LIST
MOVB *A8,A14
ORI >80,A14
MOVB A14,*A8
MOVE A8,*A0(OPLINK),L ;SET OPLINK TO BE A PTR TO THE DISP LIST BIT
MOVE *A7(MAP_X),A1,L ;A1 YPOS:XPOS OF BLOCK FROM MOD BASE
ADDXY A9,A1 ;ADD IN MODULE BASE POSITION
MOVE A1,*A0(OXPOS),W
SRL 16,A1
MOVE A1,*A0(OYPOS),W
MOVE *A7,A4,W ;A4 - MAP_Z,8:MAP_FLAGS,4:MAP_PAL,4
MOVE A4,A3
ZEXT A3
SRL 8,A3
** SLL 24,A3
** SRL 8,A3
MOVE A3,*A0(OZPOS),W
MOVE *A7(MAP_HDR),A1,W
MOVX A1,A14
SLL 16,A14
SRL 28,A14
SLL 4,A14 ;* BITS 12-15 ARE BITS 4-7 OF PAL INDEX
SLL 20,A1 ;* BITS 0-11 ARE HDR PTR;
SRL 15,A1 ;* A1-LONG WORD OFFSET INTO BLOCK HDR TBL
ADD A5,A1 ;* A1 - PTR TO OIMG HDR - INPUT TO GSAGOF
;A4 - MAP_Z,8:MAP_FLAGS,4:MAP_PAL,4
MOVE A4,A3
SLL 28,A4 ;* LAST FOUR BITS FOR PAL
SRL 28,A4
ADD A14,A4
SLL 5,A4 ;* A4 IS LWORD PTR FROM PAL TBL
ADD A10,A4 ;* ADD IN PAL TBL
MOVE A0,A2 ;SAVE A0
MOVE *A4,A0,L ;* GET PALETTE
CALLA GETBPAL
JRNZ BSETPAL
CLR A0
BSETPAL:
MOVE A0,*A2(OPAL),W
MOVE A2,A0 ;RESTORE A0
MOVI >8002,A4 ;>8000 DMA GO, 2
SRL 4,A3 ;* REMOVE PALETTE BITS
SLL 30,A3
JRC SKIP0 ;* CARRY BIT IS THE TRANSPARENCY BIT
ADDK 1,A4
SKIP0:
SRL 26,A3 ;* LINE UP FLIP H,V BITS
ADD A3,A4 ;A4 - FLAGS FOR GSAGOF
MOVE A1,*A0(OIMG),L
*A1=DATA BLOCK POINTER
*A4=OBJECT FLAGS
calla BKGSAGOF ;USES ISAG->20 FOR ISAG
; CALLA GSAGOF
*A2=RETURNED WITH NEW OSIZE
*A3=RETURNED WITH NEW SAG
*A4=RETURNED WITH NEW OFFSET:OFLAGS
MOVE A0,A1
ADDI OSIZE+>20,A1
MMTM A1,A2,A3,A4 ;STUFF OSIZE,OSAG,OFFSET,OFLAGS
MOVE *A0(OZPOS),A4 ;TURMELL
CMPI 80,A4
JRC REGA
SUBI 80,A4
SLL 5,A4
ADDI ZLIST,A4
MOVE *A4,A4,L
CALL A4
;PLACE THIS OBJECT ONTO OBJLST!
CALLA INSOBJ
CLRC
MMFM SP,A0,A2,A3,A4
RETS
REGA CALL B0
;INSERT ONTO BAKLST
CLRC
MMFM SP,A0,A2,A3,A4
RETS
ADDX: ;FAILURE TO GET OBJECT
SETC
MMFM SP,A0,A2,A3,A4
RETS
*****************************************************************************
;80
ZLIST
.LONG SOON,SOON,SOON,SOON,SOON,SOON,SOON,SOON,SOON,SOON
;90
.LONG GPIT,STEEL,PITWAL,JDWN,STRTRN,JDWNL,T72,BARL,RCTR,WALKIE
.LONG CRATE,HSTGD,HSTGC,LMINE,ADOOR,AWALL,TRUNK,UPTOP,FLAG,STAT
.LONG HSTGA,HSTGB,FLAG2,PEOPLE,TYPARM,GENLARM,GENRARM,GENHD,PROF
.LONG PROFI,PROFM
SOON: RETS
GPIT
;SAND BAGS
;COULD BE GUNPIT,VGUNPIT, OR GUNPIT FLIPPED, OR VGUNPIT FLIPPED
MOVE *A0(OFLAGS),A4
ORI M_PIXSCAN,A4
MOVE A4,*A0(OFLAGS)
MOVI CLSNEUT|TYPGATE|SUBLAY,A4 ;WILL BOUNCE OFF OF
MOVE A4,*A0(OID),W
MOVI 69,A4 ;STAND IS AT 70
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
CREATE 0,STRT_GPIT
MMFM SP,A0,A1,A8,A7,A11
RETS
STEEL
;STEEL DOOR OVER PITS
MOVI 69,A4
MOVE A4,*A0(OZPOS),W
MOVE *A0(OFLAGS),A4
ORI M_NOCOLL,A4
MOVE A4,*A0(OFLAGS)
MOVI CLSDEAD,A4 ;WILL KILL MYSELF
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
CREATE 0,ANI_STEEL
MMFM SP,A0,A1,A8,A7,A11
RETS
PITWAL
;SIDES OF PIT
MOVE *A0(OFLAGS),A4
ORI M_NOCOLL,A4
MOVE A4,*A0(OFLAGS)
;TYPE TRUNK, BUT COLLIDE OFF! SO IT GETS DELETED WHEN OFF SCRN
MOVI CLSNEUT|TYPTRUNK,A4
MOVE A4,*A0(OID),W
MOVI 69,A4
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
RETS
STRTRN
;START THIS STATIONARY SOLDIER RUNNING DOWN SCREEN
MMTM SP,A0,A1,A7,A8,A9,A11
MOVI CLSENMY|TYPHULK,A4
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI 159,A4
MOVE A4,*A0(OZPOS),W
MOVE A0,A8
CREATE HULKPID,SOLDR
MMFM SP,A0,A1,A7,A8,A9,A11
RETS
JDWN
;STRAIGHT DOWN
MMTM SP,A0,A1,A7,A8,A9,A11
CALLR JLP
CREATE HULKPID,SOLDRD
MMFM SP,A0,A1,A7,A8,A9,A11
RETS
JDWNL
;JUMP DOWN TO LEFT
MMTM SP,A0,A1,A7,A8,A9,A11
CALLR JLP
CREATE HULKPID,SOLDRDL
MMFM SP,A0,A1,A7,A8,A9,A11
RETS
JLP
MOVI CLSDEAD,A4 ;ENMY|TYPHULK,A4
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI 300,A4 ;159
MOVE A4,*A0(OZPOS),W
MOVE A0,A8
RETS
T72
;TANK APPEARS
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
CREATE T72PID,TANKON
MOVE A0,*A8(OPLINK),L
MMFM SP,A0,A1,A8,A7,A11
MOVI CLSENMY|TYPT72,A4
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI 159,A4 ;SAME AS BULLETS
MOVE A4,*A0(OZPOS),W
RETS
WALKIE
;GI WALKIE TALKIE
CALLR VELFLG
MOVI 268,A4 ;238
MOVE A4,*A0(OZPOS),W
MOVE A0,@KPLARM,L
RETS
PROFI
;RIGHT SIDE GUN FOR GI
CALLR VELFLG
MOVI 268,A4 ;238
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_EYES
MMFM SP,A0,A1,A7,A8,A11
RETS
PROFM
;GI MOUTH
CALLR VELFLG
MOVI 268,A4 ;238
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_MTH
MMFM SP,A0,A1,A7,A8,A11
RETS
PROF
;PROFESSOR
;GI
CALLR VELFLG
MOVI 268,A4 ;238
MOVE A4,*A0(OZPOS),W
MOVE @INTRO,A4
JRZ RTY
;GI INTRO
MOVI GIPID,A4
MOVE A4,*A0(OID)
RTY RETS
VELFLG
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVE *A0(OFLAGS),A4
ORI M_NOCOLL,A4
MOVE A4,*A0(OFLAGS)
MOVI CLSNEUT|TYPNEUT,A4
MOVE A4,*A0(OID),W
RETS
TYPARM
CALLR VELFLG
MOVI 07FD2H,A4
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_TYP
MMFM SP,A0,A1,A7,A8,A11
RETS
GENLARM
CALLR VELFLG
MOVI 07FD2H,A4
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_LARM
MMFM SP,A0,A1,A7,A8,A11
RETS
GENRARM
CALLR VELFLG
MOVI 07FD2H,A4
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_RARM
MMFM SP,A0,A1,A7,A8,A11
RETS
GENHD
CALLR VELFLG
MOVI 07FD2H,A4
MOVE A4,*A0(OZPOS),W
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_HD
MMFM SP,A0,A1,A7,A8,A11
RETS
PEOPLE
;OVERHEAD PEOPLE TORSO TYPE STUFF
CALLR VELFLG
MOVI 07FD2H,A4
MOVE A4,*A0(OZPOS),W
RETS
HSTGA:
;TYPE HSTG!
MMTM SP,A0,A1,A8,A7,A9,A11
CLR A9 ;HOSTAGE NUMBER FOR ANI
MOVI CLSNEUT|TYPHSTG|SUBGUYA,A4
INHSTG
PUSH A0
MOVI 300,A0 ;350
CALLA RANDPER
PULL A0
JRNC OKHSTG
MOVE A0,A8
CREATE 0,FAKEIMG
MMFM SP,A0,A1,A8,A7,A9,A11
RETS
OKHSTG
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI 140,A4 ;90
MOVE A4,*A0(OZPOS),W
MOVE *A0(OYPOS),A4
SUBK 13,A4
MOVE A4,*A0(OYPOS)
MOVE *A0(OXPOS),A4
ADDK 5,A4
MOVE A4,*A0(OXPOS)
MOVE A0,A8
CREATE HSTGPID,ANI_HSTG
MMFM SP,A0,A1,A8,A7,A9,A11
RETS
HSTGB:
MMTM SP,A0,A1,A8,A7,A9,A11
MOVK 1,A9
MOVI CLSNEUT|TYPHSTG|SUBGUYB,A4
JRUC INHSTG
HSTGC:
MMTM SP,A0,A1,A8,A7,A9,A11
MOVK 2,A9
MOVI CLSNEUT|TYPHSTG|SUBGUYC,A4
JRUC INHSTG
HSTGD:
MMTM SP,A0,A1,A8,A7,A9,A11
MOVK 3,A9
MOVI CLSNEUT|TYPHSTG|SUBGUYD,A4
JRUC INHSTG
LMINE:
PUSH A0
MOVI 800,A0
CALLA RANDPER
PULL A0
JRC OKMINE
;KILL OFF THIS MINE 20% OF TIME!
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE 0,FAKEIMG
MMFM SP,A0,A1,A7,A8,A11
RETS
FAKEIMG:
MOVE A8,A0
CALLA DELOBJ
DIE
OKMINE MOVI CLSNEUT|TYPMINE,A4
MOVE A4,*A0(OID),W
MOVI 69,A4 ;SAME AS BULLETS
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
RETS
STAT:
;STATIC FOR VWSCRN
;TYPE TRUNK, BUT COLLIDE OFF!
MOVI CLSENMY|TYPGATE,A4 ;STATIC
MOVE A4,*A0(OID),W
MOVI 279,A4 ;239
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MMTM SP,A0,A1,A7,A8,A11
MOVE A0,A8
CREATE INTROPID,ANI_STAT
MMFM SP,A0,A1,A7,A8,A11
RETS
ADOOR:
;DOOR/GATE IMAGES
;TYPE TRUNK, BUT COLLIDE OFF!
MOVI CLSENMY|TYPGATE,A4
MOVE A4,*A0(OID),W
MOVI 140,A4
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVE @TARGET_NUM,A4
JRNZ RETNO
;PLACE DROP BOMB HERE MESSAGE DOWN!
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
MOVI DROPPID,A0
CLR A1
NOT A1
CALLA EXISTP
JRNZ RETY
CREATE DROPPID,DROPBMB
RETY MMFM SP,A0,A1,A8,A7,A11
RETNO
RETS
AWALL:
;OVERHEAD IMAGES LOWER THAN MAX (VWSCRN STUFF)
MOVE *A0(OFLAGS),A4
ORI M_NOCOLL,A4
MOVE A4,*A0(OFLAGS)
;TYPE TRUNK, BUT COLLIDE OFF!
MOVI CLSNEUT|TYPTRUNK,A4
MOVE A4,*A0(OID),W
MOVI 237,A4
MOVE A4,*A0(OZPOS),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
RETS
FLAG2
MOVI 237,A4 ;FOR UNDER STATIC 238
JRUC FAG2
FLAG:
MMTM SP,A0,A1
CREATE 0,SEND_1ST
MMFM SP,A0,A1
MOVI 282,A4
FAG2 MOVE A4,*A0(OZPOS),W
CALLR VELFLG
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
MOVI 4,A0
MOVE A0,@ARWOFF ;BLINK ARROW X MORE TIMES THEN KILL!
CREATE FLGPID,ANI_FLAG
MMFM SP,A0,A1,A8,A7,A11
RETS
SEND_1ST:
;SEND GROUP OF HULKS UP AT PLAYER NEAR GATE
MOVK 4,A8
SEND1
SLEEP >40
MOVE @WORLDTLY,A0,L
ADDI [275,0],A0
MOVE @WORLDTLX,A9,L
SRL 16,A9
ADDI 170,A9
MOVY A0,A9
MOVK 1,A10 ;GO UP
PUSH A8
CALLA SEND_GROUP
PULL A8
DSJ A8,SEND1
DIE
BARL:
MOVI CLSNEUT|TYPCRTE|SUBBRL,A4
JRUC C2
CRATE:
MOVI CLSNEUT|TYPCRTE|SUBCRT,A4
C2 MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
CREATE CMAN,CRATEMAN
MOVE A0,*A8(OPLINK),L
MMFM SP,A0,A1,A8,A7,A11
MOVE A4,*A0(OID),W
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI 159,A4 ;SAME AS BULLETS
MOVE A4,*A0(OZPOS),W
RETS
TRUNK:
;TREE TRUNKS, ITEMS TO COLLIDE WITH
CLR A4
MOVE A4,*A0(OXVEL),L
MOVE A4,*A0(OYVEL),L
MOVI CLSNEUT|TYPTRUNK,A4
MOVE A4,*A0(OID),W
MOVI 159,A4 ;SAME AS BULLETS
MOVE A4,*A0(OZPOS),W
RETS
RCTR
;REACTOR!
MMTM SP,A0,A1,A8,A7,A11
MOVE A0,A8
CREATE BLOWPID,BLOW_RCTR
;OPEN SECRET PATH
CREATE DROPPID,SPATH
MMFM SP,A0,A1,A8,A7,A11
JRUC AWALL
UPTOP:
;OVERHEAD IMAGES
CALLR VELFLG
;TYPE TRUNK, BUT COLLIDE OFF!
MOVI CLSNEUT|TYPTRUNK,A4
MOVE A4,*A0(OID),W
MOVI 281,A4 ;240
MOVE A4,*A0(OZPOS),W
RETS
************************ D I S P D E L *****************************
* THIS FUNCTION DELETES ALL OBJS OUTSIDE THE GIVEN RANGE
* OF COORS FROM THE DISPLAY LIST.
* THE BOUNDRIES ARE NOT INCLUDED IN THE GROUP TO DELETE.
DISP_DEL:
*** PARMS:
; A8 - BAK LIST
; A3 - DISP_TL
; A4 - DISP_LR
*** RETURNS NOTHING
;THRASHES A0,A6,A7,A8,A9 ;ALL OF WHICH ARE PUSHED BY CALLER
DEL_LOOP:
MOVE A8,A9 ; PTR TO PREV IN A9
MOVE *A9,A8,L ; PTR TO NEXT IN A8
JRZ DEL_DONE ; QUIT IF AT END OF LIST
;IF X > XMAX CONTINUE
MOVE *A8(OXPOS),A7,W
CMPXY A7,A4
JRXLT DEL_IT ;* JUMP IF BR X < BLOCK X
;IF Y > YMAX CONTINUE
MOVE *A8(OYPOS),A0,W
SLL 16,A0
CMPXY A0,A4
JRYLT DEL_IT ;* JUMP IF BR Y < BLOCK Y
MOVE *A8(OIMG),A1,L
;IF X+WIDTH < XMIN CONTINUE
MOVE *A1,A6,W ;A6 BLOCK WIDTH
ADD A6,A7
CMPXY A3,A7
JRXLT DEL_IT ;* JUMP IF TL X > BLOCK X+W
;IF Y+HEIGHT < YMIN CONTINUE
MOVE *A1(MAP_H),A7,0 ;A7 BLOCK HEIGHT
SLL 16,A7
ADD A7,A0
CMPXY A3,A0
JRYLT DEL_IT ;* JUMP IF TL Y > BLOCK Y+H
JRUC DEL_LOOP
DEL_IT: ;* DELETE THE OBJ
;* FREE THE PALETTE
MOVE *A8(OPAL),A0,W
JRZ NOFREEP
CALLA FREEPAL
NOFREEP:
;* UNSET THE ON DISPLAY LIST BIT
MOVE *A8(OPLINK),A0,L
MOVB *A0,A7
ANDI >7F,A7
MOVB A7,*A0
MOVE *A8,*A9,L ; PUT NEXT LINK IN PREV OBJ
MOVE @OFREE,A0,L
MOVE A0,*A8,L
MOVE A8,@OFREE,L ; RETURN DELETED BLOCK TO FREE STACK
MOVE A9,A8 ;A1- POINTS TO LAST OBJ
JRUC DEL_LOOP
DEL_DONE:
RETS
.END