Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- SECTION code,CODE
- JUMPPTR Start
- INTERLACED = 0
- SCREEN_W = 320
- SCREEN_H = 256
- SCREEN_D = 5
- SCREEN_COLORS = 1<<SCREEN_D
- SCREEN_BYPL = SCREEN_W/8
- SCREEN_BYWIDTH = SCREEN_BYPL*SCREEN_D
- SCREEN_X_MARGIN = 128
- NUM_SAS = 4
- SAS_W = 48
- SAS_VISW = 32
- SAS_H = 44
- SAS_BYTES = 4+4*SAS_H
- SAS_ATTACH = NUM_SAS*SAS_BYTES+4
- GRENADE_W = 16
- GRENADE_H = 21
- GRENADE_BYTES = 4+4*GRENADE_H
- GRENADE_ATTACH = GRENADE_BYTES+4
- BOOM_H = 16
- DOOR_W = 80
- DOOR_VISW = 64
- DOOR_H = 128
- PELLET_W = 16
- PELLET_H = 16
- AUDIO_LEFT_X = 40
- NUM_AK47 = 6
- NUM_FLOOR_WALK = 6
- NUM_GRASS_WALK = 6
- NUM_MP5 = 6
- ; audio_t structure
- audio_t.pointer = 0
- audio_t.length = 4
- audio_t = 8
- ; copper_t structure
- copper_t.bitplanes = 0
- copper_t.interlaced = 1
- copper_t.bpl1mod = 2
- copper_t.bpl2mod = 4
- copper_t.diwstrt = 6
- copper_t.diwstop = 8
- copper_t.ddfstrt = 10
- copper_t.ddfstop = 12
- copper_t.wait = 14
- copper_t = 16
- FPS = 50
- pusha: MACRO
- movem.l d0-a6,-(sp)
- ENDM
- popa: MACRO
- movem.l (sp)+,d0-a6
- ENDM
- pushnr: MACRO
- movem.l d1-a6,-(sp)
- ENDM
- popnr: MACRO
- movem.l (sp)+,d1-a6
- ENDM
- ; Args:
- ; \1 - address to poke to copper
- ; \2 - copper register listing start where to poke
- pokecopper: MACRO
- move.w \1,6(\2)
- swap \1
- move.w \1,2(\2)
- swap \1
- ENDM
- audio_off: MACRO
- move #$f,DMACON(a6)
- ENDM
- ; Args:
- ; \1 - address to store
- ; \2 - address *where* to store
- store_address: MACRO
- lea \1,a0
- lea \2,a1
- move.l a0,(a1)
- ENDM
- delayed_part: MACRO
- move \1,SleepPartTime
- store_address \2,SleepPartNext(pc)
- store_address SleepPart(pc),PartPointer(pc)
- ENDM
- next_part: MACRO
- store_address \1,PartPointer(pc)
- ENDM
- ; Args:
- ; \1 - address register where to store the bullet address
- ; \2 - data register where the bullet index is
- bullet_at_list: MACRO
- lea BulletList(pc),\1
- mulu #bullet_t,\2
- add.l \2,\1
- ENDM
- fullscreen_part: MACRO
- bsr APlayNullAll
- bsr LoadFullScreenCopper
- bsr LoadScreenToCopper
- ENDM
- INCLUDE "hardware.s"
- *** MiniWrapper by Photon ***
- Start: move.l 4.w,a6 ;Exec library base address in a6
- sub.l a4,a4
- btst #0,297(a6) ;68000 CPU?
- beq.s .yes68k
- lea .GetVBR(PC),a5 ;else fetch vector base address to a4:
- jsr -30(a6) ;enter Supervisor mode
- *--- save view+coppers ---*
- .yes68k:lea .GfxLib(PC),a1 ;either way return to here and open
- jsr -408(a6) ;graphics library
- tst.l d0 ;if not OK,
- beq.s .quit ;exit program.
- move.l d0,a5 ;a5=gfxbase
- move.l a5,a6
- move.l 34(a6),-(sp)
- sub.l a1,a1 ;blank screen to trigger screen switch
- jsr -222(a6) ;on Amigas with graphics cards
- *--- save int+dma ---*
- lea $dff000,a6
- bsr.s WaitEOF ;wait out the current frame
- move.l $1c(a6),-(sp) ;save intena+intreq
- move.w 2(a6),-(sp) ;and dma
- move.l $6c(a4),-(sp) ;and also the VB int vector for sport.
- bsr.s AllOff ;turn off all interrupts+DMA
- *--- call demo ---*
- movem.l a4-a6,-(sp)
- bsr.w Demo ;call our demo \o/
- movem.l (sp)+,a4-a6
- *--- restore all ---*
- bsr.s WaitEOF ;wait out the demo's last frame
- bsr.s AllOff ;turn off all interrupts+DMA
- move.l (sp)+,$6c(a4) ;restore VB vector
- move.l 38(a5),$80(a6) ;and copper pointers
- move.l 50(a5),$84(a6)
- addq.w #1,d2 ;$7fff->$8000 = master enable bit
- or.w d2,(sp)
- move.w (sp)+,$96(a6) ;restore DMA
- or.w d2,(sp)
- move.w (sp)+,$9a(a6) ;restore interrupt mask
- or.w (sp)+,d2
- bsr.s IntReqD2 ;restore interrupt requests
- move.l a5,a6
- move.l (sp)+,a1
- jsr -222(a6) ;restore OS screen
- *--- close lib+exit ---*
- move.l a6,a1 ;close graphics library
- move.l 4.w,a6
- jsr -414(a6)
- .quit: moveq #0,d0 ;clear error return code to OS
- rts ;back to AmigaDOS/Workbench.
- .GetVBR:dc.w $4e7a,$c801 ;hex for "movec VBR,a4"
- rte ;return from Supervisor mode
- .GfxLib:dc.b "graphics.library",0,0
- WaitEOF: ;wait for end of frame
- bsr.s WaitBlitter
- move.w #$138,d0
- WaitRaster: ;Wait for scanline d0. Trashes d1.
- .l: move.l 4(a6),d1
- lsr.l #1,d1
- lsr.w #7,d1
- cmp.w d0,d1
- bne.s .l ;wait until it matches (eq)
- rts
- AllOff: move.w #$7fff,d2 ;clear all bits
- move.w d2,$96(a6) ;in DMACON,
- move.w d2,$9a(a6) ;INTENA,
- IntReqD2:
- move.w d2,$9c(a6) ;and INTREQ
- move.w d2,$9c(a6) ;twice for A4000 compatibility
- rts
- WaitBlitter: ;wait until blitter is finished
- tst.w (a6) ;for compatibility with A1000
- .loop: btst #6,2(a6)
- bne.s .loop
- rts
- *** End of MiniWrapper by Photon ***
- Demo:
- pusha
- bsr InitGeneric
- bsr StartPart1
- move.l #VBint,$6c(a4)
- move #$e020,INTENA(a6) ; Enable master, level 6 and 3 IRQ
- .waitmouse:
- tst Quit
- bne .quit
- btst #6,CIAAPRA
- bne .waitmouse
- .quit:
- popa
- rts
- Quit:
- dc.w 0
- VBint:
- pusha
- btst #5,INTREQR+1(a6)
- beq .not_vblank
- btst #2,POTGOR(a6)
- beq .paused
- jsr Frame(pc)
- move #$20,INTREQ(a6)
- move #$20,INTREQ(a6)
- .paused:
- .not_vblank:
- popa
- rte
- Frame:
- pusha
- move.l PartPointer(pc),a0
- jsr (a0)
- popa
- rts
- PartPointer:
- dc.l 0
- SleepPart:
- ; A generic sleep part that waits for a while and then move on to the
- ; next part as specified through SleepPartTime and SleepPartNext.
- pusha
- ; Countdown and do nothing if we haven't reached the finish yet.
- lea SleepPartTime(pc),a0
- tst (a0)
- bne .sleep_more
- ; We've slept enough. It's time to move to the next part.
- lea SleepPartNext(pc),a1
- move.l (a1),d0
- clr.l (a1)
- tst d0
- bne .good_pointer
- lea NoopPart(pc),a1 ; avoid crash by forcing no-op part
- move.l a1,d0
- .good_pointer:
- ; Load the next part and reset the variables.
- lea PartPointer(pc),a2
- move.l d0,(a2)
- clr (a0)
- bra .done
- .sleep_more:
- subq #1,(a0)
- .done:
- popa
- rts
- SleepPartTime:
- dc.w 0 ; 1s = Vertical Refresh Rate
- SleepPartNext:
- dc.l 0
- NoopPart:
- ; A no-op part that does nothing forever.
- audio_off
- rts
- ;;
- ;; Generic - stuff for the whole demo
- ;;
- InitGeneric:
- pusha
- bsr LoadScreenToCopper
- ; Load sprites
- bsr InitSasSprite
- lea CopperSprite,a0
- bsr PokeCopperSasSprite
- lea CopperSprite+8*4,a0
- moveq #4,d0
- bsr PokeCopperNullSprite
- lea CopperSprite6,a0
- move.l #BulletSprite,d0
- move.l d0,CurrentBulletSprite
- pokecopper d0,a0
- move #NUM_BULLETS_MAX,CurrentNumBulletsMax
- bsr InitGrenadeSprite
- ; As there are no bullets yet, this will clear the bullet sprite.
- bsr PaintBullets
- bsr AdjustDoorMask
- ; Load audio lists
- bsr InitFloorWalkList
- bsr InitGrassWalkList
- popa
- rts
- AdjustDoorMask:
- ; Write #$ff to all the bits that are non-zero.
- ; This results in the mask also covering the "transparent" pixels.
- pusha
- lea DoorMask,a0
- move #DoorMask_e-DoorMask,d0
- .loop:
- move.b (a0),d1
- tst.b d1
- beq.s .skip
- or.b #$ff,d1
- .skip:
- move.b d1,(a0)+
- dbf d0,.loop
- popa
- rts
- PokeCopperSasSprite:
- ; Args:
- ; a0 - copper list where to load
- pusha
- ; Load SAS head as a sprite.
- ; This is an attached sprite where the attachment is under the same
- ; label and starts immediately after the first sprite.
- move.l #SasLeft,d0
- pokecopper d0,a0
- add.l #SAS_ATTACH,d0
- addq.l #8,a0
- pokecopper d0,a0
- move.l #SasRight,d0
- addq.l #8,a0
- pokecopper d0,a0
- add.l #SAS_ATTACH,d0
- addq.l #8,a0
- pokecopper d0,a0
- popa
- rts
- PokeCopperNullSprite:
- ; Args:
- ; a0 - copper list where to load
- ; d0 - how many
- pusha
- move.l #NullSprite,d1
- subq #1,d0
- .nullspr_load:
- pokecopper d1,a0
- addq.l #8,a0
- dbf d0,.nullspr_load
- popa
- rts
- InitSasSprite:
- pusha
- ; Attach SAS sprites
- move.l #$80,d0
- move.l #NUM_SAS-1,d1
- lea SasLeft,a0
- lea SasRight,a1
- move.l a0,a2
- add.l #SAS_ATTACH,a2
- move.l a1,a3
- add.l #SAS_ATTACH,a3
- .attach_sas:
- move.l d0,(a0)
- move.l d0,(a1)
- move.l d0,(a2)
- move.l d0,(a3)
- add.l #SAS_BYTES,a0
- add.l #SAS_BYTES,a1
- add.l #SAS_BYTES,a2
- add.l #SAS_BYTES,a3
- dbf d1,.attach_sas
- popa
- rts
- InitGrenadeSprite:
- ; Grenayd!
- pusha
- lea GrenadeSprite,a0
- move.l #$80,(a0)
- add.l #GRENADE_ATTACH,a0
- move.l #$80,(a0)
- popa
- rts
- ;;
- ;; Part1
- ;;
- ; Bitplanes in this picture are saved one after another - not
- ; interleaved. LOGO_BYPL is therefore not calculated by lines
- ; but is the area of the whole picture.
- LOGO_W = 304
- LOGO_H = 95
- LOGO_D = 3
- LOGO_COLORS = 8
- LOGO_BYPL = LOGO_W/8*LOGO_H
- LOGO_MARGIN = (SCREEN_W-LOGO_W)/2
- FLASH_TICKS = 50<<16
- FLASH_TICKPERIOD = 25<<16
- FLASH_STAGE_WHITE = 0
- FLASH_STAGE_MUSIC = 24
- FLASH_STAGE_BLACK = FLASH_STAGE_MUSIC+1
- FLASH_STAGE_DONE = FLASH_STAGE_BLACK+50
- LOGO_FLASH_TICKS = 50<<16
- LOGO_FLASH_TICKPERIOD = 25<<16
- StartPart1:
- pusha
- ; Play null audio on all channels to prevent sound from coming out
- ; as soon as we start.
- bsr APlayNullAll
- ; Load the first part
- next_part Part1(pc)
- ; Load the logo into the copper list
- lea P1CopperLogo,a0
- lea Logo,a1
- move.l a1,d1
- moveq #LOGO_D-1,d0
- .loop:
- swap d1
- move d1,2(a0)
- swap d1
- move d1,6(a0)
- addq #8,a0
- add.l #LOGO_BYPL,d1
- dbf d0,.loop
- ; Enable copper and bitplane DMA and load the copper list
- move #$838f,DMACON(a6)
- move.l #P1Copper,COP1LCH(a6)
- popa
- rts
- Part1:
- Part1a_Flash:
- pusha
- move.l FlashCountdown(pc),d7
- sub.l #FLASH_TICKPERIOD,d7
- bpl .no_flash
- ; Transit screen color
- lea FlashColorTable(pc),a0
- move.l a0,a1
- move #LOGO_COLORS-1,d1
- move FlashStage(pc),d6
- cmp.w #FLASH_STAGE_WHITE,d6
- beq .flash_white
- cmp.w #FLASH_STAGE_MUSIC,d6
- beq .flash_music
- cmp.w #FLASH_STAGE_BLACK,d6
- beq .flash_black
- cmp.w #FLASH_STAGE_DONE,d6
- beq .flash_done
- addq #1,FlashStage
- bra .no_flash
- .flash_white:
- add #$0111,(a0)+
- dbf d1,.flash_white
- cmp.w #$0fff,(a1)
- bne .do_flash
- addq #1,FlashStage
- bra .do_flash
- .flash_music:
- bsr APlayIntro
- addq #1,FlashStage
- bra .no_flash
- .flash_black:
- addq #2,a0
- subq #1,d1
- .flash_black_loop:
- sub #$0111,(a0)+
- dbf d1,.flash_black_loop
- tst.w 2(a1)
- bne .do_flash
- addq #1,FlashStage
- bra .do_flash
- .flash_done:
- lea Part1b_Logo(pc),a0
- move.l a0,PartPointer
- bra .no_flash
- .do_flash:
- move.l a1,a0
- lea P1CopperColor,a1
- move #LOGO_COLORS,d0
- bsr PokeCopperWords
- move.l #FLASH_TICKS,d7
- .no_flash:
- move.l d7,FlashCountdown
- popa
- rts
- .flash_intermission_countdown:
- dc.w 4
- FlashColorTable:
- dcb.w LOGO_COLORS,0
- FlashStage:
- dc.w 0
- FlashCountdown:
- dc.l FLASH_TICKPERIOD-1
- Part1b_Logo:
- pusha
- ; Transit color to show the logo
- move.l .transit_countdown(pc),d7
- sub.l #LOGO_FLASH_TICKPERIOD,d7
- bpl .notransit
- ; Fade
- lea LogoDisplayColors(pc),a0
- lea LogoColors(pc),a1
- move #LOGO_COLORS,d0
- move #$0111,d2
- bsr ColorTableFadeTo
- ; Check if it's time to move to the next part.
- ; Registers already have correct values so let's reuse that.
- move d0,d1
- bsr MemCmp
- move d0,d6
- ; Poke new colors to copper
- ; a0 has the correct value
- lea P1CopperColor,a1
- move #LOGO_COLORS,d0
- bsr PokeCopperWords
- ; Is it time?
- cmp #LOGO_COLORS,d6
- bne .no_next_part
- ; Load next part
- delayed_part #FPS*3,Part1c_FadeOut(pc)
- .no_next_part:
- move.l #LOGO_FLASH_TICKS,d7
- .notransit:
- move.l d7,.transit_countdown
- popa
- rts
- .transit_countdown:
- dc.l LOGO_FLASH_TICKPERIOD-1
- Part1c_FadeOut:
- pusha
- lea LogoDisplayColors(pc),a0
- lea P1CopperColor,a1
- move #LOGO_COLORS,d0
- bsr DimScreen
- lea LogoDisplayColors(pc),a0
- lea BlackColors(pc),a1
- move.l #LOGO_COLORS,d1
- bsr MemCmp
- cmp #LOGO_COLORS,d0
- bne .no_next_part
- audio_off
- delayed_part #4,StartPart2(pc)
- bsr StartPart2
- .no_next_part:
- popa
- rts
- LogoDisplayColors:
- dc.w $0fff
- dcb.w LOGO_COLORS-1,$0000
- LogoColors:
- dc.w $0100,$0510,$0321,$0f01
- dc.w $0842,$0e74,$0fa5,$0fd5
- BlackColors:
- dcb.w 32,0
- APlayIntro:
- pusha
- lea AIntro,a0
- move #(AIntro_e-AIntro)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- move #1,d1
- bsr APlay11Khz
- popa
- rts
- ;;
- ;; Part2
- ;;
- GRASS_W = 320
- GRASS_H = 256
- GRASS_D = 4
- GRASS_COLORS = 1<<GRASS_D
- GRASS_BYPL = 320/8
- GRASS_BYWIDTH = GRASS_BYPL*GRASS_D
- P2Color:
- dc.w $0331,$0341,$0443,$0553
- dc.w $0563,$0664,$0665,$0785
- dc.w $0784,$0886,$0987,$08a5
- dc.w $08a7,$0bba,$0ac7,$0bb9
- dc.w $00ff,$0111,$0222,$0333
- dc.w $0444,$0555,$0666,$0866
- dc.w $0777,$0888,$0bab,$0000
- dc.w $0000,$0000,$0000,$0000
- LoadP2Copper:
- pusha
- sub #copper_t,sp
- move.l sp,a0
- bsr InitCopperT
- move.b #GRASS_D,copper_t.bitplanes(a0)
- move #GRASS_BYWIDTH-GRASS_BYPL,copper_t.bpl1mod(a0)
- move #GRASS_BYWIDTH-GRASS_BYPL,copper_t.bpl2mod(a0)
- bsr LoadCopper
- bsr LoadScreenToCopper
- ; Load colors
- lea P2Color(pc),a0
- bsr LoadColorsToCopper
- add #copper_t,sp
- popa
- rts
- StartPart2:
- pusha
- bsr LoadP2Copper
- ; Part 2 is the first screen that's not baked into CHIP mem section.
- ; We will copy it to the screen using the CPU. Blitter cannot be
- ; used because the source is not in chip mem.
- lea P2Scene,a0
- lea Screen,a1
- move.l #(P2Scene_e-P2Scene)/4,d0
- .screen_copy:
- move.l (a0)+,(a1)+
- dbf d0,.screen_copy
- ; Shut off all sound
- bsr APlayNullAll
- ; Enable copper and sprites
- move #$7fff,DMACON(a6)
- move #$87af,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- ; Set frame pointer to part 2
- delayed_part #FPS,Part2(pc)
- popa
- rts
- Part2:
- Part2a:
- ; 4 SAS troopers come in from the right, they move into the screen
- ; X-unevenly and stop somewhere near the right edge X-evenly.
- pusha
- _SAS_DST_X = 256
- move.l #_SAS_DST_X,d1
- bsr StepAllSasLeftToX
- move d0,d7
- ; play step sound
- move SasGrassWalkVolume(pc),d2
- cmp #$100,d2
- bge .max_volume
- addq #1,d2
- move d2,SasGrassWalkVolume
- .max_volume:
- lsr #2,d2
- cmp #1,d7
- beq .one_sas_moving
- tst d7
- beq .all_stop
- bsr APlayGrassWalkManyRight
- bra .done
- .one_sas_moving:
- bsr APlayGrassWalkOneRight
- bra .done
- .all_stop:
- bsr APlayNullAll
- delayed_part #FPS,Part2b(pc)
- .done:
- popa
- rts
- Part2b:
- pusha
- lea ABriefing,a0
- move.l #(ABriefing_e-ABriefing)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- move #1,d1
- bsr APlay11Khz
- delayed_part #FPS*2,Part2b_stop_audio(pc)
- popa
- rts
- Part2b_stop_audio:
- pusha
- bsr APlayNullAll
- delayed_part #FPS/2,Part2c_gogogo
- popa
- rts
- Part2c_gogogo:
- pusha
- lea ASasGoGoGo,a0
- move.l #(ASasGoGoGo_e-ASasGoGoGo)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- move #1,d1
- bsr APlay11Khz
- delayed_part #FPS,Part2d_move_out
- popa
- rts
- Part2d_move_out:
- pusha
- _SAS_DST_X_2D = -64
- clr.l d7
- move.l #_SAS_DST_X_2D,d1
- move .sas_moveout_countup(pc),d6
- addq #1,d6
- ; Move all SAS troopers, but with some irregular delay
- cmp #2,d6
- blt .sas_1
- clr d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_1:
- cmp #8,d6
- blt .sas_2
- moveq.l #1,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_2:
- moveq.l #2,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_3:
- cmp #5,d6
- blt .sas_e
- moveq.l #3,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_e:
- move d6,.sas_moveout_countup
- ; play step sound
- move SasPos0(pc),d0
- cmp #_SAS_DST_X_2D,d0
- ble .moved_out
- cmp #AUDIO_LEFT_X,d0
- blt .all_move_on_left
- .all_move_in_center:
- move #64,d2
- cmp #1,d7
- beq .one_sas_moving
- bsr APlayGrassWalkManyBoth
- bra .done
- .all_move_on_left:
- bsr APlayNullRight
- move SasGrassWalkVolume(pc),d2
- subq #1,d2
- move d2,SasGrassWalkVolume
- lsr #2,d2
- bsr APlayGrassWalkManyLeft
- bra .done
- .one_sas_moving:
- bsr APlayGrassWalkOneBoth
- bra .done
- .moved_out:
- bsr APlayNullAll
- delayed_part #5,StartPart3(pc)
- .done:
- popa
- rts
- .sas_moveout_countup:
- dc.w 0
- ;;
- ;; Part3
- ;;
- P3_PASKUDNY_X = 89
- P3_PASKUDNY_Y = 174
- P3_WIESNIAK_X = 92
- P3_WIESNIAK_Y = 14
- P3_DOOR_X = 0
- P3_DOOR_Y = 64
- PASKUDNY_W = 64
- PASKUDNY_VISW = 38
- PASKUDNY_H = 44
- WIESNIAK_W = 48
- WIESNIAK_VISW = 32
- WIESNIAK_H = 43
- P3Color:
- dc.w $0111,$0b89,$0b8a,$0742
- dc.w $0665,$0c9a,$0aaa,$0bad
- dc.w $0734,$0745,$0956,$0867
- dc.w $0a68,$0978,$0a77,$0b79
- dc.w $0a89,$0111,$0222,$0333
- dc.w $0444,$0555,$0666,$0866
- dc.w $0777,$0888,$0bab,$0000
- dc.w $0800,$0f00,$0780,$0ff0
- StartPart3:
- pusha
- fullscreen_part
- ; Copy part 3 scene to screen
- lea P3Scene,a0
- lea Screen,a1
- move.l #(Screen_e-Screen)/4,d0
- .screen_copy:
- move.l (a0)+,(a1)+
- dbf d0,.screen_copy
- ; Shut off all sound
- bsr APlayNullAll
- ; Load colors
- lea P3Color(pc),a0
- bsr LoadColorsToCopper
- ; Position SAS
- move #SCREEN_W+2,SasPos0
- move #SCREEN_W+8,SasPos1
- move #SCREEN_W,SasPos2
- move #SCREEN_W+5,SasPos3
- ; Enable copper, sprites and blitter
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- next_part Part3(pc)
- popa
- rts
- Part3:
- Part3a_move_in:
- pusha
- _SAS_DST_X_3A = SCREEN_W-48
- _ENEMY_SHOUT_3A = 16
- move.l #_SAS_DST_X_3A,d1
- bsr StepAllSasLeftToX
- move d0,d7
- move .shouts_counter(pc),d0
- addq #1,d0
- move d0,.shouts_counter
- cmp #_ENEMY_SHOUT_3A,d0
- bne .no_shout
- lea AXrayTroopers,a0
- move #(AXrayTroopers_e-AXrayTroopers)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- bra .no_stop_shout
- .no_shout:
- cmp #_ENEMY_SHOUT_3A+1,d0
- bne .no_stop_shout
- bsr APlayNullLeft
- .no_stop_shout:
- ; play step sound
- move #64,d2
- cmp #1,d7
- beq .one_sas_moving
- tst d7
- beq .all_stop
- bsr APlayGrassWalkManyRight
- bra .done
- .one_sas_moving:
- bsr APlayGrassWalkOneRight
- bra .done
- .all_stop:
- bsr APlayNullAll
- next_part Part3b_enemy_contact(pc)
- ;delayed_part #4,Part3b_enemy_contact(pc)
- .done:
- popa
- rts
- .shouts_counter:
- dc.w 0
- Part3b_enemy_contact:
- pusha
- lea ASasEnemyContact+3000,a0
- move #(ASasEnemyContact_e-ASasEnemyContact-3000)/2,d0
- move #1,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #(FPS/2)+(FPS/4),Part3c_offense(pc)
- popa
- rts
- Part3c_offense:
- pusha
- bsr APlayNullRight
- lea AXrayDieUBastards,a0
- move #(AXrayDieUBastards_e-AXrayDieUBastards)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #FPS/2,Part3d_shoot_sas(pc)
- popa
- rts
- ; THERE WAS A FIREFIGHT!
- Part3d_shoot_sas:
- pusha
- ; Shoot a bullet by "paskudny" at SAS 2
- move .bullet_shot(pc),d0
- tst d0
- bge .already_fired
- move #P3_PASKUDNY_X+PASKUDNY_VISW,d0
- move #P3_PASKUDNY_Y+PASKUDNY_H/2,d1
- move SasPos2(pc),d2 ; SAS x
- move SasPos2+2(pc),d3 ; SAS y
- add #SAS_H/2,d3
- bsr FireBullet
- move d0,.bullet_shot
- ; store pointer to bullet
- bullet_at_list a0,d0
- move.l a0,.first_bullet
- ; shut up paskudny
- move #0,d1
- bsr APlayNull
- ; fire AK47
- lea AAk47_1,a0
- move #(AAk47_1_e-AAk47_1)/2,d0
- move #3,d1
- move #64,d2
- bsr APlay11Khz
- bra .done
- .already_fired:
- ; shut up AK47
- move #3,d1
- bsr APlayNull
- move.l .first_bullet(pc),a0
- tst bullet_t.live(a0)
- bne .go_bullet
- next_part Part3e_sas_hit(pc)
- bra .done
- .go_bullet:
- bsr BulletEngine
- .done:
- popa
- rts
- .bullet_shot:
- dc.w $ffff
- .first_bullet:
- dc.l $0
- Part3e_sas_hit:
- pusha
- lea ASasHurt,a0
- move #(ASasHurt_e-ASasHurt)/2,d0
- move #1,d1
- move #64,2
- bsr APlay11Khz
- delayed_part #FPS/2,Part3f_sas_die(pc)
- popa
- rts
- Part3f_sas_die:
- pusha
- lea ADie05,a0
- move #(ADie05_e-ADie05)/2,d0
- move #1,d1
- move #64,2
- bsr APlay11Khz
- lea ASasManDown,a0
- move #(ASasManDown_e-ASasManDown)/2,d0
- move #2,d1
- move #64,2
- bsr APlay11Khz
- ; Blit dead SAS in place of SAS 2
- lea P3SasDead,a0
- lea P3SasDeadMask,a1
- lea Screen,a2
- move.l SasPos2(pc),d1
- move.l d1,d0
- swap d0
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- ; SAS 3 position is now stored at the position of the dead SAS 2
- ; and SAS 3 is now effectively SAS 2. Previous SAS 2 is replaced
- ; by a blitted picture of dead SAS.
- move.l SasPos3(pc),d0
- move.l #$100,SasPos3
- move.l d0,SasPos2
- move #2,d2
- bsr PlotSas
- move #3,d2
- bsr PlotSas
- delayed_part #FPS/2,Part3g_firefight(pc)
- popa
- rts
- Part3g_firefight:
- pusha
- ; Shut up SAS troopers
- move .first(pc),d0
- tst d0
- bne .not_first
- bsr APlayNullRight
- move #1,.first
- ; Begin AK47 canonade
- lea AAk47Burst,a0
- move.l #(AAk47Burst_e-AAk47Burst)/2-2000,d0
- move.l #0,d1
- move.l #64,d2
- bsr APlay11Khz
- .not_first:
- bsr BulletEngine
- .paskudny_shoot:
- move .paskudny_alive(pc),d0
- tst d0
- beq .wiesniak_shoot ; paskudny's dead, man
- move .xray_shoot(pc),d0
- move d0,d7
- addq #1,d0
- move d0,.xray_shoot
- and #$f,d0
- tst d0
- bne .wiesniak_shoot
- ; They will now shoot *very* inaccurate.
- move #P3_PASKUDNY_X+PASKUDNY_VISW,d0
- move #P3_PASKUDNY_Y+PASKUDNY_H/2,d1
- move #320,d2 ; nothing x
- move #300,d3 ; nothing y
- bsr FireBullet
- .wiesniak_shoot:
- move .wiesniak_alive(pc),d0
- tst d0
- beq .dont_xray_shoot ; wiesniak's dead too, now what we do?
- ; space his shooting differently than paskudny's
- and #$f,d7
- cmp #$8,d7
- bne .dont_xray_shoot
- move #P3_WIESNIAK_X+WIESNIAK_VISW,d0
- move #P3_WIESNIAK_Y+WIESNIAK_H/2,d1
- move #320,d2
- move #0,d3
- bsr FireBullet
- .dont_xray_shoot:
- move .xray_shoot(pc),d7
- cmp #$50,d7
- beq .sas2_shoot
- cmp #$38,d7
- bne .track_sas_bullet
- .sas1_shoot:
- move SasPos1(pc),d0
- move SasPos1+2(pc),d1
- add #SAS_H/2,d1
- move #P3_WIESNIAK_X+WIESNIAK_VISW,d2
- move #P3_WIESNIAK_Y+WIESNIAK_H/2,d3
- bsr FireBullet
- move d0,.sas_bullet_wiesniak
- lea AMp5_1,a0
- move #(AMp5_1_e-AMp5_1)/2,d0
- moveq #1,d1
- move #64,d2
- bsr APlay11Khz
- bra .dont_sas_shoot
- .sas2_shoot:
- move SasPos2(pc),d0
- move SasPos2+2(pc),d1
- add #SAS_H/2-4,d1
- move #P3_PASKUDNY_X+PASKUDNY_VISW,d2
- move #P3_PASKUDNY_Y+PASKUDNY_H/2-4,d3
- bsr FireBullet
- move d0,.sas_bullet_paskudny
- lea AMp5_2,a0
- move #(AMp5_2_e-AMp5_2)/2,d0
- moveq #2,d1
- move #64,d2
- bsr APlay11Khz
- bra .dont_sas_shoot
- .track_sas_bullet:
- ; track bullet that kills wiesniak
- move .sas_bullet_wiesniak(pc),d7
- cmp #$ffff,d7
- beq .no_sas_wiesniak_bullet
- ; bullet was shot, so shut up audio
- moveq #1,d1
- bsr APlayNull
- bullet_at_list a0,d7
- tst bullet_t.live(a0)
- bne .no_sas_wiesniak_bullet
- ; kill wiesniak
- move #0,.wiesniak_alive
- lea P3WiesniakDead,a0
- lea P3WiesniakDeadMask,a1
- lea Screen,a2
- move #P3_WIESNIAK_X,d0
- move #P3_WIESNIAK_Y,d1
- move #SCREEN_D,d2
- move #WIESNIAK_W,d3
- move #WIESNIAK_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- lea ADie07,a0
- move.l #(ADie07_e-ADie07)/2,d0
- move.l #0,d1
- move.l #64,d2
- bsr APlay11Khz
- .no_sas_wiesniak_bullet:
- ; track bullet that kills paskudny
- move .sas_bullet_paskudny(pc),d7
- cmp #$ffff,d7
- beq .no_sas_paskudny_bullet
- ; bullet was shot, so shut up audio
- moveq #2,d1
- bsr APlayNull
- bullet_at_list a0,d7
- tst bullet_t.live(a0)
- bne .no_sas_paskudny_bullet
- ; kill paskudny
- move #0,.paskudny_alive
- lea P3PaskudnyDead,a0
- lea P3PaskudnyDeadMask,a1
- lea Screen,a2
- move #P3_PASKUDNY_X,d0
- move #P3_PASKUDNY_Y,d1
- move #SCREEN_D,d2
- move #PASKUDNY_W,d3
- move #PASKUDNY_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- lea ADie06,a0
- move.l #(ADie06_e-ADie06)/2,d0
- move.l #3,d1
- move.l #64,d2
- bsr APlay11Khz
- .no_sas_paskudny_bullet:
- .dont_sas_shoot:
- .check_the_dead:
- move .wiesniak_alive(pc),d0
- tst d0
- bne .done
- move .paskudny_alive(pc),d0
- tst d0
- bne .done
- next_part Part3h_go(pc)
- .done:
- popa
- rts
- .xray_shoot:
- dc.w $ffff
- .ak47_channel:
- dc.w 0
- .first:
- dc.w 0
- .sas_bullet_wiesniak:
- dc.w $ffff
- .sas_bullet_paskudny:
- dc.w $ffff
- .wiesniak_alive:
- dc.w 1
- .paskudny_alive:
- dc.w 1
- Part3h_go:
- ; SAS now go for the door and open it
- pusha
- move .start(pc),d7
- tst d7
- bne .already_started
- bsr APlayNullAll
- .already_started:
- addq #1,d7
- move d7,.start
- bsr BulletEngine
- ; Delay a bit
- cmp #$20,d7
- blt .done
- ; Move up to the door
- move #88,d1
- move #1,d2
- bsr StepSasLeftToX
- bsr PlotSas
- move d7,d6
- and #$f,d6
- tst d6
- bne .skip_sound
- move #64,d2
- bsr APlayGrassWalkOneBoth
- .skip_sound:
- ; Continue until we're moving
- tst d0
- bne .done
- bsr APlayNullAll
- delayed_part #FPS/2,Part3i_open_door
- .done:
- popa
- rts
- .start:
- dc.w 0
- Part3i_open_door:
- pusha
- move .door_open(pc),d0
- tst d0
- bne .next
- ; OPDOR!
- lea DoorOpen,a0
- lea DoorMask,a1
- lea Screen,a2
- move #P3_DOOR_X,d0
- move #P3_DOOR_Y,d1
- move #SCREEN_D,d2
- move #DOOR_W,d3
- move #DOOR_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- lea ADoorOpen,a0
- move #(ADoorOpen_e-ADoorOpen)/2,d0
- move #1,d1
- move #64,d2
- bsr APlay11Khz
- move #1,.door_open
- bra .done
- .next:
- bsr APlayNullAll
- delayed_part #FPS/2,Part3j_walk_through
- .done:
- popa
- rts
- .door_open:
- dc.w 0
- Part3j_walk_through:
- pusha
- move.l #-32,d1
- move #$7,d2
- bsr StepMaskSasLeftToX
- move #NUM_SAS-2,d2
- .plotsas:
- bsr PlotSas
- dbf d2,.plotsas
- ; Continue until screen fades out completely
- move .fadeout_countdown(pc),d0
- subq #1,d0
- move d0,.fadeout_countdown
- tst d0
- beq .next
- and #%11,d0
- tst d0
- bne .done
- move #64,d2
- bsr APlayGrassWalkManyBoth
- .fadeout:
- lea P3Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- bra .done
- .next:
- next_part StartPart4(pc)
- .done:
- popa
- rts
- .fadeout_countdown:
- dc.w 64
- ;;
- ;; Part4
- ;;
- P4_SAS0_X = 225
- P4_SAS0_Y = 160
- P4_SAS1_X = 256
- P4_SAS1_Y = 128
- P4_SAS2_X = 256
- P4_SAS2_Y = 192
- P4_BOMB_X = 48
- P4_BOMB_Y = 85
- P4_BOMB_W = 96
- P4_BOMB_H = 171
- P4_DOOR_X = 15
- P4_DOOR_Y = 1
- P4_60S_W = 48
- P4_60S_H = 48
- P4_60S_X = P4_DOOR_X+DOOR_W/2-P4_60S_W/2
- P4_60S_Y = P4_DOOR_Y+DOOR_H-P4_60S_H-5
- P4Color:
- dc.w $0111,$0b89,$0b8a,$0742
- dc.w $0665,$0c9a,$0aaa,$0bad
- dc.w $0734,$0745,$0956,$0867
- dc.w $0a68,$0978,$0a77,$0b79
- dc.w $0a89,$0111,$0222,$0333
- dc.w $0444,$0555,$0666,$0866
- dc.w $0777,$0888,$0bab,$0000
- dc.w $0800,$0f00,$0780,$0ff0
- StartPart4:
- pusha
- fullscreen_part
- ; Yet again we need to copy the picture to the screen.
- ; Background will be used to blit back when we move stuff around.
- lea P4Scene,a0
- lea Screen,a1
- lea Background,a2
- move.l #(Screen_e-Screen)/4,d0
- .screen_copy:
- move.l (a0),(a2)+
- move.l (a0)+,(a1)+
- dbf d0,.screen_copy
- ; Load colors
- lea P4Color(pc),a0
- bsr LoadColorsToCopper
- ; Load boom sprite
- lea CopperSprite7,a0
- move.l #BoomSprite,d0
- pokecopper d0,a0
- ; Reposition SAS troopers (TROOPERS!)
- ; There will be only one trooper moving at a time so we wish
- ; to keep only one sprite.
- move.l #P4_SAS0_X<<16!P4_SAS0_Y,SasPos0
- move.l #$100,SasPos1
- move.l #$100,SasPos2
- move.l #$100,SasPos3
- moveq #NUM_SAS-1,d2
- .plotsas:
- bsr PlotSas
- dbf d2,.plotsas
- ; Enable copper, sprites and blitter
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- ; Blit the other troopers on to the screen as background elements.
- ; They will remain stationary for the most part of this scene.
- lea P3Sas,a0
- lea P3SasMask,a1
- lea Screen,a2
- move.l #P4_SAS1_X,d0
- move.l #P4_SAS1_Y,d1
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- move.l #P4_SAS2_X,d0
- move.l #P4_SAS2_Y,d1
- bsr BlitMaskedXY
- ; Somebody set up us the bomb.
- lea P4Bomb,a0
- lea P4BombMask,a1
- lea Screen,a2
- move.l #P4_BOMB_X,d0
- move.l #P4_BOMB_Y,d1
- move #SCREEN_D,d2
- move #P4_BOMB_W,d3
- move #P4_BOMB_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- ; Shotgun will be fired here
- lea CopperSprite6,a0
- bsr LoadShotgunPelletSprite
- bsr BlitWait
- delayed_part #FPS/3,Part4(pc)
- popa
- rts
- Part4:
- Part4a:
- pusha
- _SAS_DST_X_4A = 160
- clr.l d7
- move.l #_SAS_DST_X_4A,d1
- clr d2
- bsr StepSasLeftToX
- move d0,d7
- bsr PlotSas
- tst d7
- beq .next
- move .step_count(pc),d0
- addq #1,d0
- move d0,.step_count
- and #%11,d0
- tst d0
- bne .done
- move #64,d2
- bsr APlayFloorWalkOneBoth
- bra .done
- .next:
- next_part Part4b_door_opens(pc)
- .done:
- popa
- rts
- .step_count:
- dc.w $ffff
- Part4b_door_opens:
- pusha
- bsr APlayNullAll
- ; Open the door ...
- lea DoorOpen,a0
- lea DoorMask,a1
- lea Screen,a2
- move #P4_DOOR_X,d0
- move #P4_DOOR_Y,d1
- move #SCREEN_D,d2
- move #DOOR_W,d3
- move #DOOR_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- lea ADoorOpen,a0
- move #(ADoorOpen_e-ADoorOpen)/2,d0
- move #3,d1
- move #64,d2
- bsr APlay11Khz
- ; ... and reveal THE 60's behind it!
- lea P460s,a0
- lea P460sMask,a1
- lea Screen,a2
- move #P4_60S_X,d0
- move #P4_60S_Y,d1
- move #SCREEN_D,d2
- move #P4_60S_W,d3
- move #P4_60S_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- delayed_part #FPS/3,Part4c_60s_surprise(pc)
- popa
- rts
- Part4c_60s_surprise:
- pusha
- bsr APlayNullAll
- bsr BulletEngine
- move .shotgun_pellet(pc),d7
- cmp #$ffff,d7
- bne .already_fired
- ; Shoot the 60s with a shotgun, but sadly hit the pointman SAS instead.
- move #P4_SAS2_X-PELLET_W,d0
- move #P4_SAS2_Y+SAS_H/2-PELLET_H/2,d1
- move.l SasPos0,d2
- move d2,d3
- swap d2
- add #PELLET_W/2,d2
- add #SAS_H/4,d3
- bsr FireBullet
- move d0,.shotgun_pellet
- lea AShotgun,a0
- move #(AShotgun_e-AShotgun)/2,d0
- moveq #2,d1
- move #48,d2
- bsr APlay11Khz
- bra .done
- .already_fired:
- moveq #2,d1
- bsr APlayNull
- move .shotgun_pellet(pc),d0
- bullet_at_list a0,d0
- tst bullet_t.live(a0)
- bne .done
- .next:
- next_part Part4d_sas_die(pc)
- .done:
- popa
- rts
- .shotgun_pellet:
- dc.w $ffff
- Part4d_sas_die:
- pusha
- ; Oops! You killed your team mate, you piece of plant life!
- lea ADie06,a0
- move #(ADie06_e-ADie06)/2,d0
- move #3,d1
- move #32,d2
- bsr APlay11Khz
- lea ASasBluOnBlu,a0
- move #(ASasBluOnBlu_e-ASasBluOnBlu)/2,d0
- move #2,d1
- move #64,d2
- bsr APlay11Khz
- ; Blit dead SAS in place of SAS 0
- lea P3SasDead,a0
- lea P3SasDeadMask,a1
- lea Screen,a2
- move.l SasPos0(pc),d1
- move.l d1,d0
- swap d0
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- move.l #$100,SasPos0
- clr.l d2
- bsr PlotSas
- next_part Part4d2_stop_audio(pc)
- popa
- rts
- Part4d2_stop_audio:
- pusha
- bsr APlayNullAll
- delayed_part #FPS,Part4d3_xray_surrender(pc)
- popa
- rts
- Part4d3_xray_surrender:
- pusha
- ; Don't worry friend, we won't shoot you.
- lea AXrayDontShoot,a0
- move #(AXrayDontShoot_e-AXrayDontShoot)/2,d0
- moveq #3,d1
- move #56,d2
- bsr APlay11Khz
- delayed_part #FPS+FPS/2,Part4e_unpin_grenade(pc)
- popa
- rts
- Part4e_unpin_grenade:
- pusha
- clr d1
- bsr APlayNull
- moveq #1,d1
- bsr APlayNull
- moveq #3,d1
- bsr APlayNull
- move .unpinned(pc),d0
- tst d0
- bne .no_unpin
- ; Play the audio
- move #2,d1
- move #64,d2
- bsr APlayGrenadeUnpin
- move #1,.unpinned
- ; Load the grenade sprite now instead of the SAS sprite.
- ; Don't plot it yet, but we'll do it soon.
- lea CopperSprite,a0
- bsr LoadGrenadeSprite
- bra .done
- .no_unpin:
- moveq #2,d1
- bsr APlayNull
- delayed_part #FPS/2,Part4f_grenade_throw
- .done:
- popa
- rts
- .unpinned:
- dc.w 0
- P4_GRENADE_X = P4_SAS1_X
- P4_GRENADE_Y = P4_SAS1_Y+SAS_H/2-GRENADE_H/2
- P4_GRENADE_DST_X = 46
- GRENADE_SPEED = 4
- P4GrenadeX:
- dc.w P4_GRENADE_X
- P4GrenadeY:
- dc.w P4_GRENADE_Y
- Part4f_grenade_throw:
- pusha
- move #2,d1
- bsr APlayNull
- ; Now plot the *grenayd!* and fire it left like a rocket.
- bsr P4PlotGrenade
- move P4GrenadeX(pc),d0
- sub #GRENADE_SPEED,d0
- move d0,P4GrenadeX
- cmp #P4_GRENADE_DST_X,d0
- bgt .done
- next_part Part4g_grenade_drop(pc)
- .done:
- popa
- rts
- Part4g_grenade_drop:
- pusha
- move #3,d1
- move #64,d2
- bsr APlayGrenadeBounce
- move .bump_bump(pc),d0
- tst d0
- beq .next
- ; Bump it a bit more, albeit slowly
- subq #1,d0
- move d0,.bump_bump
- and #%111,d0
- tst d0
- bne .done
- sub #2,P4GrenadeX
- bsr P4PlotGrenade
- bra .done
- .next:
- next_part Part4h_grenade_boom
- .done:
- popa
- rts
- .bump_bump:
- dc.w 31
- Part4h_grenade_boom:
- pusha
- ; Grenade explodes!
- move #3,d1
- move #64,d2
- bsr APlayGrenadeExplode
- ; There is an explosion!
- lea BoomSprite,a0
- move P4GrenadeX(pc),d0
- swap d0
- or P4GrenadeY(pc),d0
- add.l #$80002c,d0
- move #BOOM_H,d1
- bsr MoveSprite
- ; Grenade is gone!
- move #257,P4GrenadeY
- bsr P4PlotGrenade
- ; 60s xray is gone in a true The Regiment fashion!
- ; Blit the open door again to make him disappear.
- lea DoorOpen,a0
- lea DoorMask,a1
- lea Screen,a2
- move #P4_DOOR_X,d0
- move #P4_DOOR_Y,d1
- move #SCREEN_D,d2
- move #DOOR_W,d3
- move #DOOR_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- lea ADie05,a0
- move #(ADie05_e-ADie05)/2,d0
- move #1,d1
- move #64,d2
- bsr APlay11Khz
- ; The booby trap somehow survives.
- delayed_part #FPS/2,Part4i_respite(pc)
- popa
- rts
- Part4i_respite:
- pusha
- bsr APlayNullAll
- ; Clear the top SAS BOB.
- lea Background,a0
- lea Screen,a2
- move.l #P4_SAS1_X,d0
- move.l #P4_SAS1_Y,d1
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitBackground
- ; Remove explosion
- lea BoomSprite,a0
- move.l #$12c,d0
- move #BOOM_H,d1
- bsr MoveSprite
- ; Reload SAS sprite and replace the top SAS
- lea CopperSprite,a0
- bsr PokeCopperSasSprite
- move.l #P4_SAS1_X<<16!P4_SAS1_Y,SasPos0
- clr.l d2
- bsr PlotSas
- delayed_part #FPS*2,Part4j_sas_move_out(pc)
- popa
- rts
- Part4j_sas_move_out:
- ; Move to the booby trap, trigger it and die there.
- pusha
- _SAS_DST_X_4J = 145
- clr.l d7
- move.l #_SAS_DST_X_4J,d1
- clr d2
- bsr StepSasLeftToX
- move d0,d7
- bsr PlotSas
- tst d7
- beq .next
- move .step_count(pc),d0
- addq #1,d0
- move d0,.step_count
- and #%11,d0
- tst d0
- bne .done
- move #64,d2
- bsr APlayFloorWalkOneBoth
- bra .done
- .next:
- next_part Part4k_see_trap(pc)
- .done:
- popa
- rts
- .step_count:
- dc.w $ffff
- Part4k_see_trap:
- _SAS_DST_X_4K = 105
- ; Notice the trap, but keep moving
- pusha
- move .noticed(pc),d0
- tst d0
- bne .already_noticed
- move #1,.noticed
- lea ASasBooby,a0
- move #(ASasBooby_e-ASasBooby)/2,d0
- move #2,d1
- move #64,d2
- bsr APlay11Khz
- bra .keep_going
- .already_noticed:
- bsr APlayNullAll
- .keep_going:
- clr.l d7
- move.l #_SAS_DST_X_4K,d1
- clr d2
- bsr StepSasLeftToX
- move d0,d7
- bsr PlotSas
- tst d7
- bne .done
- .next:
- next_part Part4l_trip_trap(pc)
- .done:
- popa
- rts
- .noticed:
- dc.w 0
- Part4l_trip_trap:
- ; The "oh shit..." moment
- pusha
- move .tripped(pc),d0
- tst d0
- bne .next
- move #1,.tripped
- lea ABoobyTripped,a0
- move #(ABoobyTripped_e-ABoobyTripped)/2,d0
- move #1,d1
- move #64,d2
- bsr APlay11Khz
- bra .done
- .next:
- bsr APlayNullAll
- delayed_part #FPS,Part4m_explosion(pc)
- .done:
- popa
- rts
- .tripped:
- dc.w 0
- Part4m_explosion:
- ; It kills the nearby SAS and clears the whole screen, basically
- pusha
- ; Audio canonade
- lea ABoobyExplode,a0
- move #(ABoobyExplode_e-ABoobyExplode)/2,d0
- move #2,d1
- move #48,d2
- bsr APlay11Khz
- move #3,d1
- bsr APlay11Khz
- lea ADie07,a0
- move #(ADie07_e-ADie07)/2,d0
- move #0,d1
- move #64,d2
- bsr APlay11Khz
- ; Redraw the left part of the screen
- lea Background,a0
- lea Screen,a2
- move #16,d0
- move #P4_BOMB_Y,d1
- move #SCREEN_D,d2
- move #192,d3
- move #SCREEN_H-P4_BOMB_Y,d4
- move #SCREEN_W,d5
- bsr BlitBackground
- ; Now the final SAS becomes SAS 0
- move.l #P4_SAS2_X<<16!P4_SAS2_Y,SasPos0
- clr.l d2
- bsr PlotSas
- ; There is another explosion!
- lea BoomSprite,a0
- move.l #(P4_BOMB_X+80)<<16+P4_BOMB_Y+BOOM_H/2+$80002c,d0
- move #BOOM_H,d1
- bsr MoveSprite
- ; Blit the open door back
- lea DoorOpen,a0
- lea DoorMask,a1
- lea Screen,a2
- move #P4_DOOR_X,d0
- move #P4_DOOR_Y,d1
- move #SCREEN_D,d2
- move #DOOR_W,d3
- move #DOOR_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- ; And redraw the background under the SAS
- lea Background,a0
- lea Screen,a2
- move #P4_SAS2_X,d0
- move #P4_SAS2_Y,d1
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitBackground
- next_part Part4n_aftermath(pc)
- popa
- rts
- Part4n_aftermath:
- pusha
- bsr APlayNullAll
- delayed_part #FPS+FPS/2,Part4n2_clear_explosion(pc)
- popa
- rts
- Part4n2_clear_explosion:
- pusha
- lea BoomSprite,a0
- move.l #0,(a0)
- lea ASasMedic,a0
- move #(ASasMedic_e-ASasMedic)/2,d0
- move #1,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #2,Part4n3_nomedic(pc)
- popa
- rts
- Part4n3_nomedic:
- pusha
- bsr APlayNullAll
- delayed_part #FPS*2,Part4o_mission_continues(pc)
- popa
- rts
- Part4o_mission_continues:
- pusha
- _SAS_DST_X_4O = 0
- move.l #_SAS_DST_X_4O,d1
- clr d2
- bsr StepSasLeftToX
- bsr PlotSas
- ; Continue until screen fades out completely
- move .fadeout_countdown(pc),d0
- subq #1,d0
- move d0,.fadeout_countdown
- tst d0
- beq .next
- and #%111,d0
- tst d0
- bne .done
- move #64,d2
- bsr APlayFloorWalkOneBoth
- .fadeout:
- lea P4Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- bra .done
- .next:
- next_part StartPart5(pc)
- .done:
- popa
- rts
- .fadeout_countdown:
- dc.w 128
- P4PlotGrenade:
- pusha
- lea GrenadeSprite,a0
- move P4GrenadeX(pc),d0
- swap d0
- or P4GrenadeY(pc),d0
- add.l #$80002c,d0
- move #GRENADE_H,d1
- bsr MoveSprite
- add.l #GRENADE_ATTACH,a0
- bsr MoveSprite
- popa
- rts
- ;;
- ;; Part 5
- ;;
- P5_SAS0_X = 160
- P5_SAS0_Y = -SAS_H
- P5_SADDAM_X = 135
- P5_SADDAM_Y = 144
- SADDAM_W = 48
- SADDAM_VISW = 32
- SADDAM_H = 52
- P5Color:
- dc.w $0565,$0776,$0333,$0764
- dc.w $0455,$0c9a,$0aaa,$0bad
- dc.w $0734,$0745,$0956,$0867
- dc.w $0a68,$0978,$0a77,$0b79
- dc.w $0a89,$0111,$0222,$0333
- dc.w $0444,$0555,$0666,$0866
- dc.w $0777,$0888,$0bab,$0000
- dc.w $0800,$0f00,$0780,$0ff0
- StartPart5:
- ; Here we are. The lone survivor SAS hero arrives at the final enemy.
- ; This enemy is Saddam! And he helds the ambassador hostage.
- ; The ambassador needs some serious saving, but we'll get to
- ; that later.
- pusha
- fullscreen_part
- ; Load background
- lea P5Scene,a0
- lea Screen,a1
- move.l #(Screen_e-Screen)/4,d0
- .screen_copy:
- move.l (a0)+,(a1)+
- dbf d0,.screen_copy
- ; Load colors
- lea P5Color(pc),a0
- bsr LoadColorsToCopper
- ; Position SAS
- move #P5_SAS0_X,SasPos0
- move #P5_SAS0_Y,SasPos0+2
- clr d2
- bsr PlotSas
- ; Shotgun will be fired here
- lea CopperSprite6,a0
- bsr LoadShotgunPelletSprite
- ; Enable copper, sprites and blitter
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- next_part Part5(pc)
- popa
- rts
- Part5:
- Part5_lonewolf_sas_moves_in_and_this_can_be_any_length_i_want:
- pusha
- _SAS_Y_P5 = 16
- move #_SAS_Y_P5,d1
- clr d2
- bsr StepSasBottomToY
- move d0,d7
- bsr PlotSas
- move .step_count(pc),d0
- addq #1,d0
- move d0,.step_count
- and #%111,d0
- tst d0
- bne .is_done
- move #64,d2
- bsr APlayFloorWalkOneBoth
- .is_done:
- tst d7
- bne .done
- next_part Part5b_saddam_threat(pc)
- .done:
- popa
- rts
- .step_count:
- dc.w 0
- Part5b_saddam_threat:
- pusha
- bsr APlayNullAll
- ; Say THAT threat
- lea AXrayYouBloodyFools,a0
- move #(AXrayYouBloodyFools_e-AXrayYouBloodyFools)/2,d0
- moveq #3,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #2,Part5b2_saddam_threatens(pc)
- popa
- rts
- Part5b2_saddam_threatens:
- pusha
- bsr APlayNullAll
- delayed_part #FPS,Part5c_sas_kill_saddam(pc)
- popa
- rts
- Part5c_sas_kill_saddam:
- pusha
- ; Fire shotgun at Saddam
- lea AShotgun,a0
- move #(AShotgun_e-AShotgun)/2,d0
- moveq #1,d1
- move #64,d2
- bsr APlay11Khz
- move.l SasPos0(pc),d1
- move.l d1,d0
- swap d0
- add #SAS_H,d1
- add #4,d0
- move #P5_SADDAM_X+SADDAM_VISW/2,d2
- move #P5_SADDAM_Y,d3
- bsr FireBullet
- move d0,P5Pellet
- bullet_at_list a0,d0
- move.l a0,P5Pellet
- delayed_part #2,Part5d_track_bullet(pc)
- popa
- rts
- Part5d_track_bullet:
- ; We are doing the same code differently each time.
- ; Long live the consistency!
- pusha
- bsr APlayNullAll
- bsr BulletEngine
- move.l P5Pellet(pc),a0
- move bullet_t.live(a0),d0
- tst d0
- bne .done
- next_part Part5e_saddam_die(pc)
- .done:
- popa
- rts
- Part5e_saddam_die:
- ; Not again...
- pusha
- lea ADie05,a0
- move #(ADie05_e-ADie05)/2,d0
- moveq #0,d1
- move #64,d2
- bsr APlay11Khz
- lea P5SaddamDead,a0
- lea P5SaddamMask,a1
- lea Screen,a2
- move #P5_SADDAM_X,d0
- move #P5_SADDAM_Y,d1
- move #SCREEN_D,d2
- move #SADDAM_W,d3
- move #SADDAM_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- delayed_part #FPS/2,Part5f_continue_saddam(pc)
- popa
- rts
- Part5f_continue_saddam:
- pusha
- bsr APlayNullAll
- ; Saddam threat is a long one and continues when he's dead already.
- lea AXrayAndItsYourFault,a0
- move #(AXrayAndItsYourFault_e-AXrayAndItsYourFault)/2,d0
- moveq #3,d1
- move #64,d2
- bsr APlay11Khz
- next_part Part5f2_respite(pc)
- popa
- rts
- Part5f2_respite:
- pusha
- bsr APlayNullAll
- delayed_part #FPS*2,Part5g_approach_ambassador(pc)
- popa
- rts
- Part5g_approach_ambassador:
- ; Copypaste programming is the best when you're running out of time
- ; and the deadline is just around the corner.
- pusha
- _SAS_Y_5G = 160
- move #_SAS_Y_5G,d1
- clr d2
- bsr StepSasBottomToY
- move d0,d7
- bsr PlotSas
- move .step_count(pc),d0
- addq #1,d0
- move d0,.step_count
- and #%111,d0
- tst d0
- bne .is_done
- move #64,d2
- bsr APlayFloorWalkOneBoth
- .is_done:
- tst d7
- bne .done
- next_part Part5h_ambassador_thanks(pc)
- .done:
- popa
- rts
- .step_count:
- dc.w 0
- Part5h_ambassador_thanks:
- pusha
- bsr APlayNullAll
- ; Say "thank you"
- lea AHostThankYou,a0
- move #(AHostThankYou_e-AHostThankYou)/2,d0
- moveq #2,d1
- move #64,d2
- bsr APlay11Khz
- next_part Part5h2(pc)
- popa
- rts
- Part5h2:
- pusha
- bsr APlayNullAll
- delayed_part #FPS+FPS/2,Part5i_mission_successful(pc)
- popa
- rts
- Part5i_mission_successful:
- pusha
- ; Play the success sound.
- lea AWin,a0
- move #(AWin_e-AWin)/2,d0
- moveq #0,d1
- move #64,d2
- bsr APlay8Khz
- moveq #1,d1
- bsr APlay8Khz
- ; Screen dims a bit.
- lea P5Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- delayed_part #FPS+FPS/2,Part5j_unpin_grenade(pc)
- popa
- rts
- Part5j_unpin_grenade:
- pusha
- ; SAS has a present for everyone.
- move #3,d1
- move #64,d2
- bsr APlayGrenadeUnpin
- ; Screen dims a bit... again.
- lea P5Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- ; Blit SAS as we will be replacing their sprite with a grenade, again.
- lea P3Sas,a0
- lea P3SasMask,a1
- lea Screen,a2
- move.l SasPos0(pc),d1
- move.l d1,d0
- swap d0
- move #SCREEN_D,d2
- move #SAS_W,d3
- move #SAS_H,d4
- move #SCREEN_W,d5
- bsr BlitMaskedXY
- ; Arbitrary values show that I want to get over with this already.
- sub #8,d0
- move d0,P5GrenadeX
- add #20,d1
- move d1,P5GrenadeY
- move.l #$100,SasPos0
- clr d2
- bsr PlotSas
- lea CopperSprite,a0
- bsr LoadGrenadeSprite
- next_part Part5j2(pc)
- popa
- rts
- Part5j2:
- pusha
- bsr APlayNullAll
- delayed_part #FPS+FPS,Part5k_throw(pc)
- popa
- rts
- Part5k_throw:
- pusha
- move P5GrenadeX(pc),d0
- add #$80,d0
- swap d0
- move P5GrenadeY(pc),d0
- add #$2c,d0
- move #GRENADE_H,d1
- lea GrenadeSprite,a0
- bsr MoveSprite
- add.l #GRENADE_ATTACH,a0
- bsr MoveSprite
- moveq #3,d1
- move #64,d2
- bsr APlayGrenadeBounce
- delayed_part #FPS/4,Part5k2
- popa
- rts
- Part5k2:
- pusha
- bsr APlayNullAll
- lea P5Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- delayed_part #FPS+FPS,Part5k3_dimmore(pc)
- popa
- rts
- Part5k3_dimmore:
- pusha
- bsr APlayNullAll
- lea P5Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr DimScreen
- delayed_part #FPS+FPS/2,Part5l_kaboom(pc)
- popa
- rts
- Part5l_kaboom:
- pusha
- lea P5Color(pc),a0
- move #SCREEN_COLORS-1,d0
- .blackloop:
- move #0,(a0)+
- dbf d0,.blackloop
- lea P5Color(pc),a0
- lea CopperColor,a1
- move #SCREEN_COLORS,d0
- bsr PokeCopperWords
- moveq #3,d1
- move #40,d2
- bsr APlayGrenadeExplode
- delayed_part #10,Part5l2(pc)
- popa
- rts
- Part5l2:
- pusha
- moveq #3,d1
- bsr APlayNull
- lea ADie06,a0
- move #(ADie06_e-ADie06)/2,d0
- moveq #0,d1
- move #64,d2
- bsr APlay11Khz
- lea ADie07,a0
- move #(ADie07_e-ADie07)/2,d0
- moveq #1,d1
- bsr APlay11Khz
- next_part Part5l3
- popa
- rts
- Part5l3:
- pusha
- bsr APlayNullAll
- delayed_part #FPS*4,StartEndScreen(pc)
- popa
- rts
- P5Pellet:
- dc.l $ffffffff
- P5GrenadeX:
- dc.w 0
- P5GrenadeY:
- dc.w 0
- ;;
- ;; Part End
- ;;
- END_W = 320
- END_H = 49
- END_D = 3
- END_BYPL = END_W/8
- END_BYWIDTH = END_BYPL*END_D
- BONUS_W = 116
- BONUS_VISW = 104
- BONUS_H = 128
- BONUS_D = 4
- BONUS_BYPL = BONUS_W/8
- BONUS_BYWIDTH = BONUS_BYPL*BONUS_D
- BONUS_X = (SCREEN_W-BONUS_W)/2
- BONUS_Y = (SCREEN_H-BONUS_H)/2
- ; Offset screen pointer to begin at the top-left corner of the center.
- BONUS_TOPLEFT = SCREEN_W/8*BONUS_D*BONUS_Y+BONUS_X/8
- GURU_W = 304
- GURU_VISW = 293
- GURU_H = 51
- GURU_D = 1
- GURU_BYPL = GURU_W/8
- GURU_X = (SCREEN_W-GURU_W)/2
- GURU_Y = 16
- GURU_TOPLEFT = SCREEN_W/8*GURU_D*GURU_Y+GURU_X/8
- EndColor:
- dc.w $0332,$0333,$0542,$0851
- dc.w $0565,$0e80,$0899,$0bcc
- dcb.w 24,0
- StartEndScreen:
- pusha
- bsr LoadEndCopper
- bsr APlayNullAll
- bsr ClearScreen
- ; Copy the screen
- lea MissionSuccess,a0
- lea Screen,a1
- move.l #(MissionSuccess_e-MissionSuccess)/4,d0
- .screen_copy:
- move.l (a0)+,(a1)+
- dbf d0,.screen_copy
- bsr BlitWait
- ; Enable copper, audio and bitplane DMA and load the copper list
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- next_part MissionEnd(pc)
- popa
- rts
- LoadEndCopper:
- pusha
- sub #copper_t,sp
- move.l sp,a0
- bsr InitCopperT
- move.b #END_D,copper_t.bitplanes(a0)
- move #$807f,copper_t.wait(a0)
- move #END_BYWIDTH-END_BYPL,copper_t.bpl1mod(a0)
- move #END_BYWIDTH-END_BYPL,copper_t.bpl2mod(a0)
- bsr LoadCopper
- bsr LoadScreenToCopper
- lea EndColor(pc),a0
- bsr LoadColorsToCopper
- lea CopperSprite,a0
- moveq #8,d0
- bsr PokeCopperNullSprite
- add #copper_t,sp
- popa
- rts
- MissionEnd:
- pusha
- bsr APlayIntro
- delayed_part #FPS*10,StartBonusScreen(pc)
- popa
- rts
- BonusColor:
- dc.w $0100,$0211,$0211,$0311
- dc.w $0322,$0321,$0421,$0532
- dc.w $0531,$0642,$0642,$0742
- dc.w $0743,$0754,$0852,$0864
- dcb.w 16,0
- StartBonusScreen:
- pusha
- bsr LoadBonusCopper
- bsr APlayNullAll
- bsr ClearScreen
- ; Copy the screen
- ; Bonus screen is not the full width of the screen so we need
- ; to modulo it correctly. We also need to position it at the center.
- lea BonusScreen,a0
- lea Screen+BONUS_TOPLEFT,a1
- move #(BONUS_H-1)*BONUS_D,d0 ; How many bitplane lines
- .screen_copy:
- move #BONUS_BYPL-1,d1
- .line_copy:
- move.b (a0)+,(a1)+
- dbf d1,.line_copy
- add.l #SCREEN_BYPL-BONUS_BYPL,a1 ; Shift the screen by modulo
- dbf d0,.screen_copy
- bsr BlitWait
- ; Enable copper, audio and bitplane DMA and load the copper list
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- delayed_part #FPS*2,BonusPart(pc)
- popa
- rts
- LoadBonusCopper:
- pusha
- sub #copper_t,sp
- move.l sp,a0
- bsr InitCopperT
- move.b #BONUS_D,copper_t.bitplanes(a0)
- move #SCREEN_BYPL*BONUS_D-SCREEN_BYPL,copper_t.bpl1mod(a0)
- move #SCREEN_BYPL*BONUS_D-SCREEN_BYPL,copper_t.bpl2mod(a0)
- bsr LoadCopper
- bsr LoadScreenToCopper
- lea BonusColor(pc),a0
- bsr LoadColorsToCopper
- lea CopperSprite,a0
- moveq #8,d0
- bsr PokeCopperNullSprite
- add #copper_t,sp
- popa
- rts
- BonusPart:
- pusha
- lea AMp5_1,a0
- move #(AMp5_1_e-AMp5_1)/2,d0
- moveq #2,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #FPS/2,BonusPartDie(pc)
- popa
- rts
- BonusPartDie:
- pusha
- bsr APlayNullAll
- lea ADie05,a0
- move #(ADie05_e-ADie05)/2,d0
- moveq #3,d1
- move #64,d2
- bsr APlay11Khz
- delayed_part #FPS/2,BonusPartExplode(pc)
- popa
- rts
- BonusPartExplode:
- pusha
- bsr APlayNullAll
- lea ABoobyExplode,a0
- move #(ABoobyExplode_e-ABoobyExplode)/2,d0
- moveq #0,d1
- move #63,d2
- bsr APlay11Khz
- moveq #1,d1
- bsr APlay11Khz
- delayed_part #FPS,StartGuru(pc)
- popa
- rts
- GuruColor:
- dc.w $0000,$0f00,$0000,$0000
- dcb.w 28,0
- StartGuru:
- pusha
- audio_off
- bsr LoadGuruCopper
- bsr APlayNullAll
- bsr ClearScreen
- ; Copy the screen
- lea GuruScreen,a0
- lea Screen+GURU_TOPLEFT,a1
- move #(GURU_H-1)*GURU_D,d0
- .screen_copy:
- move #GURU_BYPL-1,d1
- .line_copy:
- move.b (a0)+,(a1)+
- dbf d1,.line_copy
- add.l #SCREEN_BYPL-GURU_BYPL,a1
- dbf d0,.screen_copy
- bsr BlitWait
- ; Enable copper, audio and bitplane DMA and load the copper list
- move #$7fff,DMACON(a6)
- move #$87ef,DMACON(a6)
- move.l #Copper,COP1LCH(a6)
- next_part GuruPartRed(pc)
- popa
- rts
- LoadGuruCopper:
- pusha
- sub #copper_t,sp
- move.l sp,a0
- bsr InitCopperT
- move.b #GURU_D,copper_t.bitplanes(a0)
- move #SCREEN_BYPL*GURU_D-SCREEN_BYPL,copper_t.bpl1mod(a0)
- move #SCREEN_BYPL*GURU_D-SCREEN_BYPL,copper_t.bpl2mod(a0)
- bsr LoadCopper
- bsr LoadScreenToCopper
- lea GuruColor(pc),a0
- bsr LoadColorsToCopper
- lea CopperSprite,a0
- moveq #8,d0
- bsr PokeCopperNullSprite
- add #copper_t,sp
- popa
- rts
- GuruPartRed:
- ; Just blink until the end of time
- pusha
- move #$0f00,GuruColor+2
- lea GuruColor(pc),a0
- bsr LoadColorsToCopper
- delayed_part #FPS,GuruPartBlack(pc)
- popa
- rts
- GuruPartBlack:
- pusha
- move #$0000,GuruColor+2
- lea GuruColor(pc),a0
- bsr LoadColorsToCopper
- add #1,GuruUntilQuit
- cmp #10,GuruUntilQuit
- bne .noquit
- move #1,Quit
- .noquit:
- delayed_part #FPS,GuruPartRed(pc)
- popa
- rts
- GuruUntilQuit:
- dc.w 0
- ;;
- ;; SAS
- ;;
- ; get the SAS trooper position by index
- ; Arg1 - d-register with index
- ; Arg2 - a-register where to store the addresss
- SasIdxToPosAddr: MACRO
- lea SasPos0(pc),\2
- ext \1
- mulu #4,\1
- add.l \1,\2
- ENDM
- StepAllSasLeftToX:
- ; Args:
- ; d1 - long; X to stepto
- ; Result:
- ; d0 - number of troopers that moved
- pushnr
- move #1,d2
- lsl #NUM_SAS,d2
- subq #1,d2
- bsr StepMaskSasLeftToX
- popnr
- rts
- StepMaskSasLeftToX:
- ; Args:
- ; d1 - long; X to step to
- ; d2 - SAS mask - bits 3-0 -> SAS 3-0
- ; Result:
- ; d0 - number of troopers that moved
- pushnr
- move d2,d6
- clr.l d7
- btst #0,d6
- beq .sas_1
- clr.l d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_1:
- btst #1,d6
- beq .sas_2
- moveq #1,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_2:
- btst #2,d6
- beq .sas_3
- moveq #2,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_3:
- btst #3,d6
- beq .sas_e
- moveq #3,d2
- bsr StepSasLeftToX
- add d0,d7
- bsr PlotSas
- .sas_e:
- move d7,d0
- ext d0
- popnr
- rts
- StepSasLeftToX:
- ; Args:
- ; d1 - long; X to move to
- ; d2 - SAS 0, 1, 2 or 3
- ; Result:
- ; d0 - 1 if moved, 0 if not
- pushnr
- ; get the SAS trooper position by index
- SasIdxToPosAddr d2,a0
- move.l (a0),d0
- swap d0
- cmp d1,d0
- ble .no_move
- subq #1,d0
- move d0,d1
- swap d0
- move.l d0,(a0)
- moveq #1,d0
- bra .move
- .no_move:
- clr.l d0
- .move:
- popnr
- rts
- StepSasBottomToY:
- ; Args:
- ; d1 - long; Y to move to
- ; d2 - SAS 0, 1, 2 or 3
- ; Result:
- ; d0 - 1 if moved, 0 if not
- pushnr
- ; get the SAS trooper position by index
- SasIdxToPosAddr d2,a0
- move 2(a0),d0
- cmp d1,d0
- bge .no_move
- addq #1,d0
- move d0,2(a0)
- moveq.l #1,d0
- bra .move
- .no_move:
- clr.l d0
- .move:
- popnr
- rts
- PlotSas:
- ; d2 - SAS 0, 1, 2 or 3
- ;
- ; SAS 0, 1, 2 and 3 are the same sprite and they cannot occupy the
- ; same line. They must be separated by at least one blank line.
- pusha
- ; get SAS (x,y) in d0
- move.l d2,d0
- SasIdxToPosAddr d0,a0
- move.l (a0),d0
- ; We need to add both values separately or else the negative values
- ; won't be added properly (someone didn't do the job proply).
- add #$2c,d0
- swap d0
- add #SCREEN_X_MARGIN,d0
- swap d0
- move #SAS_H,d1
- mulu #SAS_BYTES,d2
- lea SasLeft,a0
- lea (a0,d2),a0
- bsr MoveSprite
- add.l #SAS_ATTACH,a0
- bsr MoveSprite
- add.l #$100000,d0
- lea SasRight,a0
- lea (a0,d2),a0
- bsr MoveSprite
- add.l #SAS_ATTACH,a0
- bsr MoveSprite
- popa
- rts
- _SAS_X = 420
- _SAS_Y = 25
- SasPos0:
- dc.w _SAS_X,_SAS_Y
- SasPos1:
- dc.w _SAS_X+57,_SAS_Y+SAS_H+5+1
- SasPos2:
- dc.w _SAS_X-3,_SAS_Y+2*SAS_H+10+2
- SasPos3:
- dc.w _SAS_X+4,_SAS_Y+3*SAS_H+15+3
- SasGrassWalkVolume:
- dc.w 0
- ;;
- ;; Bullets
- ;;
- BULLET_H = 1
- BULLET_BYTES = 4+4*BULLET_H
- NUM_BULLETS_MAX = 20
- bullet_t.x = 0
- bullet_t.y = 2
- bullet_t.dst_x = 4
- bullet_t.dst_y = 6
- bullet_t.src_x = 8
- bullet_t.src_y = 10
- bullet_t.live = 12
- bullet_t = 14
- BulletEngine:
- pusha
- bsr MoveBullets
- bsr PlotBullets
- popa
- rts
- FireBullet:
- ; Args:
- ; d0 - origin x
- ; d1 - origin y
- ; d2 - target x
- ; d3 - target y
- ; Result:
- ; d0 - index of fired bullet, or $ffff if cannot fire
- pushnr
- ; Find first free bullet on the list
- lea BulletList(pc),a0
- move #NUM_BULLETS_MAX-1,d7
- .loop_bullet_seek:
- move bullet_t.live(a0),d6
- tst d6
- beq .bullet_found
- add #bullet_t,a0
- dbf d7,.loop_bullet_seek
- ; Free bullet not found; bail
- move #$ffff,d0
- bra .done
- .bullet_found:
- ; The free bullet is in a0
- ; Let's init it
- move d0,bullet_t.x(a0)
- move d0,bullet_t.src_x(a0)
- move d1,bullet_t.y(a0)
- move d1,bullet_t.src_y(a0)
- move d2,bullet_t.dst_x(a0)
- move d3,bullet_t.dst_y(a0)
- move #1,bullet_t.live(a0)
- ; Return the index
- move #NUM_BULLETS_MAX-1,d0
- sub d7,d0
- .done:
- popnr
- rts
- MoveBullets:
- pusha
- lea BulletList(pc),a0
- move #NUM_BULLETS_MAX-1,d7
- .loop:
- tst bullet_t.live(a0)
- beq .continue
- move #4,d6 ; move bullet by many steps at once - bullets are fast
- .bullet_step:
- move bullet_t.src_x(a0),d0
- move bullet_t.src_y(a0),d1
- move bullet_t.dst_x(a0),d2
- move bullet_t.dst_y(a0),d3
- move bullet_t.x(a0),d4
- move bullet_t.y(a0),d5
- ; Has bullet reached its destination?
- cmp d2,d4
- bne .bullet_alive
- cmp d3,d5
- bne .bullet_alive
- ; bullet dead
- move #0,bullet_t.live(a0)
- bra .continue
- .bullet_alive:
- ext.l d0
- ext.l d1
- ext.l d2
- ext.l d3
- ext.l d4
- ext.l d5
- bsr BresenhamStepLine
- move d0,bullet_t.x(a0)
- move d1,bullet_t.y(a0)
- dbf d6,.bullet_step
- .continue:
- add.l #bullet_t,a0
- dbf d7,.loop
- popa
- rts
- PlotBullets:
- pusha
- move CurrentNumBulletsMax(pc),d7
- subq #1,d7
- move.l CurrentBulletSprite(pc),a0
- move #0,d0
- .bullet_loop:
- bsr NextYBullet
- tst.l d0
- beq .done
- ; plot bullet
- move.l d0,a1
- move bullet_t.x(a1),d0
- swap d0
- move bullet_t.y(a1),d0
- add.l #$80002c,d0
- move BulletHeight(pc),d1
- bsr MoveSprite
- add #BULLET_BYTES,a0 ; next bullet sprite
- move bullet_t.y(a1),d0 ; next y from which to start
- addq #1,d0
- dbf d7,.bullet_loop ; dbf is for infinite loop precaution
- .done:
- ; all remaining sprites must be removed from screen
- tst d7
- bmi .all_done
- .sprite_remove:
- move.l #0,(a0)
- add #BULLET_BYTES,a0
- dbf d7,.sprite_remove
- .all_done:
- popa
- rts
- BulletHeight:
- dc.w 1
- CurrentNumBulletsMax:
- dc.w 1
- CurrentBulletSprite:
- dc.l $ffffffff
- NextYBullet:
- ; Gets next bullet from the list that's closest to the passed Y
- ; Args:
- ; d0 - the Y value
- ; Result;
- ; d0 - addr of the closest bullet to the passed Y or 0 if none
- pushnr
- move.l #0,a1
- move #$ffff,d6 ; current Y distance
- lea BulletList(pc),a0
- move #NUM_BULLETS_MAX-1,d7
- .loop_bullets:
- ; dead bullets don't count
- tst bullet_t.live(a0)
- beq .continue_bullets
- ; has this bullet greater Y?
- cmp.w bullet_t.y(a0),d0
- bge .continue_bullets
- ; is this bullet closer than the previous one?
- move bullet_t.y(a0),d1
- sub d0,d1
- cmp d1,d6
- blo .continue_bullets
- ; we have a new closest bullet
- move d1,d6
- move.l a0,a1
- .continue_bullets:
- add.l #bullet_t,a0
- dbf d7,.loop_bullets
- move.l a1,d0
- popnr
- rts
- PaintBullets:
- pusha
- lea BulletSprite,a0
- move #NUM_BULLETS_MAX-1,d0
- .loop:
- move.b #%11000000,4(a0)
- move.b #%11000000,6(a0)
- add.l #8,a0
- dbf d0,.loop
- popa
- rts
- LoadShotgunPelletSprite:
- ; Args:
- ; a0 - copper address for sprite address poke
- pusha
- ; Only shotgun will be fired so we can hack the bullet engine
- ; to draw something else instead of the 1-pixel dot.
- move.l #PelletSprite,d0
- move.l d0,CurrentBulletSprite
- pokecopper d0,a0
- move #PELLET_H,BulletHeight
- move #1,CurrentNumBulletsMax
- popa
- rts
- BulletList:
- dcb.b bullet_t*NUM_BULLETS_MAX,0
- EVEN
- ;;
- ;; Grenade!
- ;;
- LoadGrenadeSprite:
- ; Args:
- ; a0 - Copper list where to load to
- pusha
- move.l #GrenadeSprite,d0
- pokecopper d0,a0
- add.l #GRENADE_ATTACH,d0
- addq.l #8,a0
- pokecopper d0,a0
- popa
- rts
- ;;
- ;; SFX
- ;;
- APlayGrenadeUnpin:
- ; Args:
- ; d1 - channel (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- lea AGrenadeUnpin,a0
- move #(AGrenadeUnpin_e-AGrenadeUnpin)/2,d0
- bsr APlay11Khz
- popa
- rts
- APlayGrenadeBounce:
- ; Args:
- ; d1 - channel (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- lea AGrenadeBounce,a0
- move #(AGrenadeBounce_e-AGrenadeBounce)/2,d0
- bsr APlay11Khz
- popa
- rts
- APlayGrenadeExplode:
- ; Args:
- ; d1 - channel (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- lea AGrenadeExplode,a0
- move #(AGrenadeExplode_e-AGrenadeExplode)/2,d0
- bsr APlay11Khz
- popa
- rts
- APlayGrassWalkManyBoth:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextGrassWalk
- move.l d0,a0 ; audio_t argument
- ; Iterate channel
- move .channel(pc),d1
- and #%11,d1
- bsr APlayAudioT8Khz
- popa
- rts
- .many_channel:
- dc.w 0
- .channel:
- dc.w 0
- APlayFloorWalkOneBoth:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextFloorWalk
- move.l d0,a0 ; audio_t argument
- moveq #0,d1
- bsr APlayAudioT8Khz
- moveq #1,d1
- bsr APlayAudioT8Khz
- popa
- rts
- APlayGrassWalkOneBoth:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextGrassWalk
- move.l d0,a0 ; audio_t argument
- moveq #0,d1
- bsr APlayAudioT8Khz
- moveq #1,d1
- bsr APlayAudioT8Khz
- moveq #2,d1
- bsr APlayNull
- moveq #3,d1
- bsr APlayNull
- popa
- rts
- APlayGrassWalkManyRight:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextGrassWalk
- move.l d0,a0 ; audio_t argument
- ; Pick channel
- moveq #1,d1 ; channel A
- move .many_channel(pc),d0
- addq #1,d0
- move d0,.many_channel
- btst #0,d0
- beq .play_it
- moveq #2,d1 ; channel B
- .play_it:
- bsr APlayAudioT8Khz
- popa
- rts
- .many_channel:
- dc.w 0
- APlayGrassWalkOneRight:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextGrassWalk
- move.l d0,a0 ; audio_t argument
- moveq #1,d1
- bsr APlayAudioT8Khz
- moveq #2,d1
- bsr APlayNull
- popa
- rts
- APlayGrassWalkManyLeft:
- ; Args:
- ; d2 - Volume (0 - 64)
- pusha
- bsr NextGrassWalk
- move.l d0,a0 ; audio_t argument
- ; Pick channel
- moveq #0,d1 ; channel A
- move .many_channel(pc),d0
- addq #1,d0
- move d0,.many_channel
- btst #0,d0
- beq .play_it
- moveq #3,d1 ; channel B
- .play_it:
- bsr APlayAudioT8Khz
- popa
- rts
- .many_channel:
- dc.w 0
- NextAudio:
- ; Args:
- ; d0 - total count of elements on list
- ; a0 - audio_t; list address
- ; a1 - word; index address
- ; Result:
- ; d0 - address to the current structure on the list,
- ; a1 - counter is incremented
- pushnr
- ; Load the current sound and iterate the offset to the next one
- ; until we run out of sounds.
- move (a1),d7
- move d7,d6
- ext d6
- mulu #audio_t,d6
- add.l d6,a0
- addq #1,d7
- cmp d0,d7
- blt .loaded
- clr d7
- .loaded:
- move d7,(a1)
- move.l a0,d0
- popnr
- rts
- NextGrassWalk:
- ; Result:
- ; d0 - pointer to the audio_t structure
- pushnr
- move #NUM_GRASS_WALK,d0
- lea GrassWalkList(pc),a0
- lea GrassWalkIndex(pc),a1
- bsr NextAudio
- popnr
- rts
- InitGrassWalkList:
- pusha
- lea GrassWalkList(pc),a0
- lea AGrassWalk1,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk1_e-AGrassWalk1)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AGrassWalk2,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk2_e-AGrassWalk2)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AGrassWalk3,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk3_e-AGrassWalk3)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AGrassWalk4,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk4_e-AGrassWalk4)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AGrassWalk2,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk2_e-AGrassWalk2)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AGrassWalk3,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AGrassWalk3_e-AGrassWalk3)/2,audio_t.length(a0)
- add.l #audio_t,a0
- popa
- rts
- GrassWalkList:
- dcb.b audio_t*NUM_GRASS_WALK,0
- GrassWalkIndex:
- dc.w 0
- NextFloorWalk:
- ; Result:
- ; d0 - pointer to the audio_t structure
- pushnr
- move #NUM_FLOOR_WALK,d0
- lea FloorWalkList(pc),a0
- lea FloorWalkIndex(pc),a1
- bsr NextAudio
- popnr
- rts
- InitFloorWalkList:
- pusha
- lea FloorWalkList(pc),a0
- lea AFloorWalk1,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk1_e-AFloorWalk1)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AFloorWalk2,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk2_e-AFloorWalk2)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AFloorWalk3,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk3_e-AFloorWalk3)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AFloorWalk4,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk4_e-AFloorWalk4)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AFloorWalk2,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk2_e-AFloorWalk2)/2,audio_t.length(a0)
- add.l #audio_t,a0
- lea AFloorWalk3,a1
- move.l a1,audio_t.pointer(a0)
- move.l #(AFloorWalk3_e-AFloorWalk3)/2,audio_t.length(a0)
- add.l #audio_t,a0
- popa
- rts
- FloorWalkList:
- dcb.b audio_t*NUM_FLOOR_WALK,0
- FloorWalkIndex:
- dc.w 0
- ;;
- ;; Routines
- ;;
- InitCopperT:
- ; Args:
- ; a0 - copper_t structure to init
- pusha
- move.b #5,copper_t.bitplanes(a0)
- move.b #INTERLACED,copper_t.interlaced(a0)
- move #SCREEN_BYWIDTH-SCREEN_BYPL,copper_t.bpl1mod(a0)
- move #SCREEN_BYWIDTH-SCREEN_BYPL,copper_t.bpl2mod(a0)
- move #$2c81,copper_t.diwstrt(a0)
- move #$2cc1,copper_t.diwstop(a0)
- move #$38,copper_t.ddfstrt(a0)
- move #$d0,copper_t.ddfstop(a0)
- move #$0707,copper_t.wait(a0)
- popa
- rts
- LoadFullScreenCopper:
- pusha
- sub #copper_t,sp
- move.l sp,a0
- bsr InitCopperT
- bsr LoadCopper
- add #copper_t,sp
- popa
- rts
- LoadCopper:
- ; Loads the 'Copper' copper list with the specifications
- ; provided by the copper_t structure.
- ;
- ; Args:
- ; a0 - pointer to a copper_t structure
- pusha
- move #$0200,d1
- move.b copper_t.interlaced(a0),d0
- tst.b d0
- beq .progressive
- or #$4,d1
- .progressive:
- move d1,CopperBplcon0+2
- move d1,CopperScreenControl+2
- move.b copper_t.bitplanes(a0),d0
- lsl #8,d0
- lsl #4,d0
- or d0,CopperScreenControl+2
- move copper_t.bpl1mod(a0),CopperScreenControl+2*4+2
- move copper_t.bpl2mod(a0),CopperScreenControl+3*4+2
- move copper_t.diwstrt(a0),CopperWindowControl+2
- move copper_t.diwstop(a0),CopperWindowControl+1*4+2
- move copper_t.ddfstrt(a0),CopperWindowControl+2*4+2
- move copper_t.ddfstop(a0),CopperWindowControl+3*4+2
- move copper_t.wait(a0),CopperWait
- popa
- rts
- LoadScreenToCopper:
- ; Load screen bitplane to the copper list
- pusha
- move.l #Screen,d0
- lea CopperScreen,a0
- move.l #SCREEN_D-1,d1
- .screen_load:
- pokecopper d0,a0
- add.l #SCREEN_BYPL,d0
- addq.l #8,a0
- dbf d1,.screen_load
- popa
- rts
- LoadColorsToCopper:
- ; Args:
- ; a0 - a 32-color table
- pusha
- lea CopperColor,a1
- move #32,d0
- bsr PokeCopperWords
- popa
- rts
- ClearScreen:
- pusha
- lea Screen,a0
- move #(Screen_e-Screen)/4,d0
- .loop:
- clr.l (a0)+
- dbf d0,.loop
- popa
- rts
- DimScreen:
- ; Args:
- ; a0 - Color table address
- ; a1 - Copperlist color list address
- ; d0 - Colors count
- pusha
- move.l a1,a2
- lea BlackColors(pc),a1
- move #$0111,d2
- bsr ColorTableFadeTo
- move.l a2,a1
- bsr PokeCopperWords
- popa
- rts
- ColorTableFadeTo:
- ; Increases or decreases each color to match its counterpart in the
- ; other table.
- ; Args:
- ; a0 - fade table; contents will be modified
- ; a1 - fade-to table; read-only
- ; d0 - number of colors
- ; d2 - absolute step (one nibble for each RGB)
- pusha
- subq #1,d0
- move d0,d7
- .loop:
- move (a0),d0
- move (a1)+,d1
- ; d2 has the correct value already
- bsr ColorFadeTo
- move d0,(a0)+
- dbf d7,.loop
- popa
- rts
- ColorFadeTo:
- ; Increases or decreases source RGB components to match the target RGB.
- ; Args:
- ; d0 - RGB color to change
- ; d1 - target RGB
- ; d2 - absolute step (one nibble for each RGB)
- ; Result:
- ; d0 - stepped RGB
- pushnr
- move d0,d3
- move d1,d4
- move d2,d5
- ; B
- and #$f,d0
- and #$f,d1
- and #$f,d2
- bsr NumberFadeTo
- and #$ff0,d3
- or d0,d3
- ; G
- move d3,d0
- lsr #4,d0
- and #$f,d0
- move d4,d1
- lsr #4,d1
- and #$f,d1
- move d5,d2
- lsr #4,d2
- and #$f,d2
- bsr NumberFadeTo
- lsl #4,d0
- and #$f0f,d3
- or d0,d3
- ; R
- move d3,d0
- lsr #8,d0
- and #$f,d0
- move d4,d1
- lsr #8,d1
- and #$f,d1
- move d5,d2
- lsr #8,d2
- and #$f,d2
- bsr NumberFadeTo
- lsl #8,d0
- and #$0ff,d3
- or d0,d3
- move d3,d0
- popnr
- rts
- NumberFadeTo:
- ; Fades source number to target by given step.
- ; Operates on words; figures out if step should be positive or negative.
- ;
- ; Args:
- ; d0 - source number
- ; d1 - target number
- ; d2 - absolute fade step
- ; Result:
- ; d0 - number faded by step or equal to the target
- ;
- ; if abs(target-source) >= step
- ; return target
- ; else
- ; if target > source
- ; return source + step
- ; else
- ; return source - step
- pushnr
- ; Get absolute delta (d3)
- move d1,d3
- sub d0,d3
- bpl .already_positive
- neg d3
- .already_positive:
- ; If delta <= step, return the target
- cmp d2,d3
- bgt .do_step
- move d1,d0
- bra .done
- .do_step:
- cmp d0,d1
- bgt .add
- sub d2,d0
- bra .done
- .add:
- add d2,d0
- .done:
- popnr
- rts
- MoveSpriteAttached:
- ; Args - same as in MoveSprite
- pusha
- bsr MoveSprite
- move d1,d2
- ext.l d2
- asl #2,d2 ; multiply by 4 bytes per each line
- add.l d2,a0
- add.l #8,a0
- bsr MoveSprite
- popa
- rts
- MoveSprite:
- ; Moves sprite to a given (x,y) coordinate.
- ;
- ; Args:
- ; d0
- ; - hi-word: x
- ; - lo-word: y
- ; d1
- ; - lo-word: sprite height
- ; a0 - sprite address
- pusha
- ; y
- move.b d0,(a0)
- bclr #2,3(a0)
- cmp #$ff,d0
- ble .under_y1_256
- bset #2,3(a0)
- .under_y1_256:
- ; h
- add d0,d1
- move.b d1,2(a0)
- bclr #1,3(a0)
- cmp #$ff,d1
- ble .under_y2_256
- bset #1,3(a0)
- .under_y2_256:
- ; x
- swap d0
- bclr #0,3(a0)
- btst #0,d0
- beq .even_x
- bset #0,3(a0)
- .even_x:
- lsr #1,d0
- move.b d0,1(a0)
- popa
- rts
- BlitMasked:
- ; Args:
- ; a0 - pic to blit
- ; a1 - blit mask
- ; a2 - blit destination
- ; d2 - word; blit depth
- ; d3 - word; blit src width
- ; d4 - word; blit height
- ; d5 - word; blit dst width
- pusha
- bsr BlitWait
- move.l #$0fe20000,BLTCON0(a6)
- move.l #$ffffffff,BLTAFWM(a6)
- move.l a0,BLTAPTH(a6)
- move.l a1,BLTBPTH(a6)
- move.l a2,BLTCPTH(a6)
- move.l a2,BLTDPTH(a6)
- move #0,BLTAMOD(a6)
- move #0,BLTBMOD(a6)
- ; destination modulo
- move d5,d7
- sub d3,d7
- lsr #3,d7
- move d7,BLTCMOD(a6)
- move d7,BLTDMOD(a6)
- ; size
- ext.l d4
- mulu d2,d4 ; depth
- lsl #6,d4 ; shift height
- lsr #4,d3 ; add width in words
- and #$ffc0,d4
- or d3,d4
- move d4,BLTSIZE(a6)
- popa
- rts
- BlitMaskedXY:
- ; Args:
- ; a0 - pic to blit
- ; a1 - blit mask
- ; a2 - blit destination
- ; d0 - word; blit x \ added to
- ; d1 - word; blit y / destination
- ; d2 - word; blit depth
- ; d3 - word; blit src width
- ; d4 - word; blit height
- ; d5 - word; blit dst width
- pusha
- bsr BlitWait
- ; Designate the blit shift
- move d0,d7
- and.l #$f,d7
- ext.l d7
- lsl.l #8,d7
- lsl.l #4,d7
- move.l d7,d6
- swap d6
- or.l d6,d7
- or.l #$0fe20000,d7
- move.l d7,BLTCON0(a6)
- move.l #$ffffffff,BLTAFWM(a6)
- ; Designate the x word offset
- lsr #4,d0
- lsl #1,d0
- add d0,a2
- ; Designate the y offset
- and.l #$0000ffff,d1
- move d5,d7
- lsr #3,d7
- mulu d7,d1
- mulu d2,d1
- add.l d1,a2
- move.l a0,BLTAPTH(a6)
- move.l a1,BLTBPTH(a6)
- move.l a2,BLTCPTH(a6)
- move.l a2,BLTDPTH(a6)
- move #0,BLTAMOD(a6)
- move #0,BLTBMOD(a6)
- ; destination modulo
- move d5,d7
- sub d3,d7
- lsr #3,d7
- move d7,BLTCMOD(a6)
- move d7,BLTDMOD(a6)
- ; size
- ext.l d4
- mulu d2,d4 ; depth
- lsl #6,d4 ; shift height
- lsr #4,d3 ; add width in words
- and #$ffc0,d4
- or d3,d4
- move d4,BLTSIZE(a6)
- popa
- rts
- BlitBackground:
- ; Blits selected area of screen background back to its place.
- ; The blit x must be on the word boundary or else the blit will suck.
- ;
- ; Args:
- ; a0 - background
- ; a2 - blit destination
- ; d0 - word; x \ added to background
- ; d1 - word; y / and destination
- ; d2 - word; blit depth
- ; d3 - word; blit width
- ; d4 - word; blit height
- ; d5 - word; total width
- pusha
- bsr BlitWait
- move.l #$09f00000,BLTCON0(a6)
- move.l #$ffffffff,BLTAFWM(a6)
- ; Designate the x word offset
- lsr #4,d0
- lsl #1,d0
- add d0,a0
- add d0,a2
- ; Designate the y offset
- and.l #$0000ffff,d1
- move d5,d7
- lsr #3,d7
- mulu d7,d1
- mulu d2,d1
- add.l d1,a0
- add.l d1,a2
- move.l a0,BLTAPTH(a6)
- move.l a2,BLTDPTH(a6)
- ; modulo
- move d5,d7
- sub d3,d7
- lsr #3,d7
- move d7,BLTAMOD(a6)
- move d7,BLTDMOD(a6)
- ; size
- ext.l d4
- mulu d2,d4 ; depth
- lsl #6,d4 ; shift height
- lsr #4,d3 ; add width in words
- and #$ffc0,d4
- or d3,d4
- move d4,BLTSIZE(a6)
- popa
- rts
- BlitXY:
- ; Good for blitting rectangles.
- ;
- ; Args:
- ; a0 - pic to blit
- ; a2 - blit destination
- ; d0 - word; blit x \ added to
- ; d1 - word; blit y / destination
- ; d2 - word; blit depth
- ; d3 - word; blit src width
- ; d4 - word; blit height
- ; d5 - word; blit dst width
- pusha
- bsr BlitWait
- ; Designate the blit shift
- move d0,d7
- and.l #$f,d7
- ext.l d7
- lsl.l #8,d7
- lsl.l #4,d7
- move.l d7,d6
- swap d6
- or.l d6,d7
- or.l #$09f00000,d7
- move.l d7,BLTCON0(a6)
- move.l #$ffffffff,BLTAFWM(a6)
- ; Designate the x word offset
- lsr #4,d0
- lsl #1,d0
- add d0,a2
- ; Designate the y offset
- and.l #$0000ffff,d1
- move d5,d7
- lsr #3,d7
- mulu d7,d1
- mulu d2,d1
- add.l d1,a2
- move.l a0,BLTAPTH(a6)
- move.l a2,BLTDPTH(a6)
- ; destination modulo
- move d5,d7
- sub d3,d7
- lsr #3,d7
- move d7,BLTDMOD(a6)
- ; size
- ext.l d4
- mulu d2,d4 ; depth
- lsl #6,d4 ; shift height
- lsr #4,d3 ; add width in words
- and #$ffc0,d4
- or d3,d4
- move d4,BLTSIZE(a6)
- popa
- rts
- BlitWait:
- tst DMACONR(a6)
- .blitwait:
- btst #6,DMACONR(a6)
- bne.s .blitwait
- rts
- BresenhamStepLine:
- ; Gets next point on a straight line from source (X,Y) to
- ; destination (X,Y) by using only ints to do so.
- ;
- ; All args are long
- ; Args:
- ; d0 - x0
- ; d1 - y0
- ; d2 - x1
- ; d3 - y1
- ; d4 - x current
- ; d5 - y current
- ; Result:
- ; d0 - next x
- ; d1 - next y
- movem.l d2-a6,-(sp)
- ; dx, dy = x1 - x0, y1 - y0
- move.l d2,d7
- sub.l d0,d7
- move.l d7,.dx
- move.l d3,d7
- sub.l d1,d7
- move.l d7,.dy
- ; dx >= 0 ? incx = +1 : incx = -1
- ; dy >= 0 ? incy = +1 : incy = -1
- move.l #1,.incx
- move.l .dx(pc),d7
- tst.l d7
- bge .pos_x
- move.l #-1,.incx
- .pos_x:
- move.l #1,.incy
- move.l .dy(pc),d7
- tst.l d7
- bge .pos_y
- move.l #-1,.incy
- .pos_y:
- ; abs dx,dy
- move.l .dx(pc),d7
- bpl .no_abs_dx
- neg.l d7
- move.l d7,.dx
- .no_abs_dx:
- move.l .dy(pc),d7
- bpl .no_abs_dy
- neg.l d7
- move.l d7,.dy
- .no_abs_dy:
- ; x = 0, y = 0
- ; the dst values won't be needed anymore
- clr.l d2
- clr.l d3
- move #0,.bail
- ; the big if/else choice
- ; dx >= dy
- move.l .dx(pc),d6
- move.l .dy(pc),d7
- cmp d7,d6
- blt .dx_lesser_than_dy
- ; it is: dx >= dy
- ; d = 2*dy-dx
- ; delta_a = 2*dy
- ; delta_b = 2*dy-2*dx
- move.l .dy(pc),d7
- lsl.l #1,d7
- move.l d7,.delta_a
- sub.l .dx(pc),d7
- move.l d7,.d
- sub.l .dx(pc),d7
- move.l d7,.delta_b
- ; for (i=dx, i>=0, --i)
- move.l .dx(pc),d6
- .for1:
- ; if (x == cur_x && y == cur_y)
- ; bail in this iteration
- move.l d0,d7
- add.l d2,d7
- cmp.l d4,d7
- bne .no_bail1
- move.l d1,d7
- add.l d3,d7
- cmp.l d5,d7
- bne .no_bail1
- move #1,.bail
- .no_bail1:
- move.l .d(pc),d7
- ; if (d > 0)
- tst.l d7
- ble .else1
- ; d += delta_b
- ; x += incx
- ; y += incy
- add.l .delta_b(pc),d7
- move.l d7,.d
- add.l .incx(pc),d2
- add.l .incy(pc),d3
- bra .continue1
- .else1:
- ; d += delta_a
- ; x += incx
- add.l .delta_a(pc),d7
- move.l d7,.d
- add.l .incx(pc),d2
- .continue1:
- move .bail(pc),d7
- tst d7
- bne .done
- dbf d6,.for1
- bra .done
- .dx_lesser_than_dy:
- ; it is: dy < dx
- ; d = 2*dx-dy
- ; delta_a = 2*dx
- ; delta_b = 2*dx-2*dy
- move.l .dx(pc),d7
- lsl.l #1,d7
- move.l d7,.delta_a
- sub.l .dy(pc),d7
- move.l d7,.d
- sub.l .dy(pc),d7
- move.l d7,.delta_b
- ; for (i=dy, i>=0, --i)
- move.l .dy(pc),d6
- .for2:
- ; if (x == cur_x && y == cur_y)
- ; bail in this iteration
- move.l d0,d7
- add.l d2,d7
- cmp.l d4,d7
- bne .no_bail2
- move.l d1,d7
- add.l d3,d7
- cmp.l d5,d7
- bne .no_bail2
- move #1,.bail
- .no_bail2:
- move.l .d(pc),d7
- ; if (d > 0)
- tst.l d7
- ble .else2
- ; d += delta_b
- ; x += incx
- ; y += incy
- add.l .delta_b(pc),d7
- move.l d7,.d
- add.l .incx(pc),d2
- add.l .incy(pc),d3
- bra .continue2
- .else2:
- ; d += delta_a
- ; y += incy
- add.l .delta_a(pc),d7
- move.l d7,.d
- add.l .incy(pc),d3
- .continue2:
- move .bail(pc),d7
- tst d7
- bne .done
- dbf d6,.for2
- .done:
- add.l d2,d0
- add.l d3,d1
- movem.l (sp)+,d2-a6
- rts
- .dx:
- dc.l 0
- .dy:
- dc.l 0
- .incx:
- dc.l 1
- .incy:
- dc.l 1
- .d:
- dc.l 0
- .delta_a:
- dc.l 0
- .delta_b:
- dc.l 0
- .bail:
- dc.w 0
- PokeCopperWords:
- ; Args:
- ; a0 - the word value table in memory
- ; a1 - copper register listing start
- ; d0 - word; how many values to poke
- pusha
- subq #1,d0
- .loop:
- add #2,a1 ; skip the register
- move (a0)+,(a1)+
- dbf d0,.loop
- popa
- rts
- APlayAudioT8Khz:
- ; Args:
- ; a0 - audio_t to play
- ; d1 - Channel to play on (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- move.l audio_t.length(a0),d0
- move.l audio_t.pointer(a0),a0
- bsr APlay8Khz
- popa
- rts
- APlayAudioT11Khz:
- ; Args:
- ; a0 - audio_t to play
- ; d1 - Channel to play on (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- move.l audio_t.length(a0),d0
- move.l audio_t.pointer(a0),a0
- bsr APlay11Khz
- popa
- rts
- APlay8Khz:
- ; Args:
- ; a0 - Audio to play
- ; d0 - Length of the audio in words
- ; d1 - Channel to play on (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- move.l #AUD0LCH,d7
- mulu #AUD_INTERCHANNEL_OFFSET,d1
- add.l d1,d7
- move.l a0,AUDXLCH(a6,d7)
- move d0,AUDXLEN(a6,d7)
- move #447,AUDXPER(a6,d7)
- move d2,AUDXVOL(a6,d7)
- popa
- rts
- APlay11Khz:
- ; Args:
- ; a0 - Audio to play
- ; d0 - Length of the audio in words
- ; d1 - Channel to play on (0 - 3)
- ; d2 - Volume (0 - 64)
- pusha
- move.l #AUD0LCH,d7
- mulu #AUD_INTERCHANNEL_OFFSET,d1
- add.l d1,d7
- move.l a0,AUDXLCH(a6,d7)
- move d0,AUDXLEN(a6,d7)
- move #324,AUDXPER(a6,d7)
- move d2,AUDXVOL(a6,d7)
- popa
- rts
- APlayNullAll:
- ; Play null audio sample (silence) on all channels.
- bsr APlayNullLeft
- bsr APlayNullRight
- rts
- APlayNullLeft:
- ; Play null audio sample (silence) on left channels.
- pusha
- clr d1
- bsr APlayNull
- moveq #3,d1
- bsr APlayNull
- popa
- rts
- APlayNullRight:
- ; Play null audio sample (silence) on right channels.
- pusha
- moveq #1,d1
- bsr APlayNull
- moveq #2,d1
- bsr APlayNull
- popa
- rts
- APlayNull:
- ; Play null audio sample (silence).
- ; Args:
- ; d1 - Channel to play on (0 - 3)
- pusha
- move.l #AUD0LCH,d7
- mulu #AUD_INTERCHANNEL_OFFSET,d1
- add.l d1,d7
- lea ANull,a0
- move #(ANull_e-ANull)/2,d0
- move.l a0,AUDXLCH(a6,d7)
- move d0,AUDXLEN(a6,d7)
- popa
- rts
- MemCmp:
- ; Args:
- ; a0 - mem area a
- ; a1 - mem area b
- ; d1 - long; area len
- ; Result:
- ; d0 - equal to d1 if areas are the same, otherwise
- ; equal to the length at which the areas differ
- pushnr
- clr.l d0
- subq #1,d1
- .loop:
- move.b (a0)+,d2
- cmp.b (a1)+,d2
- bne .done
- addq.l #1,d0
- dbf d1,.loop
- .done:
- popnr
- rts
- SECTION storage,DATA
- P2Scene:
- incbin "grass.320x256x4.raw"
- P2Scene_e:
- P3Scene:
- incbin "part3.320x256x5.raw"
- P3Scene_e:
- P4Scene:
- incbin "part4.320x256x5.raw"
- P4Scene_e:
- P5Scene:
- incbin "part5.320x256x5.raw"
- P5Scene_e:
- MissionSuccess:
- incbin "mission_success.320x49x3.raw"
- MissionSuccess_e:
- BonusScreen:
- incbin "hostbomb.104x128x4.raw"
- BonusScreen_e:
- GuruScreen:
- incbin "gurumedi.293x51x1.raw"
- GuruScreen_e:
- ;;
- ;; CHIP MEM
- ;;
- SECTION chip,DATA_C
- SectionChip:
- Logo:
- incbin "regilogo.300x95x3.raw"
- LogoE:
- DoorOpen:
- incbin "dooropen.64x128x5.raw"
- DoorOpen_e:
- DoorClosed:
- incbin "doorclosed.64x128x5.raw"
- DoorClosed_e:
- DoorMask:
- incbin "door.mask.raw"
- DoorMask_e:
- P3Sas:
- incbin "p3_sas.32x44x5.raw"
- P3Sas_e:
- P3SasMask:
- incbin "p3_sas.mask.raw"
- P3SasMask_e:
- P3SasDead:
- incbin "p3_sas_dead.32x44x5.raw"
- P3SasDead_e:
- P3SasDeadMask:
- incbin "p3_sas_dead.mask.raw"
- P3SasDeadMask_e:
- P3PaskudnyDead:
- incbin "p3_paskudny_dead.48x44x5.raw"
- P3PaskudnyDead_e:
- P3PaskudnyDeadMask:
- incbin "p3_paskudny_dead.mask.raw"
- P3PaskudnyDeadMask_e:
- P3WiesniakDead:
- incbin "p3_wiesniak_dead.32x43x5.raw"
- P3WiesniakDead_e:
- P3WiesniakDeadMask:
- incbin "p3_wiesniak_dead.mask.raw"
- P3WiesniakDeadMask_e:
- P460s:
- incbin "p4_60s.32x48x5.raw"
- P460s_e:
- P460sMask:
- incbin "p4_60s.mask.raw"
- P460sMask_e:
- P4Bomb:
- incbin "p4_tnt.96x171x5.raw"
- P4Bomb_e:
- P4BombMask:
- incbin "p4_tnt.mask.raw"
- P4BombMask_e:
- EVEN
- P5SaddamDead:
- incbin "saddam_dead.32x52x5.raw"
- P5SaddamDead_e:
- EVEN
- P5SaddamMask:
- incbin "saddam_dead.mask.raw"
- P5SaddamMask_e:
- EVEN
- AIntro:
- incbin "intro_begin_11k.raw"
- AIntro_e:
- EVEN
- ABriefing:
- incbin "briefing_11k.raw"
- ABriefing_e:
- EVEN
- ASasBooby: ; it's less fun than it sounds
- incbin "sas_booby_11k.raw"
- ASasBooby_e:
- EVEN
- ASasBluOnBlu:
- incbin "sas_blu_11k.raw"
- ASasBluOnBlu_e:
- EVEN
- ASasGoGoGo:
- incbin "gogogo_11k.raw"
- ASasGoGoGo_e:
- EVEN
- ASasEnemyContact:
- incbin "sas_contact_11k.raw"
- ASasEnemyContact_e:
- EVEN
- ASasManDown:
- incbin "sas_mandown_01_11k.raw"
- ASasManDown_e:
- EVEN
- ASasMedic:
- incbin "sas_medic_11k.raw"
- ASasMedic_e:
- EVEN
- ASasHurt:
- incbin "sas_hit_1_11k.raw"
- ASasHurt_e:
- EVEN
- AXrayDieUBastards:
- incbin "xray_die_u_bastards_11k.raw"
- AXrayDieUBastards_e:
- EVEN
- AXrayDontShoot:
- incbin "xray_dontshoot_11k.raw"
- AXrayDontShoot_e:
- EVEN
- AXrayTroopers:
- incbin "xray_troopers_11k.raw"
- AXrayTroopers_e:
- EVEN
- AXrayYouBloodyFools:
- incbin "xray_youbloodyfools_11k.raw"
- AXrayYouBloodyFools_e:
- EVEN
- AXrayAndItsYourFault:
- incbin "xray_anditsyourfault_11k.raw"
- AXrayAndItsYourFault_e:
- EVEN
- AHostThankYou:
- incbin "host_thankyou_11k.raw"
- AHostThankYou_e:
- EVEN
- ADie05:
- incbin "die_05_11k.raw"
- ADie05_e:
- EVEN
- ADie06:
- incbin "die_06_11k.raw"
- ADie06_e:
- EVEN
- ADie07:
- incbin "die_07_11k.raw"
- ADie07_e:
- EVEN
- AAk47_1:
- incbin "ak47_01_11k.raw"
- AAk47_1_e:
- EVEN
- EVEN
- AAk47Burst:
- incbin "ak47_burst.raw"
- AAk47Burst_e:
- EVEN
- AMp5_1:
- incbin "mp5_01_11k.raw"
- AMp5_1_e:
- EVEN
- AMp5_2:
- incbin "mp5_02_11k.raw"
- AMp5_2_e:
- EVEN
- EVEN
- AShotgun:
- incbin "shotgun_11k.raw"
- AShotgun_e:
- EVEN
- AGrenadeUnpin:
- incbin "grenade_unpin_11k.raw"
- AGrenadeUnpin_e:
- EVEN
- AGrenadeBounce:
- incbin "grenade_bounce_11k.raw"
- AGrenadeBounce_e:
- EVEN
- AGrenadeExplode:
- incbin "grenade_explode_11k.raw"
- AGrenadeExplode_e:
- EVEN
- ABoobyTripped:
- incbin "booby_tripped_11k.raw"
- ABoobyTripped_e:
- EVEN
- ABoobyExplode:
- incbin "big_explode_11k.raw"
- ABoobyExplode_e:
- EVEN
- ADoorOpen:
- incbin "dooropen_11k.raw"
- ADoorOpen_e:
- EVEN
- AGrassWalk1:
- incbin "grass_walk_01_8k.raw"
- AGrassWalk1_e:
- EVEN
- AGrassWalk2:
- incbin "grass_walk_02_8k.raw"
- AGrassWalk2_e:
- EVEN
- AGrassWalk3:
- incbin "grass_walk_03_8k.raw"
- AGrassWalk3_e:
- EVEN
- AGrassWalk4:
- incbin "grass_walk_04_8k.raw"
- AGrassWalk4_e:
- EVEN
- AFloorWalk1:
- incbin "stone_walk_01_8k.raw"
- AFloorWalk1_e:
- EVEN
- AFloorWalk2:
- incbin "stone_walk_02_8k.raw"
- AFloorWalk2_e:
- EVEN
- AFloorWalk3:
- incbin "stone_walk_03_8k.raw"
- AFloorWalk3_e:
- EVEN
- AFloorWalk4:
- incbin "stone_walk_04_8k.raw"
- AFloorWalk4_e:
- EVEN
- AWin:
- incbin "win_8k.raw"
- AWin_e:
- EVEN
- ANull:
- dc.w 0,0
- ANull_e:
- EVEN
- BulletSprite:
- dcb.w 4*NUM_BULLETS_MAX,0
- dc.w 0,0
- EVEN
- PelletSprite:
- dc.w $0,$0
- dc.w %0000000000000000,%0000011011010000
- dc.w %0000010011010000,%0000110111011000
- dc.w %0001011110110100,%0001011110110100
- dc.w %0001101011011000,%0101101011011000
- dc.w %0010011011010100,%0010011011010110
- dc.w %0001010101011000,%1001111101111001
- dc.w %0011101010101100,%0011111111111110
- dc.w %0001010111010100,%1001010111010100
- dc.w %0010110010011100,%1010111011011100
- dc.w %0101011101100100,%0101011111110110
- dc.w %0011110110110100,%1011110110111100
- dc.w %0001011011011100,%0001111011011100
- dc.w %0111010110110100,%0111011111110110
- dc.w %0000101001011000,%0011111011011010
- dc.w %0000011011010000,%0001011011010000
- dc.w %0000000000000000,%0000101010101000
- dc.w $0,$0
- ; Grenade is an attached sprite
- EVEN
- GrenadeSprite:
- include "grenade.sprite"
- EVEN
- BoomSprite:
- include "boom.sprite"
- EVEN
- SasLeft:
- include "sas.sprite_16.s"
- SasLeft_e:
- SasRight:
- include "sas.sprite_16p2.s"
- SasRight_e:
- EVEN
- NullSprite:
- dc.w $2a20,$2b00
- dc.w 0,0
- dc.w 0,0
- EVEN
- P1Copper:
- dc.w $1fc,0 ; slow fetch mode, AGA compatibility
- dc.w BPLCON0,$0200!(INTERLACED<<2)
- dc.w BPLCON1,$0
- P1CopperColor:
- dc.w $0180,$0,$0182,$0,$0184,$0,$0186,$0
- dc.w $0188,$0,$018a,$0,$018c,$0,$018e,$0
- dc.w $8007,$fffe
- P1CopperLogo:
- dc.w BPL1PTH,0
- dc.w BPL1PTL,0
- dc.w BPL2PTH,0
- dc.w BPL2PTL,0
- dc.w BPL3PTH,0
- dc.w BPL3PTL,0
- dc.w BPLCON0,(LOGO_D<<12)!$204
- dc.b 0,DIWSTRT,$80,81
- dc.b 0,DIWSTOP,$2c,$c1-LOGO_MARGIN
- dc.w DDFSTRT,$38+LOGO_MARGIN/2
- dc.w DDFSTOP,$d0-LOGO_MARGIN/2
- dc.w BPL1MOD,0
- dc.w BPL2MOD,0
- dc.b $80+LOGO_H,$07,$ff,$fe
- dc.w BPLCON0,$0200!(INTERLACED<<2)
- dc.w $ffff,$fffe
- EVEN
- Copper:
- dc.w $1fc,0 ; slow fetch mode, AGA compatibility
- CopperBplcon0:
- dc.w BPLCON0,$0204
- dc.w BPLCON1,$0
- CopperWindowControl:
- dc.w DIWSTRT,$2c81
- dc.w DIWSTOP,$2cc1
- dc.w DDFSTRT,$38
- dc.w DDFSTOP,$d0
- CopperColor:
- dc.w $0180,$0111,$0182,$0b89,$0184,$0b8a,$0186,$0742
- dc.w $0188,$0665,$018a,$0c9a,$018c,$0aaa,$018e,$0bad
- dc.w $0190,$0734,$0192,$0745,$0194,$0956,$0196,$0867
- dc.w $0198,$0a68,$019a,$0978,$019c,$0a77,$019e,$0b79
- dc.w $01a0,$0a89,$01a2,$0111,$01a4,$0222,$01a6,$0333
- dc.w $01a8,$0444,$01aa,$0555,$01ac,$0666,$01ae,$0866
- dc.w $01b0,$0777,$01b2,$0888,$01b4,$0bab,$01b6,$0000
- dc.w $01b8,$0800,$01ba,$0f00,$01bc,$0780,$01be,$0ff0
- CopperWait:
- dc.w $0707,$fffe
- CopperSprite:
- dc.w SPRITE0,0
- dc.w SPRITE0+2,0
- dc.w SPRITE1,0
- dc.w SPRITE1+2,0
- dc.w SPRITE2,0
- dc.w SPRITE2+2,0
- dc.w SPRITE3,0
- dc.w SPRITE3+2,0
- dc.w SPRITE4,0
- dc.w SPRITE4+2,0
- dc.w SPRITE5,0
- dc.w SPRITE5+2,0
- CopperSprite6:
- dc.w SPRITE6,0
- dc.w SPRITE6+2,0
- CopperSprite7:
- dc.w SPRITE7,0
- dc.w SPRITE7+2,0
- CopperScreen:
- dc.w BPL1PTH,0
- dc.w BPL1PTL,0
- dc.w BPL2PTH,0
- dc.w BPL2PTL,0
- dc.w BPL3PTH,0
- dc.w BPL3PTL,0
- dc.w BPL4PTH,0
- dc.w BPL4PTL,0
- dc.w BPL5PTH,0
- dc.w BPL5PTL,0
- CopperScreenControl:
- dc.w BPLCON0,(SCREEN_D<<12)!$0204
- dc.w BPLCON3,$40
- dc.w BPL1MOD,SCREEN_BYWIDTH-SCREEN_BYPL
- dc.w BPL2MOD,SCREEN_BYWIDTH-SCREEN_BYPL
- dc.w $ffff,$fffe
- SectionChip_e:
- SECTION chip_bss,BSS_C
- Screen:
- ds.b SCREEN_BYWIDTH*SCREEN_H
- Screen_e:
- Background:
- ds.b SCREEN_BYWIDTH*SCREEN_H
- BackgroundE:
- END
- ABC -> D
- 0 000 0
- 1 001 0
- 2 010 0
- 3 011 0
- 4 100 1
- 5 101 1
- 6 110 1
- 7 111 1
- $c0
- ABC -> D
- 0 000 0
- 1 001 1
- 2 010 0
- 3 011 0
- 4 100 0
- 5 101 1
- 6 110 1
- 7 111 1
- $e2
Add Comment
Please, Sign In to add comment