The source was highlighted using GeSHi © 2004-2007 Nigel McNie, 2007-2010 Benny Baumann, 2008-2009 Milian Wolff
INCDIR INCLUDE:
INCLUDE HARDWARE/AGA_CUSTOM.I
INCLUDE HARDWARE/DMABITS.I
INCLUDE GRAPHICS/GFX.I
INCDIR DH1:DEV/RSC/
INCLUDE VIDEO.OFFSETS
;DEBUG
;EXEC
; ---- GFX CONSTANTS ----
SCRWIDTH = 48
SCRHEIGHT = 200
PLANE_SIZE = SCRWIDTH*SCRHEIGHT
NUMPLANES = 4
BOBHEIGHT = 22
BOBWIDTH = 6
BOBPLANE = (BOBHEIGHT*BOBWIDTH)
BOBSIZE = (BOBPLANE*NUMPLANES)
BOBSIZEFULL = (BOBSIZE+BOBPLANE)
MAXBOBS = 13
MAXPLAYERS = 2
MAXHOOKERS = 3
MAXOUTLAWS = 5
NUMBOBS = 157
MAXBULLETS = 10
; ---- DEVICE CONSTANTS ----
dev_joy0 = 0
dev_joy1 = 1*4
dev_cpu = 2*4
dev_none = 3*4
; ---- device directions ----
d_up = 4
d_upleft = 8
d_upright = 12
d_down = 16
d_downleft = 20
d_downright = 24
d_left = 28
d_right = 32
; ---- directions ----
di_up = 1
di_upleft = 2
di_upright = 3
di_down = 4
di_downleft = 5
di_downright = 6
di_left = 7
di_right = 8
A EQU %11110000
B EQU %11001100
C EQU %10101010
FM_INITREPLAY = 0
FM_INITSONG = 4
FM_PLAYSONG = 8
FM_ENDSONG = 12
FM_PLAYSTATUS = 16
FM_PLAYSFX = 20
; -----------------------------------------------
;
; HIGH NOON
;
; -----------------------------------------------
;
; C64 CONVERSION BY LLOYD ROSEN
;
; ORIGINAL GAME © 1983 OCEAN SOFTWARE
;
; AMIGA VERSION © 1997 SEASONS CLASSIC!
;
; -----------------------------------------------
; ASSEMBLED WITH ASM-ONE
;
; DO NOT SPREAD THIS SOURCE OUTSIDE SEASONS!!
; History
; v0.10 (APR 25)
; - all initial things done.
; - arena drawn to screen
; - walk behind background okay.
; v0.11 (APR 26)
; - zones added.
; v0.12 (APR 27)
; - bullets added.
; v0.14 (APR 28)
; - door open/close gfx routines added.
; - one outlaw added.
; v0.16 (MAY 02)
; - random routine added.
; - the outlaw robs the bank and runs away(!)
; v0.17 (MAY 07)
; - the outlaw kidnaps a hooker!
; v0.19 (MAY 08)
; - lots of outlaws invades the town..
; - outlaws shoot.
; v0.21 (MAY 09)
; - more hookers added.
; - bugs fixed.
; v0.22 (MAY 10)
; - outlaws die when shot.
; v0.24 (MAY 11)
; - some bugs fixed.
; - sorting routine added.
; - last visible shitty bug removed (located
; and eliminated in restore backgrounds..)
; - obnoxius hooker bug removed (finally! phew!)
; v0.25 (MAY 14)
; - different height of bobs allowed.
; v0.27 (MAY 18)
; - dynamite maniac added.
; - sheriff can die.
; v0.28 (MAY 19)
; - many small bugs removed.
; - horse added.
; v0.32 (MAY 20)
; - cleaned up a little - making small bugs go away
; - horsemen rides by
; - ... and shoot
; - snipers added. not very much left!
; v0.36 (MAY 21)
; - text routines and number conversion added.
; - wave 5 graphics added.
; - wave 5 outlaws added.
; - even more bugs removed
; v0.37 (MAY 22)
; - bonus draw sequence just about complete!
; v0.38 (MAY 25) DEADLINE REACHED!
; - music and sound effects added.
; - scoring, level data, wave data added.
; - start walking sequence added.
; v0.39 (MAY 26) over deadline... :-(
; - the game works great in 1 player mode!
; v0.41 (MAY 27)
; - new, more accurate sorting routine added.
; - computer control modified.
; v0.43 (MAY 29)
; - scoring for pl2/bugs removed
; - bonus draw for 2 players
; v0.44 (MAY 30)
; - chunky background added. (saved lotsa memory!)
; - game works fine. or so it seems..
; - title screens added.
; v0.45 (MAY 31)
; - hall of fame complete.
; - extra life checking added.
; v0.46 (JUN 02)
; - dynamite checking added.
; - bugs fixed.
; - highscore saving/loading
; v0.99 (JUN 02)
; - GAME DONE & EXECUTABLED! Serious playtesting left..
; DOS.LIBRARY
_LVOOPEN = -30
_LVOCLOSE = -36
_LVOREAD = -42
_LVOWRITE = -48
_LVOUNLOCK = -90
_LVOUNLOADSEG = -156
; EXEC.LIBRARY
_LVOFINDTASK = -294
_LVOSETTASKPRI = -300
_LVOADDINTSERVER = -168
_LVOREMINTSERVER = -174
_LVOOPENLIBRARY = -552
_LVOCLOSELIBRARY = -414
_LVOFORBID = -132
_LVOPERMIT = -138
; GRAPHICS.LIBRARY
_LVOWAITBLIT = -228
_LVOOWNBLITTER = -456
_LVODISOWNBLITTER = -462
_LVOALLOCBITMAP = -918
_LVOFREEBITMAP = -924
; INTUTION.LIBRARY
_LVOCURRENTTIME = -84
CALLVIDEO MACRO
lea _videoresource(pc),a4
jsr VI_\1(a4)
ENDM
CALL MACRO
jsr _LVO\1(a6)
ENDM
CALLGRAF MACRO
move.l _gfxbase(pc),a6
jsr _LVO\1(a6)
ENDM
DBUG MACRO
move #$f00,$dff180
ENDM
OUTLAWLIMIT = MAXOUTLAWS
MAXKIDNAPPERS = 3
SNIPEDELAY = 75 ; delay before disappearing
IFD EXEC
rb_HunkStart SUB.L A1,A1
MOVE.L 4.W,A6
JSR -294(A6) ; FindTask
MOVE.L D0,A4
MOVEQ #0,D0
TST.L $AC(A4) ; pr_CLI
BNE.S rb_FromCLI
LEA $5C(A4),A0 ; pr_MsgPort
JSR -384(A6) ; WaitPort
LEA $5C(A4),A0
JSR -372(A6) ; GetMsg
rb_FromCLI MOVE.L D0,D7 ; D7 = WBmsg
LEA rb_DOSname(PC),A1
MOVEQ #0,D0
JSR -552(A6) ; OpenLibrary
TST.L D0
BEQ.S rb_dexit
MOVE.L d0,dosbase
MOVE.L D0,A5
EXG A5,A6 ; A6=DOS
MOVE.L $98(A4),D1 ; pr_CurrentDir
JSR -96(A6) ; DupLock
MOVE.L D0,rb_CurrentDir
EXG A5,A6 ; A6=exec
JSR -132(A6) ; Forbid
MOVE.L #rb_ProgName,D1
MOVEQ.L #0,D2
MOVE.B 9(A4),D2 ; priority
LEA rb_HunkStart-4(PC),A0
MOVE.L (A0),D3 ; Ptr to next segment
CLR.L (A0) ; Unlink next segment
MOVE.L #4000,D4
EXG A5,A6 ; A6=DOS
JSR -138(A6) ; CreateProc
EXG A5,A6 ; A6=exec
JSR -138(A6) ; Permit
MOVE.L A5,A1
JSR -414(A6) ; CloseLibrary
rb_dexit TST.L D7
BEQ.S rb_exit
JSR -132(A6) ; Forbid
MOVE.L D7,A1
JSR -378(A6) nbsp; ; ReplyMsg
rb_exit MOVEQ #0,D0
RTS
rb_DOSname dc.b "dos.library",0
rb_progname dc.b "High Noon © 1997 Seasons",0
; End of runback hunk
SECTION ptcode,CODE
START MOVE.L 4.W,A6
SUB.L A1,A1
CALL FindTask
move.l sp,_stacksave
BSR.S Main
move.l _stacksave,sp
MOVE.L 4.W,A6
CALL Forbid
MOVE.L DOSbase,A6
MOVE.L rb_CurrentDir(PC),D1
CALL UnLock
LEA START-4(PC),A0
MOVE.L A0,D1
LSR.L #2,D1
CALL UnLoadSeg
MOVEQ #0,D0
RTS
rb_currentdir dc.l 0
ptprocess dc.l 0
_stacksave dc.l 0
dosbase dc.l 0
; ---- MAIN INITIALISATION ----
ENDIF
main ;move.l sp,_stacksave
bsr.w init_all
bsr.w init_screenswap
bsr.w set_random
bsr.w make_boblookup
bsr.w allocate_bobs
cmp #-5,d0
beq.w quit
bsr read_highscoretable
lea _musicdata,a0
jsr FM_INITREPLAY(a0)
bsr.w set_vbintserver
CALLVIDEO HSCREENSTART ; show hscreen
IFND DEBUG
CALLGRAF OwnBlitter
ENDIF
clr _hiscore
go_hiscore lea _musicdata,a0
moveq #4,d0
moveq #0,d1
jsr FM_INITSONG(a0)
bsr enter_hiscore
move.b #1,_level
; ---- TITLE SCREEN ----
go_title clr.b _rawkey
bsr draw_title
lea _musicdata,a0
moveq #0,d0
moveq #0,d1
jsr FM_INITSONG(a0)
move #200,_dispcount
clr.b _titleflag
bsr swap_screens
bsr show_screen
titlemain bsr get_key
move.b _rawkey(pc),d0
cmp.b #$50,d0
beq.w start_1player
cmp.b #$51,d0
beq.w start_2player
cmp.b #$45,d0
beq quit
lea _player1(pc),a3
bsr read_joystick1
tst.b p_fire(a3)
bne start_1player
lea _player2(pc),a3
bsr read_joystick0
tst.b p_fire(a3)
bne start_2player
tst.b _titleflag
bne .notitle
lea _player1(pc),a3
cmp.b #(D_LEFT),p_joystick(a3)
beq decrease_level
cmp.b #(D_RIGHT),p_joystick(a3)
beq increase_level
lea _player2(pc),a3
cmp.b #(D_LEFT),p_joystick(a3)
beq decrease_level
cmp.b #(D_RIGHT),p_joystick(a3)
beq decrease_level
.notitle bsr wait_sync
subq #1,_dispcount
beq.b .swapem
bra titlemain
.swapem move #250,_dispcount
bsr swap_screens
bsr show_screen
not.b _titleflag
bra titlemain
_dispcount dc 0
_titleflag dc.b 0,0
; ---- DECREASE LEVEL ----
decrease_level moveq #10,d0
.1 bsr wait_sync
dbf d0,.1
cmp.b #1,_level
beq.b _no
subq.b #1,_level
bra.b _ok
; ---- INCREASE LEVEL ----
increase_level moveq #10,d0
.1 bsr wait_sync
dbf d0,.1
cmp.b #9,_level
beq.b _no
addq.b #1,_level
_ok bsr swap_screens
bsr print_level
bsr swap_screens
_no bra titlemain
start_1player lea _player1(pc),a0
move #3,p_lives(a0)
clr.b _hero1dead
st.b _hero2dead
move.b #1,_numplayers
bra.b start_game
start_2player lea _player1(pc),a0
move #3,p_lives(a0)
lea _player2(pc),a0
move #3,p_lives(a0)
clr _hero1dead
move.b #2,_numplayers
start_game clr.b _gameover
move.b #1,_wave
lea _player1(pc),a0
clr p_plscore(a0)
clr p_lifescore(a0)
lea _player2(pc),a0
clr p_plscore(a0)
clr p_lifescore(a0)
bsr.w init_leveldata
new_wave clr.b _hasseenwave
moveq #6,d0
bsr.w random
add #18,d0 ; from 18 - 24 outlaws pr. wave
move.b d0,_mustshoot
bsr.w set_wavetext
start_wave cmp.b #5,_wave
bne.b .not5
move.b #5,_mustshoot ; must shoot 5 outlaws on wav5
.not5 bsr.w init_bobstructures
bsr.w init_allstructs
bsr bullets_inactive
bsr.w init_wavedata
bsr.w draw_arena
bsr.w swap_screens
bsr.w draw_arena
clr.b _restartwave
bsr.w wave_start
moveq #100,d0
bsr.w random
add #50,d0
move d0,_outlawtimer
moveq #100,d0
bsr.w random
add #50,d0
move d0,_snipertimer
move #350,_deadcount
; -----------------------------------------
;
; MAIN LOOP
;
; -----------------------------------------
main_loop tst.b _gameover
bne go_hiscore
bsr get_key
cmp.b #$45,_rawkey
beq go_title
tst.b _mustshoot
bne.b .ok
cmp.b #5,_wave
beq.b .nono
tst.b _numoutlaws
bne.b .ok
lea _player1(pc),a0
move.l p_bob(a0),a0
tst.b bo_maskmade(a0)
bne.b .ok
.nono st.b _bonusdraw
bra.w bonus_draw
.ok tst.b _restartwave
beq.b .nores
lea _musicdata,a0
JSR FM_PLAYSTATUS(a0)
tst.b d0
bne.b .nores
bra start_wave
.nores bsr.w wait_dead5
bsr.w add_outlaws
bsr.w add_snipers
; ---- movements ----
bsr.w update_devices
; ---- animations ----
bsr.w update_animations
bsr.w animate_dynahorse
; ---- zones ----
tst.b _hero1dead
bne.b .dontcheck
lea _player1(pc),a3
bsr.w get_zone
bsr.w check_top
bsr.w set_walklimitations
bsr.w check_walklimitations
.dontcheck cmp.b #2,_numplayers
bne.b .nonono
tst.b _hero2dead
bne.b .nonono
lea _player2(pc),a3
bsr.w get_zone
bsr.w check_top
bsr.w set_walklimitations
bsr.w check_walklimitations
; ---- movements ----
.nonono bsr.w update_movements
bsr.w update_bullets
bsr.w check_bullethit
bsr check_dynamite
bsr.w check_deadbodies
bsr.w update_snipercount
; ---- shooting ----
bsr.w update_shooting
; ---- double buffering ----
bsr.w create_masks
bsr.w draw_snipers
bsr.b draw_text
bsr.w save_backgrounds
; bsr.w init_drawlist
bsr.w horseman_cheat
bsr.w sort_drawlist
bsr.w horseman_cheat2
bsr.w draw_bullets
bsr.w draw_bobs
bsr.w wait_sync
bsr.w swap_screens
bsr.w show_screen
bsr.w clear_bullets
bsr.w restore_backgrounds
bsr.w clear_snipers
bra main_loop
quit lea _musicdata,a0
moveq #0,d0
jsr FM_ENDSONG(a0)
bsr.w reset_vbintserver
bsr write_highscoretable
bsr.w cleanup_all
; move.l _stacksave(pc),sp
rts
; ---- DRAW TEXT TO SCREEN ----
draw_text tst.b _drawtext
bne.b .istext
rts
.istext subq.b #1,_drawtext
move.l _textptr(pc),a1
.prt move.l (a1)+,d0 ; x pos
bmi.b .done
move.l (a1)+,d1 ; y pos
move.l (a1)+,d2 ; length
move.l (a1)+,a0 ; text
bsr.w print_text2
bra.b .prt
.done rts
_drawtext dc.b 0,0
_textptr dc.l 0
_startwavtxt dc.l 20,22,7,_wavtxt
dc.l -1
_bonusdrawtxt dc.l 12+4,21,14,_endoftxt
dc.l 15+4,23,9,_drawtxt
dc.l -1
_cleareoftxt dc.l 12+4,21,14,_cleartxt
dc.l -1
_clearwavtxt dc.l 20,22,7,_cleartxt
dc.l -1
_endoftxt dc.b "E"-55,"N"-55,"D"-55,-1,"O"-55,"F"-55,37
_wavtxt dc.b 0,0,0,0,"W"-55,"A"-55,"V"-55,"E"-55
_drawtxt dc.b "B"-55,"O"-55,"N"-55,"U"-55,"S"-55,-1
dc.b "D"-55,"R"-55,"A"-55,"W"-55
_cleartxt dc.b 37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37
even
; ---- DEAD WAIT ON WAVE 5 ----
wait_dead5 cmp.b #5,_wave
beq.b .ok
rts
.ok cmp #$FFFF,_hero1dead
beq.b .count
.bobbo rts
.count subq #1,_deadcount
beq.b .leave
rts
.leave bra lose_life
_deadcount dc 0
_restartwave dc.b 0
_hasseenwave dc.b 0
; ---- INIT WAVE ----
wave_start clr.b _swapflag
lea _musicdata,a0
moveq #4,d0
&nnbsp; moveq #0,d1
jsr FM_INITSONG(a0)
cmp.b #5,_wave
beq.b .noopen
bsr.w jail_open
.noopen tst.b _hero1dead
bne.b .no3
lea _player1(pc),a0
move.l p_bob(a0),a0
move #90,bo_x(a0)
move #83,bo_y(a0)
clr.b bo_inactive(a0)
st.b bo_firstflag(a0)
clr.b bo_maskmade(a0)
.no3 tst.b _hero2dead
bne.b .no2
cmp.b #2,_numplayers
bne.b .no2
lea _player2(pc),a0
move.l p_bob(a0),a0
move #90,bo_x(a0)
move #83,bo_y(a0)
clr.b bo_inactive(a0)
st.b bo_firstflag(a0)
clr.b bo_maskmade(a0)
.no2 clr.b _leaveinit
clr.b _nosfx
clr.b _doorclose
bsr.w print_mainline
bsr.w print_score
bsr.w print_hiscore
bsr.w print_lives
move _initbonusstore(pc),_bonus
bsr.w print_bonus
move #100,_textcount
move #100,_deadcount
tst.b _hasseenwave
bne.b .noprint
cmp.b #5,_wave
bne.b .not5
clr _textcolor2
bra.b .fff
.not5 clr _textcolor
.fff move.l #_startwavtxt,_textptr
move.b #2,_drawtext
st.b _hasseenwave
.noprint bsr.w init_leavejail
; ---- MAIN LOOP FOR WAVE START ----
wavestart_loop tst.b _leaveinit
bne.b .leave
bsr.b wait_remtext
bsr.b wait_closedoor
bsr.w update_devices
bsr.w update_animations
bsr.w update_movements
bsr.w draw_text
bsr.w save_backgrounds
bsr.w sort_drawlist
bsr.w draw_bobs
bsr.w wait_sync
bsr.w swap_screens
bsr.w show_screen
bsr.w restore_backgrounds
bra.b wavestart_loop
.leave rts
; ---- WAIT TO REMOVE WAVE TEXT ----
wait_remtext tst _textcount
beq.b .done
subq #1,_textcount
beq.b .rem
.done rts
.rem cmp.b #5,_wave
beq.b .is5
; DBUG
move #$000C,_textcolor
bra.b rem_wavetext
.is5 move #$00C0,_textcolor2
rem_wavetext move.l #_clearwavtxt,_textptr
move.b #2,_drawtext
rts
_textcount dc 0
wait_closedoor tst.b _doorclose
beq.b .done
subq.b #1,_doorclose
bne.b .close
.done rts
.close bra.w jail_close
_doorclose dc.b 0
_leaveinit dc.b 0
; ---- INIT SHERIFFS TO LEAVE JAIL ----
init_leavejail cmp.b #2,_numplayers
bne.b .setpl1
tst.b _hero1dead
bne.b .setplayer2
.setpl1 lea _player1(pc),a3
move.l #(DEV_CPU),p_device(a3)
st.b p_noshoot(a3)
clr.b p_notwalking(a3)
cmp.b #5,_wave
bne.b .isnot5
move.l p_bob(a3),a1
move #104,bo_y(a1)
move #0,bo_x(a1)
lea walkseqcode_enterwave5(pc),a0
move.l a0,p_walkseqcode(a3)
lea _enterwave5sequence(pc),a0
bra.b .setseq
.isnot5 lea walkseqcode_leavejail1(pc),a0
move.l a0,p_walkseqcode(a3)
lea _leavejail1sequence(pc),a0
.setseq lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
clr p_walkseqpos(a3)
cmp.b #2,_numplayers
beq.b .setplayer2
rts
.setplayer2 tst.b _hero2dead
bne.b .no
lea _player2(pc),a3
move.l #(DEV_CPU),p_device(a3)
st.b p_noshoot(a3)
clr.b p_notwalking(a3)
cmp.b #5,_wave
bne.b .isnot51
move.l p_bob(a3),a1
move #104,bo_y(a1)
move #0,bo_x(a1)
lea walkseqcode_enterwave5(pc),a0
move.l a0,p_walkseqcode(a3)
lea _enterwave52sequence(pc),a0
bra.b .setseqq
.isnot51 lea walkseqcode_leavejail1(pc),a0
move.l a0,p_walkseqcode(a3)
lea _leavejail2sequence(pc),a0
bra.w .setseqq
.setseqq lea p_walksequence(a3),a1
moveq #1,d0
.3 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.3
clr p_walkseqpos(a3)
.no rts
walkseqcode_enterwave5
cmp #-1,d0
beq.b endof
rts
walkseqcode_leavejail1
cmp #1,d0
beq.b closedoor
cmp #-1,d0
beq.b endof
rts
walkseqcode_leavejail2
cmp #-1,d0
beq.b endof
rts
endof cmp.b #(OT_SHERIFF1),p_type(a3)
bne.b .is2
move.l #(DEV_JOY1),p_device(a3)
clr.b p_noshoot(a3)
st.b _leaveinit
rts
.is2 move.l #(DEV_JOY0),p_device(a3)
clr.b p_noshoot(a3)
st.b _leaveinit
rts
closedoor tst.b _bonusdraw
bne.b .lee
move.b #3,_doorclose
move #$0500,d0
moveq #0,d2
bra.w play_sfx
.lee st.b _leaveinit
rts
_leavejail1sequence
dc 90,90,0
dc 90,84,1
dc 180-24,140,-1
dc 0,0,0
dc 0,0,0
dc 0,0,-1
_leavejail2sequence
dc 90,90,0
dc 90,84,1
dc 180+24,140,-1
dc 0,0,0
dc 0,0,0
dc 0,0,-1
_enterwave5sequence
dc 180-24,140,-1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
_enterwave52sequence
dc 180+24,140,-1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
; ---- PLAY SOUNDEFFECT ----
play_sfx tst.b _nosfx
bne.b .no
movem.l a0-a6,-(sp)
lea _musicdata,a0
jsr FM_PLAYSFX(a0)
movem.l (sp)+,a0-a6
.no rts
_nosfx dc.b 0,0
; ---- PRINT "WAVE" TEXT ----
set_wavetext moveq #0,d0
move.b _wave(pc),d0
subq.b #1,d0
lea _wavetxt(pc),a0
lsl #2,d0
lea (a0,d0),a0
lea _wavtxt(pc),a1
move.b (a0)+,(a1)+
move.b (a0)+,(a1)+
move.b (a0)+,(a1)+
move.b (a0)+,(a1)+
rts
_outlawtimer dc 0
_snipertimer dc 0
_shootfrequency dc 300 ; shoot frequency for outlaws (random)
_horseshootfreq dc 150
_outlawmaxtime dc 100 ; max. time allowed before appearing
_snipermaxtime dc 400 ; max. time allowed .... etc.
_scoresub dc 10 ; amount to subtract from killscore
_initkillscore dc 100 ; initial kill score for outlaws
_initbonus dc 100 ; initial bonus
_killbonus dc 20 ; bonus for outlaw kill
_scorecounter dc 100 ; counter before subtracting
_initbonusstore dc 0 ; store
_mustshoot dc.b 0 ; must shoot this many to clear wave
_level dc.b 1 ; level
_wave dc.b 4 ; wave
_bonusdraw dc.b 0 ; set if bonus draw
_numplayers dc.b 1,0 ; number of players
_hero1dead dc.b 0
_hero2dead dc.b 0
; ---- INIT LEVELDATA ----
init_leveldata moveq #0,d0
move.b _level(pc),d0
subq.b #1,d0
lsl #3,d0
lea _leveldata(pc,d0.l),a0
move (a0)+,_shootfrequency
move (a0)+,_horseshootfreq
move (a0)+,_outlawmaxtime
move (a0)+,_snipermaxtime
rts
; ---- LEVEL DATA ----
; shootfreq, horseshootfreq, outlawmaxtime, snipermaxtime
_leveldata dc 300,150,100,400 ; 1
dc 280,120,090,380 ; 2
dc 260,100,080,360 ; 3
dc 250,090,080,340 ; 4
dc 210,080,070,300 ; 5
dc 180,070,060,290 ; 6
dc 150,050,050,250 ; 7
dc 100,030,040,200 ; 8
dc 050,020,020,150 ; 9
; ---- INIT WAVEDATA ----
init_wavedata moveq #0,d0
move.b _wave(pc),d0
subq.b #1,d0
mulu #10,d0
lea _wavedata(pc,d0.l),a0
move (a0)+,_scoresub
move (a0)+,_initkillscore
move (a0),_initbonusstore
move (a0)+,_initbonus
move (a0)+,_killbonus
move (a0)+,_scorecounter
rts
; ---- WAVE DATA ----
; scoresub, initkillscore, initbonus, killbonus, scorecount
_wavedata dc 010,100,100,10,100 ; 1
dc 020,200,200,20,110 ; 2
dc 030,300,300,30,120 ; 3
dc 040,400,400,40,130 ; 4
dc 050,500,500,50,140 ; 5
_wavetxt dc.b 1,"S"-55,"T"-55,-1
dc.b 2,"N"-55,"D"-55,-1
dc.b 3,"R"-55,"D"-55,-1
dc.b 4,"T"-55,"H"-55,-1
dc.b 5,"T"-55,"H"-55,-1
; ---- BONUS DRAW ----
BLINKSPEED = 25
bonus_draw bsr.w init_drawman
bsr.w init_sheriffdraw
movem.l d0-d2/a0-a3,-(sp)
lea _musicdata,a0
moveq #2,d0
moveq #0,d1
jsr FM_INITSONG(a0)
movem.l (sp)+,d0-d2/a0-a3
cmp.b #5,_wave
bne.b .not5
clr _textcolor2
bra.b .gon
.not5 clr _textcolor
.gon move #370,_endcount
move #1,_blinkcount
st.b _blinkflag
clr.b _noch
clr.b _drawok
move.b #8,_blinkleft
move.l #_bonusdrawtxt,_textptr
move.b #2,_drawtext
drawmain_loop ;bsr get_key
;cmp.b #$45,_rawkey
;beq.b .up
tst.b _drawok
beq.b .notdrawn
subq #1,_endcount
bne.b .notdrawn
.up tst.b _addbonus
beq.b .nobonus
tst.b _hero1dead
bne.b .nod
lea _player1(pc),a0
move _bonus(pc),d0
add d0,p_plscore(a0)
add d0,p_lifescore(a0)
bsr check_extralife
.nod tst.b _hero2dead
bne.b .nobonus
lea _player2(pc),a0
move _bonus(pc),d0
add d0,p_plscore(a0)
add d0,p_lifescore(a0)
bsr check_extralife
.nobonus clr.b _bonusdraw
addq.b #1,_wave
cmp.b #5,_wave
ble.b .ok
move.b #1,_wave
cmp.b #9,_level
beq.b .ok
addq.b #1,_level
.ok bra.w new_wave
; rts
.notdrawn bsr.w blink_text
bsr.w wait_for_draw
bsr.w wait_for_shoot
bsr.w update_devices
bsr.w update_animations
bsr.w update_movements
bsr.w update_bullets
bsr.w check_bullethit
bsr.b check_deads
tst.b _drawok
beq.b .nodraw
bsr.w update_shooting
.nodraw bsr.w draw_text
bsr.w sort_drawlist
bsr.w save_backgrounds
bsr.w draw_bullets
bsr.w draw_bobs
bsr.w wait_sync
bsr.w swap_screens
bsr.w show_screen
bsr.w clear_bullets
bsr.w restore_backgrounds
bra.w drawmain_loop
check_extralife cmp #10000,p_lifescore(a0)
bge.b .addlife
.nomore rts
.addlife clr p_lifescore(a0)
cmp #9,p_lives(a0)
beq.b .nomore
addq #1,p_lives(a0)
bra print_lives
check_deads tst.b _noch
bne.b .ff
tst.b _drawok
bne.b .chk
.ff rts
.chk clr.b _addbonus
tst.b _hero1dead
bne.b .nopl1
lea _player1(pc),a0
tst.b p_dead(a0)
bne.b .nobonus
lea _hookers(pc),a0
tst.b p_dead(a0)
beq.b .nobonus
.nopl1 tst.b _hero2dead
bne.b .nono
lea _player2(pc),a0
tst.b p_dead(a0)
bne.b .nobonus
lea _hookers+bo_sizeof(pc),a0
tst.b p_dead(a0)
beq.b .nobonus
.nono movem.l d0-d2/a0-a3,-(sp)
lea _musicdata,a0
moveq #3,d0
moveq #0,d1
jsr FM_INITSONG(a0)
st.b _nosfx
movem.l (sp)+,d0-d2/a0-a3
st.b _noch
st.b _addbonus
.nobonus rts
_addbonus dc.b 0
_noch dc.b 0
; ---- BLINK TEXT ----
blink_text tst.b _blinkleft
beq.b .sk
subq #1,_blinkcount
beq.b .okok
.sk rts
.okok move #(BLINKSPEED),_blinkcount
subq.b #1,_blinkleft
beq.b .clearendof
not.b _blinkflag
beq.b .off
cmp.b #5,_wave
beq.b .is5
move #$0CC0,_textcolor
rts
.is5 move #$0C0,_textcolor2
rts
.off cmp.b #5,_wave
beq.b .is52
move #$0000,_textcolor
rts
.is52 clr _textcolor2
rts
.clearendof move.l #_cleareoftxt,_textptr
move.b #2,_drawtext
rts
_blinkflag dc.b 0
_blinkleft dc.b 0
_blinkcount dc 0
_endcount dc 0
; ---- INIT SHERIFF TO DRAW ----
init_sheriffdraw
lea _player1(pc),a3
lea _drawshersequence(pc),a0
bsr.b .setsh
cmp.b #2,_numplayers
beq.b .ok
rts
.ok tst.b _hero2dead
beq.b .ok2
rts
.ok2 lea _player2(pc),a3
lea _drawsher2sequence(pc),a0
.setsh move.l #(DEV_CPU),p_device(a3)
st.b p_noshoot(a3)
clr.b p_nomove(a3)
clr.b p_notwalking(a3)
lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
lea walkseqcode_drawsher(pc),a0
move.l a0,p_walkseqcode(a3)
clr p_walkseqpos(a3)
rts
; ---- INIT DRAW OPPONENT ----
init_drawman lea _hookers(pc),a3
lea _drawmansequence(pc),a0
bsr.b .initdraw
cmp.b #2,_numplayers
bne.b .nopl2
tst.b _hero1dead
bne.b .1dead
.nopl2 move.l p_bob(a3),a0
clr.b bo_inactive(a0)
clr.b bo_maskmade(a0)
st.b bo_firstflag(a0)
move #352,bo_x(a0)
move #128,bo_y(a0)
tst.b _hero2dead
bne.b .no2
.1dead lea _hookers+p_sizeof(pc),a3
lea _drawman2sequence(pc),a0
bsr.b .initdraw
move.l p_bob(a3),a0
clr.b bo_inactive(a0)
st.b bo_firstflag(a0)
move #352,bo_x(a0)
move #100,bo_y(a0)
.no2 move #100,d0
bsr.w random
add #150,d0
move d0,_drawwait
clr.b _drawok
clr.b _oneshot
rts
.initdraw lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
clr p_walkseqpos(a3)
lea walkseqcode_drawman(pc),a0
move.l a0,p_walkseqcode(a3)
move.l #_drawmanleft,p_animleft(a3)
move.l #_drawmandie,p_animdie(a3)
clr.b p_animpos(a3)
move.b #1,p_animspdcount(a3)
move.b #1,p_walkspeed(a3)
move.b #(DI_LEFT),p_direction(a3)
clr.b p_lastdirection(a3)
clr.b p_nomove(a3)
move.b #(OT_ROBBER),p_type(a3)
clr.b p_runhome(a3)
clr.b p_cantdie(a3)
clr.b p_notwalking(a3)
rts
_drawwait dc 0
_shootwait dc 0
_drawok dc.b 0
_shootok dc.b 0
_oneshot dc.b 0,0
; ---- WAIT TO DRAW GUN ----
wait_for_draw tst.b _blinkleft
bne.b .sji
tst.b _oneshot
bne.b .sji
tst.b _hero1dead
bne.b .no22
lea _player1(pc),a0
tst.b p_notwalking(a0)
beq.b .sji
lea _hookers(pc),a0
tst.b p_notwalking(a0)
beq.b .sji
.no22 cmp.b #2,_numplayers
bne.b .okok
tst.b _hero2dead
bne.b .okok
lea _player2(pc),a0
tst.b p_notwalking(a0)
beq.b .sji
lea _hookers+p_sizeof(pc),a0
tst.b p_notwalking(a0)
beq.b .sji
bra.b .okok
.sji rts
.okok lea _player1(pc),a0
tst.b p_fire(a0)
bne.b .notyet
cmp.b #2,_numplayers
bne.b .subc
tst.b _hero2dead
bne.b .subc
lea _player2(pc),a0
tst.b p_fire(a0)
bne.b .notyet
.subc subq #1,_drawwait
beq.b .draw
.notyet rts
.draw st.b _drawok
tst.b _hero1dead
bne.b .nononono
lea _hookers(pc),a0
move.l p_bob(a0),a0
move #(153),bo_image(a0)
.nononono cmp.b #2,_numplayers
bne.b .nono
tst.b _hero2dead
bne.b .nono
lea _hookers+p_sizeof(pc),a0
move.l p_bob(a0),a0
move #(153),bo_image(a0)
.nono moveq #30,d0
bsr.w random
add #40,d0
move d0,_shootwait
rts
; ---- WAIT TO SHOOT ----
wait_for_shoot tst.b _oneshot
bne.b .nn
tst.b _drawok
bne.b .ok
.nn rts
.ok subq #1,_shootwait
beq.b .shoot
rts
.shoot tst.b _hero1dead
bne.b .nosh
lea _hookers(pc),a3
tst.b p_dead(a3)
bne.b .nosh
st.b p_nomove(a3)
st.b _oneshot
bsr.b .fireshot
.nosh cmp.b #2,_numplayers
bne.b .nn
tst.b _hero2dead
bne.b .nn
lea _hookers+p_sizeof(pc),a3
tst.b p_dead(a3)
bne.b .noshoot
st.b p_nomove(a3)
st.b _oneshot
.fireshot moveq #0,d3
move.l p_bob(a3),a0
movem bo_x(a0),d0/d1
move.b #(DI_LEFT),d2
subq #4,d0
add #10,d1
bra.w add_bullet
.noshoot rts
_drawmansequence
dc 212,128,1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
_drawman2sequence
dc 212,100,1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
_drawshersequence
dc 136,128,1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
_drawsher2sequence
dc 136,100,1
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
; ---- WALKSEQCODE FOR DRAW MAN ----
walkseqcode_drawman
tst.b p_notwalking(a3)
bne.b .skip
cmp #1,d0
beq.b .ok
rts
.skip st.b p_nomove(a3)
clr p_walkseqpos(a3)
rts
.ok st.b p_nomove(a3)
move.b #(DI_LEFT),p_direction(a3)
clr.b p_lastdirection(a3)
clr p_walkseqpos(a3)
move.l p_bob(a3),a0
move #(152),bo_image(a0) ; prepare to draw
st.b p_notwalking(a3)
rts
; ---- WALKSEQCODE FOR SHERIFFDRAW ----
walkseqcode_drawsher
cmp #1,d0
beq.b .ok
rts
.ok cmp.b #(OT_SHERIFF1),p_type(a3)
bne.b .2
move.l #(DEV_JOY1),p_device(a3)
bra.b .set
.2 cmp.b #(OT_SHERIFF2),p_type(a3)
bne.b .ff
move.l #(DEV_JOY0),p_device(a3)
.set st.b p_nomove(a3)
clr.b p_noshoot(a3)
clr.b p_direction(a3)
move.b #(DI_RIGHT),p_lastdirection(a3)
clr p_walkseqpos(a3)
move.l p_bob(a3),a0
move #(9),bo_image(a0)
st.b p_notwalking(a3)
.ff rts
; ---- "CHEAT" TO SIT HORSEMAN UPON THE HORSE ----
horseman_cheat tst.b _horseactive
bne.b .ok
rts
.ok move.l _horseman(pc),a3
move.l p_bob(a3),a0
add #43,bo_y(a0) ; needed to be UPON the horse
rts
horseman_cheat2 tst.b _horseactive
bne.b .ok
rts
.ok move.l _horseman(pc),a3
move.l p_bob(a3),a0
sub #43,bo_y(a0) ; back to normal
rts
; ---- CHECK FOR ANY DEAD BODIES ----
check_deadbodies
cmp.b #4,_wave
ble.b .okokok
rts
.okokok lea _rigormortis(pc),a1
move.l p_bob(a1),a0
tst.b bo_inactive(a0)
bmi.b .ok
rts
&nnbsp;
.ok lea _player1(pc),a3
moveq #(MAXBOBS-1),d0
.1 tst.b p_dead(a3)
bne.b .isdead
lea P_SIZEOF(a3),a3
dbf d0,.1
rts
.isdead move.l p_bob(a3),a0
lea _deadbodypos(pc),a1
move.l bo_x(a0),(a1)
lea _rigormortis(pc),a0
move.l a3,p_rigorbody(a0)
; ---- START RIGOR MORTIS TO DO HIS JOB ----
lea _rigormortis(pc),a3
move.l p_bob(a3),a0
clr.b bo_inactive(a0)
st.b bo_firstflag(a0)
move #35*8,bo_x(a0)
move #82,bo_y(a0)
lea walkseqcode_rigor(pc),a0
move.l a0,p_walkseqcode(a3)
bsr.w reset_pstruct
.left lea _rigorsequence(pc),a0
.2 lea p_walksequence(a3),a1
moveq #1,d0
.3 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.3
move.l (a0)+,(a1)+
clr p_walkseqpos(a3)
rts
_rigorsequence dc 38*8-4,82,0 ; entrance
dc 38*8-4,88,0 ; just outside
_deadbodypos dc 0,0,1 ; dead body
dc 38*8-4,88,0 ; just outside
dc 38*8-4,83,0 ; entrance
dc 34*8+5,82,-1 ; inside and done
walkseqcode_rigor
cmp #1,d0
beq.b .fetchbody
cmp #-1,d0
beq.b .remrigor
rts
.fetchbody move.l p_rigorbody(a3),a0
st.b p_rigorgot(a0)
rts
.remrigor move.l p_bob(a3),a0
move.b #2,bo_inactive(a0)
move.l p_rigorbody(a3),a0
clr.l p_rigorbody(a3)
move.l a0,a3
cmp.b #(OT_SHERIFF1),p_type(a3)
beq.b lose_life
cmp.b #(OT_SHERIFF2),p_type(a3)
beq.b lose_life
clr.b p_dead(a3)
bra.w remove_outlaw
lose_life lea _player1(pc),a0
tst p_lives(a0)
beq.b .not1
clr.b _hero1dead
tst.b p_dead(a0)
beq.b .not1
clr.b p_dead(a0)
subq #1,p_lives(a0)
bne.b .not1
st.b _hero1dead
move.l p_bob(a0),a0
move.b #2,bo_inactive(a0)
.not1 lea _player2(pc),a0
tst p_lives(a0)
beq.b .not2
clr.b _hero2dead
tst.b p_dead(a0)
beq.b .not2
clr.b p_dead(a0)
subq #1,p_lives(a0)
bne.b .not2
st.b _hero2dead
move.l p_bob(a0),a0
move.b #2,bo_inactive(a0)
.not2 cmp.b #2,_numplayers
beq.b .check2
tst.b _hero1dead
beq.b .gogo
st.b _gameover
rts
.check2 cmp #$FFFF,_hero1dead
bne.b .gogo
st.b _gameover
rts
.gogo st.b _restartwave
rts
_gameover dc.b 0,0
; ---- ADD OUTLAWS ACCORDING TO RANDOM TIMER ----
add_outlaws tst.b _mustshoot
beq.b .nono
cmp #$FFFF,_hero1dead
beq.b .nono
cmp.b #5,_wave
beq.b .olokay
cmp.b #2,_numplayers
bne.b .only1
tst.b _hero2dead
bne.b .only1
lea _player2(pc),a0
move.l p_bob(a0),a0
tst.b bo_maskmade(a0)
bne.b .nono
tst.b _hero1dead
bne.b .olokay
.only1 tst.b _hero1dead
bne.b .nono
lea _player1(pc),a0
move.l p_bob(a0),a0
tst.b bo_maskmade(a0) ; no new outlaws if inside bld.
beq.b .olokay
.nono rts
.olokay tst _outlawtimer
beq.b .addone
subq #1,_outlawtimer
bne.b .nono
.addone move _outlawmaxtime(pc),d0
bsr.w random
move d0,_outlawtimer
bra.w add_outlaw
; ---- ADD SNIPERS ACCORDING TO RANDOM TIMER ----
add_snipers tst.b _mustshoot
beq.b .nonew
cmp.b #4,_wave
beq.b .ok
rts
.ok cmp #$FFFF,_hero1dead
beq.b .nonew
lea  nbsp; _player2(pc),a0
move.l p_bob(a0),a0
tst.b bo_maskmade(a0)
bne.b .nonew
lea _player1(pc),a0
move.l p_bob(a0),a0
tst.b bo_maskmade(a0)
beq.b .ok2
.nonew rts
.ok2 tst _snipertimer
beq.b .addone
subq #1,_snipertimer
rts
.addone move _snipermaxtime(pc),d0
bsr.w random
move d0,_snipertimer
moveq #2,d0 ; max. 3 snipers
lea _snipers+(SN_SIZEOF*2)(pc),a0
.1 tst.b sn_counter(a0)
beq.b .okko
subq #(SN_SIZEOF),a0
dbf d0,.1
rts
.okko moveq #5,d0
bsr.w random
lea _snipers(pc),a1
cmp.b sn_number(a1),d0
beq.b .okko
addq #(SN_SIZEOF),a1
cmp.b sn_number(a1),d0
beq.b .okko
addq #(SN_SIZEOF),a1
cmp.b sn_number(a1),d0
beq.b .okko
move.b #(SNIPEDELAY),sn_counter(a0)
move.b d0,sn_number(a0)
move.b #2,sn_draw(a0)
lea _sniperxpos(pc),a0
moveq #0,d2
move.b (a0,d0),d2
lea _player1(pc),a0
tst.b p_dead(a0)
bne.b .onlypl2
tst.b _hero1dead
bne.b .onlypl2
lea _player2(pc),a0
tst.b p_dead(a0)
bne.b .onlypl1
tst.b _hero2dead
bne.b .onlypl1
moveq #2,d0
bsr.w random ; random sheriff
tst d0
beq.b .onlypl1
.onlypl2 lea _player2(pc),a0
bra.b .okok
.onlypl1 lea _player1(pc),a0
.okok move.l p_bob(a0),a0
move d2,d0
lsl #3,d0
move bo_x(a0),d1
cmp d0,d1
beq.b .shootdown
cmp d0,d1
blo.b .shootleft
move d1,d2
sub d0,d2
cmp #32,d2
bhi.b .yes
bra.b .shootdown
.yes moveq #84,d1
move.b #(DI_DOWNRIGHT),d2
bra.b .add_bullet
.shootdown moveq #84,d1
move.b #(DI_DOWN),d2
bra.b .add_bullet
.shootleft move d0,d2
sub d1,d2
cmp #32,d2
bhi.b .okk
bra.b .shootdown
.okk moveq #84,d1
move.b #(DI_DOWNLEFT),d2
.add_bullet movem.l d0-d2,-(sp)
move #$0501,d0
moveq #0,d2
bsr.w play_sfx
movem.l (sp)+,d0-d2
bra.w add_bullet
RSRESET
sn_counter RS.B 1
sn_number RS.B 1
sn_draw RS.B 2 ; +is draw -is clear
sn_sizeof RS.B 0
_snipers blk.b (SN_SIZEOF)*3,0
draw_snipers cmp.b #4,_wave
beq.b .ok
rts
.ok moveq #0,d0 ; max. 3 snipers
moveq #2,d2
lea _snipers+(SN_SIZEOF*2)(pc),a0
.1 cmp.b #1,sn_draw(a0)
bge.b .okko
subq #(SN_SIZEOF),a0
dbf d2,.1
rts
.okko subq.b #1,sn_draw(a0)
move.b sn_number(a0),d0
bra.w draw_sniper
clear_snipers cmp.b #4,_wave
beq.b .ok
rts
.ok moveq #0,d0 ; max. 3 snipers
moveq #2,d2
lea _snipers+(SN_SIZEOF*2)(pc),a0
.1 cmp.b #-1,sn_draw(a0)
ble.b .okko
subq #(SN_SIZEOF),a0
dbf d2,.1
rts
.okko addq.b #1,sn_draw(a0)
bne.b .stl
move.b sn_number(a0),d0
bra.b .ddd
clr.b sn_number(a0)
.stl move.b sn_number(a0),d0
.ddd bra.w clear_sniper
update_snipercount
cmp.b #4,_wave
beq.b .ok
rts
.ok lea _snipers+(SN_SIZEOF*2)(pc),a0
moveq #2,d0
.1 tst.b sn_counter(a0)
bhi.b .okko
.2 subq #(SN_SIZEOF),a0
dbf d0,.1
rts
.okko subq.b #1,sn_counter(a0)
bne.b .still
move.b #-2,sn_draw(a0)
.still bra.b .2
; ---- CLEAR FIRSTFLAGS ----
clear_firstflags
lea _bobstructs(pc),a0
moveq #(MAXBOBS-1),d0
.1 clr.b bo_firstflag(a0)
lea BO_SIZEOF(a0),a0
dbf d0,.1
rts
; ---- CREATE MASKS ----
create_masks cmp.b #5,_wave
blo.b .ok
rts
.ok lea _player1(pc),a4
moveq #(MAXBOBS-1),d4
.1 move.l a4,a3
bsr.w create_mask
lea P_SIZEOF(a4),a4
dbf d4,.1
rts
; ---- UPDATE SHOOTING ----
update_shooting
lea _player1(pc),a3
moveq #(MAXBOBS-1),d7
.1 bsr.w check_shot
lea P_SIZEOF(a3),a3
dbf d7,.1
rts
; ---- READ DEVICES ----
update_devices lea _player1(pc),a4
moveq #(MAXBOBS-1),d7
.1 move.l a4,a3
bsr.w read_device
lea P_SIZEOF(a4),a4
dbf d7,.1
rts
; ---- UPDATE ANIMATIONS ----
update_animations
lea _player1(pc),a3
moveq #(MAXBOBS-1),d7
.1 bsr.w animate_actors
lea P_SIZEOF(a3),a3
dbf d7,.1
rts
; ---- UPDATE MOVEMENTS ----
update_movements
lea _player1(pc),a3
moveq #(MAXBOBS-1),d7
.1 bsr.w move_actor
lea P_SIZEOF(a3),a3
dbf d7,.1
rts
_numkidnappers dc.b 0
_numoutlaws dc.b 0
_numbobs dc.b 0
EVEN
; ---- ADD A HOOKER ----
add_hooker lea _hookers(pc),a3
moveq #(MAXHOOKERS-1),d7
.1 move.l p_bob(a3),a2
tst.b bo_inactive(a2)
bne.b .ok2
lea P_SIZEOF(a3),a3
dbf d7,.1
moveq #-1,d0
rts
.ok2 clr.b bo_inactive(a2)
st.b bo_firstflag(a2)
clr.b p_runhome(a3)
bsr.w reset_pstruct
st.b p_noshoot(a3)
moveq #0,d0
rts
; ---- ADD AN OUTLAW ----
add_outlaw cmp.b #(MAXBOBS),_numbobs
beq.b .no
cmp.b #(OUTLAWLIMIT),_numoutlaws
blo.b .ok
.no rts
.ok lea _outlaws(pc),a3
moveq #(MAXOUTLAWS-1),d0
.1 move.l p_bob(a3),a2
tst.b bo_inactive(a2)
bne.b .ok2
lea P_SIZEOF(a3),a3
dbf d0,.1
rts
.ok2 bsr.w set_outlawtype
tst d0
bmi.b .nothing
moveq #0,d0
clr.b bo_inactive(a2)
st.b bo_firstflag(a2) ; activate outlaw bob
bsr.w reset_pstruct
cmp.b #(OT_HORSEMAN),p_type(a3)
beq.b .nothing
bsr.w set_randomposition
bsr.w set_outlawanimations
.nothing rts
; ---- REMOVE OUTLAW ----
remove_outlaw subq.b #1,_numoutlaws
move.l p_bob(a3),a0
move.b #2,bo_inactive(a0) ; remove outlaw
clr.b p_rigorgot(a3)
clr.b p_joystick(a3)
clr.b p_xalign(a3)
clr.b p_dead(a3)
clr.b p_nomove(a3)
cmp.b #(OT_KIDNAPPER),p_type(a3)
bne.b .nohooker
move.l p_outlawhooker(a3),d0
beq.b .nohooker
move.l d0,a0
tst.b p_runhome(a0)
bne.b .nohooker
clr.l p_hookeroutlaw(a0)
move.l p_bob(a0),a0
move.b #2,bo_inactive(a0) ; remove hooker
.nohooker cmp.b #(OT_ROBBER),p_type(a3)
bne.b .norob
rts
.norob cmp.b #(OT_KIDNAPPER),p_type(a3)
bne.b .nokid
subq.b #1,_numkidnappers
rts
.nokid cmp.b #(OT_DYNAMAN),p_type(a3)
bne.b .nodyn
clr.b p_nevershoot(a3)
; subq.b #1,_numoutlaws
clr.b _dynamiteactive
.nodyn rts
; ---- RESET PLAYER STRUCTURE (OUTLAW) ----
reset_pstruct moveq #0,d0
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
clr.b p_animpos(a3)
move.l d0,p_hookeroutlaw(a3)
move.l d0,p_outlawhooker(a3)
move d0,p_zone(a3)
move d0,p_building(a3)
move d0,p_walkseqpos(a3)
clr.b p_rigorgot(a3)
clr.b p_nomove(a3)
clr.b p_noup(a3)
clr.b p_nodown(a3)
clr.b p_noleft(a3)
clr.b p_noright(a3)
clr.b p_noshoot(a3)
clr.b p_dead(a3)
clr.b p_joystick(a3)
move.b #1,p_direction(a3)
clr.b p_lastdirection(a3)
move.b #1,p_shootcounter(a3)
clr.b p_shooting(a3)
move.b #1,p_walkcntx(a3)
move.b #1,p_walkcnty(a3)
cmp.b #(OT_HORSEMAN),p_type(a3)
beq.b .noon
move.l #_outlawshoot,p_shootimages(a3)
move.l #_outlawdrag,p_dragimages(a3)
move.l #_outlawdie,p_animdie(a3)
.noon move _initkillscore(pc),p_score(a3)
clr p_scorecount(a3)
rts
; ---- SET OUTLAW ANIMATIONS ----
set_outlawanimations
lea _animtableoutlaw(pc),a0
lea p_animup(a3),a1
moveq #7,d0
.2 move.l (a0)+,(a1)+
dbf d0,.2
rts
OT_SHERIFF1 = $40 ; bit 6 identifies sheriff
OT_SHERIFF2 = $41
OT_ROBBER = $81 ; bit 7 identifies outlaw
OT_KIDNAPPER = $82
OT_DYNAMAN = $83
OT_HORSEMAN = $84
OT_KILLER = $85
OT_HOOKER = 3
OT_RIGOR = 4
OT_DYNA = 5
OT_HORSE = 6
; ---- SET OUTLAW TYPE (BANK ROBBER/KIDNAPPER/DYNAMITE MANIAC) ----
set_outlawtype cmp.b #5,_wave
beq.w type_killer
moveq #4,d0
bsr.w random
lsl #2,d0
jmp _typeinittable(pc,d0.w)
_typeinittable jmp type_bankrobber(pc)
jmp type_kidnapper(pc)
jmp type_dynamiteman(pc)
jmp type_horseman(pc)
; ---- SET TYPE: HORSEMAN ----
type_horseman cmp.b #3,_wave
bge.b .okokok
moveq #-1,d0
rts
.okokok cmp.b #5,_wave
beq.b .no
tst.b _horseactive
bne.b .no
cmp.b #(MAXBOBS-2),_numbobs
ble.b .ok
.no moveq #-1,d0
rts
.ok addq.b #1,_numoutlaws
move.b #1,_horsefxcount
st.b _horseactive
bsr.w init_horseman
bsr.w init_horse
moveq #2,d0
bsr.w random
tst d0
beq.b .left
.right move.l #_horsemanshootright,p_shootimages(a3)
move.l #_horsemandieright,p_animdie(a3)
move.b #(DI_RIGHT),p_direction(a3)
moveq #2,d0
bsr.w random
lsl #2,d0
move _horsestartright(pc,d0.w),bo_x(a0)
move _horsestartright+2(pc,d0.w),bo_y(a0)
lea _horse(pc),a0
move.b #(DI_RIGHT),p_direction(a0)
lea _animhorseright(pc),a1
bra.b .setanim
.left move.l #_horsemanshootleft,p_shootimages(a3)
move.l #_horsemandieleft,p_animdie(a3)
move.b #(DI_LEFT),p_direction(a3)
moveq #2,d0
bsr.w random
lsl #2,d0
move _horsestartleft(pc,d0.w),bo_x(a0)
move _horsestartleft+2(pc,d0.w),bo_y(a0)
lea _horse(pc),a0
move.b #(DI_LEFT),p_direction(a0)
lea _animhorseleft(pc),a1
.setanim move (a1)+,d0
move.b d0,p_animspeed(a0) ; first byte is animspeed
move.b #1,p_animspdcount(a0)
move.l a1,p_animation(a0)
clr.b p_animpos(a0)
moveq #0,d0
rts
_horsestartright
dc 0,104
dc 0,154
_horsestartleft
dc 320,104
dc 320,154
init_horseman move.b #(OT_HORSEMAN),p_type(a3)
clr.b p_noshoot(a3)
clr.b p_dead(a3)
move _initkillscore(pc),p_score(a3)
clr p_scorecount(a3)
move.l a3,_horseman
lea _horsemandrag(pc),a0
move.l a0,p_dragimages(a3)
rts
init_horse lea _horse(pc),a0
move.b #1,p_walkspdcount(a0)
st.b p_nomove(a0)
st.b p_nevershoot(a0)
move.l p_bob(a0),a0
clr.b bo_inactive(a0)
st.b bo_firstflag(a0) ; activate horse
rts
_horseactive dc.b 0,0
_horseman dc.l 0
; ---- SET TYPE: BANK ROBBER ----
type_bankrobber addq.b #1,_numoutlaws
lea walkseqcode_bankrobbery(pc),a0
move.l a0,p_walkseqcode(a3)
moveq #2,d0
bsr.w random
tst d0
beq.b .left
lea _banksequenceright(pc),a0
bra.b .2
.left lea _banksequenceleft(pc),a0
.2 lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
bsr.w get_randomposition
move (a0)+,-2(a1) ; runaway exit
move (a0)+,(a1)
move #-1,2(a1)
clr p_walkseqpos(a3)
move.b #(OT_ROBBER),p_type(a3)
moveq #0,d0
rts
_banksequenceright
dc 29*8-4,86,0 ; bank entrance
dc 29*8-4,82,0 ; inside
dc 33*8-6,82,1 ; inside bank (right)
dc 29*8-4,82,0 ; bank entrance
dc 29*8-4,84,0 ; and down
dc 0,140,-1 ; and run away
_banksequenceleft
dc 29*8-4,86,0 ; bank entrance
dc 29*8-4,82,0 ; inside
dc 25*8,82,1 ; inside bank (left)
dc 29*8-4,82,0 ; bank entrance
dc 29*8-4,84,0 ; and down
dc 0,140,-1 ; and run away
; ---- SET TYPE: KIDNAPPER ----
type_kidnapper cmp.b #(MAXKIDNAPPERS),_numkidnappers
bne.b .ok
moveq #-1,d0
rts
.ok addq.b #1,_numkidnappers
addq.b #1,_numoutlaws
lea walkseqcode_kidnapping(pc),a0
move.l a0,p_walkseqcode(a3)
moveq #2,d0
bsr.w random
tst d0
beq.b .left
lea _saloonsequenceright(pc),a0
bra.b .2
.left lea _saloonsequenceleft(pc),a0
.2 lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
bsr.b get_randomposition
move (a0)+,-2(a1) ; runaway exit
move (a0)+,(a1)
move #-1,2(a1)
clr p_walkseqpos(a3)
move.b #(OT_KIDNAPPER),p_type(a3)
moveq #0,d0
rts
_saloonsequenceleft
dc 19*8-4,83,0 ; sal. entrance
dc 19*8-4,82,0 ; inside
dc 16*8-4,82,1 ; inside saloon left
dc 19*8-4,82,0 ; inside
dc 19*8-4,84,0 ; sal. entrance
dc 0,140,-1 ; and run away
_saloonsequenceright
dc 19*8-4,83,0 ; sal. entrance
dc 19*8-4,82,0 ; inside
dc 23*8-4,82,1 ; inside saloon right
dc 19*8-4,82,0 ; inside
dc 19*8-4,84,0 ; sal. entrance
dc 0,140,-1 ; and run away
get_randomposition
moveq #6,d0
bsr.w random
lsl #2,d0
lea _startpositions(pc),a0
add d0,a0
rts
_twoplayers dc.b 0
_dynamitepl2 dc.b 0
_dynamiteactive dc.b 0
_dynaset dc.b 0
_dynamiteinrange
dc.b 0
_dynablow dc.b 0
_dynamiteman dc.l 0
; ---- SET TYPE: DYNAMITE MANIAC ----
type_dynamiteman
cmp.b #2,_wave
bge.b .okokok
moveq #-1,d0
rts
.okokok cmp.b #5,_wave
beq.b .nonono
tst.b _dynaset
beq.b .ok
.nonono moveq #-1,d0
rts
.ok tst.b _dynamiteactive
beq.b .ok2
moveq #-1,d0
rts
.ok2 cmp.b #(MAXBOBS-2),_numbobs
blo.b .ok3
moveq #-1,d0
rts
.ok3 addq.b #1,_numoutlaws
st.b _dynamiteactive
st.b p_nevershoot(a3)
move.l a3,_dynamiteman
lea walkseqcode_dynamite(pc),a0
move.l a0,p_walkseqcode(a3)
lea _dynamitesequence(pc),a0
clr.b _dynamitepl2
cmp.b #2,_numplayers
bne.b .ispl1
tst.b _hero1dead
bne.b .ispl2
tst.b _hero2dead
bne.b .ispl1
moveq #2,d0
bsr.w random
tst d0
bne.b .ispl1
.ispl2 st.b _dynamitepl2
.ispl1 lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
bsr.w get_randomposition
clr p_walkseqpos(a3)
move.b #(OT_DYNAMAN),p_type(a3)
moveq #0,d0
rts
_dynamitesequence
dc 0,0,1 ; hero1 or 2
dc 19*8-4,82,0 ; inside
dc 16*8-4,82,0 ; inside saloon left
dc 19*8-4,82,0 ; inside
dc 19*8-4,84,0 ; sal. entrance
dc 0,140,-1 ; and run away
; ---- SET TYPE: KILLER ----
type_killer addq.b #1,_numoutlaws
lea walkseqcode_killer(pc),a0
move.l a0,p_walkseqcode(a3)
lea _killersequence(pc),a0
lea p_walksequence(a3),a1
moveq #1,d0
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d0,.1
lea p_walksequence(a3),a0
move.l #272,d0
bsr.w random
add #32,d0
move d0,(a0) ; new dest. x
moveq #83,d0
bsr.w random
add #88,d0
move d0,2(a0) ; new dest. y
clr p_walkseqpos(a3)
move.b #(OT_KILLER),p_type(a3)
moveq #0,d0
rts
_killersequence
dc 0,0,1 ; random position
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
dc 0,0,0
; ---- SET A RANDOM START POSITION FOR OUTLAWS ----
set_randomposition
cmp.b #5,_wave
bne.b .nono
moveq #8,d0
bra.b .rand
.nono moveq #6,d0
.rand bsr.w random
lsl #2,d0
cmp.b #5,_wave
bne.b .okok
lea _startpositions5(pc,d0),a0
bra.b .setpos
.okok lea _startpositions(pc,d0),a0
.setpos move (a0)+,bo_x(a2) ; set start position
move (a0)+,bo_y(a2) ; set start position
rts
_startpositions dc 0,90
dc 0,150
dc 0,170
dc 352,90
dc 352,150
dc 352,170
_startpositions5
dc 0,90
dc 0,150
dc 0,170
dc 352,90
dc 352,150
dc 352,170
dc 180,83
dc 180,83
; ---- CHECK IF PLAYER SHOOTS ----
check_shot tst.b p_nevershoot(a3)
bne.b .okok
tst.b p_dead(a3)
bne.b .noshot
move.l p_bob(a3),a0
tst.b bo_inactive(a0)
beq.b .isactive
.okok rts
.isactive tst.b p_shootcounter(a3)
beq.b .ok
subq.b #1,p_shootcounter(a3)
rts
.ok tst.b p_fire(a3)
bne.b .isshot
.noshot clr.b p_shooting(a3)
clr.b p_nomove(a3)
rts
.isshot tst.b p_noshoot(a3)
bne.b .noshot
tst.b _bonusdraw
bne.b .isnotout
btst #7,p_type(a3)
beq.b .isnotout
cmp #$FFFF,_hero1dead
beq.b .noshot
.noout bsr.b set_shootdir
.isnotout move #$0501,d0 ; gunshot
moveq #0,d2
bsr.w play_sfx
st.b p_shooting(a3)
move.b #1,p_animspdcount(a3)
st.b p_nomove(a3)
move.b p_shootdelay(a3),p_shootcounter(a3)
moveq #0,d3
move.l p_bob(a3),a0
move bo_x(a0),d0
move bo_y(a0),d1
move.b p_direction(a3),d2
bne.b .1
move.b p_lastdirection(a3),d2
.1 move.b d2,d3
lsl #2,d3
add _bulletstarttable(pc,d3),d0
add _bulletstarttable+2(pc,d3),d1
bra.w add_bullet
; ---- bullet start offsets -----
_bulletstarttable
dc.l 0
dc 16,-2 ; up
dc 0,-2 ; upleft
dc 32,0 ; upright
dc 0,23 ; down
dc -4,16 ; downleft
dc 24,23 ; downright
dc&nbsnbsp; -4,10 ; left
dc 32,10 ; right
; ---- SET SHOOT DIRECTION FOR OUTLAWS ----
set_shootdir tst.b _hero2dead
bne.b .onlypl1
tst.b _hero1dead
bne.b .onlypl2
moveq #2,d0
bsr.w random ; random sheriff
tst d0
beq.b .onlypl1
.onlypl2 lea _player2(pc),a0
bra.b .dothing
.onlypl1 lea _player1(pc),a0
.dothing move.l p_bob(a0),a0
move.l p_bob(a3),a1
move.b #1,p_animspdcount(a3)
movem bo_x(a1),d0-d1
movem bo_x(a0),d2-d3
clr d4
cmp d0,d2
beq.b .upd
cmp d0,d2
blo.b .left
or #$0100,d4
bra.b .upd
.left or #$FF00,d4
.upd cmp d1,d3
beq.b .chk
cmp d1,d3
blo.b .up
or #$0001,d4
bra.b .chk
.up or #$00FF,d4
.chk tst d4
beq.b .dontshoot
cmp #$FF00,d4
beq.b .shootleft
cmp #$FF01,d4
beq.b .shootleftdown
cmp #$FFFF,d4
beq.b .shootleftup
cmp #$0100,d4
beq.b .shootright
cmp #$01FF,d4
beq.b .shootrightup
cmp #$0101,d4
beq.b .shootrightdown
.dontshoot rts
.shootleft move.b #(DI_LEFT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootleftup moveq #4,d0
bsr.w random
subq.b #1,d0
beq.b .shootleft
subq.b #1,d0
beq.b .shootup
move.b #(DI_UPLEFT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootleftdown
moveq #4,d0
bsr.w random
subq.b #1,d0
beq.b .shootleft
subq.b #1,d0
beq.b .shootdown
move.b #(DI_DOWNLEFT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootright move.b #(DI_RIGHT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootrightup moveq #4,d0
bsr.w random
subq.b #1,d0
beq.b .shootright
subq.b #1,d0
beq.b .shootup
move.b #(DI_UPRIGHT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootrightdown moveq #4,d0
bsr.w random
subq.b #1,d0
beq.b .shootright
subq.b #1,d0
beq.b .shootdown
move.b #(DI_DOWNRIGHT),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootup move.b #(DI_UP),p_lastdirection(a3)
clr.b p_direction(a3)
rts
.shootdown move.b #(DI_DOWN),p_lastdirection(a3)
clr.b p_direction(a3)
rts
; ---- CHECK IF DYNAMITE KILLS SOMEBODY ----
check_dynamite tst.b _dynablow
bne.b .test
rts
.test lea _player1(pc),a3
lea _dynamite(pc),a0
move.l p_bob(a0),a0
movem bo_x(a0),d0/d1
moveq #(MAXBOBS-1),d4
.loop tst.b p_dead(a3)
bne.b .nxt
tst.b p_cantdie(a3)
bne.b .nxt
move.l p_bob(a3),a0
tst.b bo_maskmade(a0)
bne.b .nxt
tst.b bo_inactive(a0)
bne.b .nxt
movem bo_x(a0),d2/d3
sub #24,d0
cmp d0,d2
blo.b .nxt
add #24+24+24,d0
cmp d0,d2
bhi.b .nxt
sub #22,d1
cmp d1,d3
blo.b .nxt
add #22+22+22,d1
cmp d1,d3
bhi.b .nxt
move.b #1,p_dead(a3)
.nxt lea P_SIZEOF(a3),a3
dbf d4,.loop
rts
; ---- CHECK IF BULLET HIT SOMEBODY ----
check_bullethit lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d7
.1 tst.b b_active(a0)
beq.b .next
moveq #0,d4
move.b b_direction(a0),d4
add d4,d4
add d4,d4
lea _player1(pc),a3
moveq #(MAXBOBS-1),d6
.2 tst.b p_dead(a3)
bne.b .nochk
tst.b p_cantdie(a3)
bne.b .nochk
move.l p_bob(a3),a1
movem bo_x(a1),d0/d1
cmp.b #5,_wave
beq.b .dnn
tst.b bo_maskmade(a1)
bne.b .nochk
.dnn move b_x(a0),d2
lsl #3,d2
move b_y(a0),d3
jsr _checkhittable(pc,d4.l)
.nochk lea P_SIZEOF(a3),a3
dbf d6,.2
.next lea B_SIZEOF(a0),a0
dbf d7,.1
rts
CNOP 0,4
_checkhittable dc.l 0
jmp chkh_up(pc)
jmp chkh_upleft(pc)
jmp chkh_upright(pc)
jmp chkh_down(pc)
jmp chkh_downleft(pc)
jmp chkh_downright(pc)
jmp chkh_leftright(pc)
jmp chkh_leftright(pc)
; ---- bullet hit somebody ----
bullet_hit btst #7,p_type(a3)
bne.w .isoutlaw
cmp.b #(OT_SHERIFF1),p_type(a3)
bne.b .no3
tst.b _bonusdraw
bne.b .wasbonus
btst #6,b_fromwho(a0)
bne.b .no3
st.b _hero1dead
move.b #1,p_dead(a3)
clr.b b_active(a0)
bra.b .playsong
.wasbonus move.b #1,p_dead(a3)
clr.b b_active(a0)
bra.b .playsong
.no3 cmp.b #(OT_SHERIFF2),p_type(a3)
bne.w .no2
tst.b _bonusdraw
bne.b .wasbonus
btst #6,b_fromwho(a0)
bne.w .no2
st.b _hero2dead
move.b #1,p_dead(a3)
clr.b b_active(a0)
.playsong movem.l d0-d2/a0-a3,-(sp)
lea _musicdata,a0
moveq #1,d0
moveq #0,d1
jsr FM_INITSONG(a0)
st.b _nosfx
movem.l (sp)+,d0-d2/a0-a3
rts
.isoutlaw move.b #1,p_dead(a3)
clr.b b_active(a0)
tst.b _bonusdraw
bne.w .no2
cmp.b #(OT_SHERIFF1),b_fromwho(a0)
bne.b .not1
move p_score(a3),d0
lea _player1(pc),a2
add d0,p_plscore(a2) ; add to score
add d0,p_lifescore(a2)
move.l a0,-(sp)
move.l a2,a0
bsr check_extralife
move.l (sp)+,a0
bsr.w print_score
bra.b .dobonus
.not1 cmp.b #(OT_SHERIFF2),b_fromwho(a0)
bne.b .not2
lea _player2(pc),a2
add d0,p_plscore(a2) ; add to score
add d0,p_lifescore(a2)
move.l a0,-(sp)
move.l a2,a0
bsr check_extralife
move.l (sp)+,a0
bsr.w print_score
bsr.w print_score
.dobonus move _killbonus(pc),d0
add d0,_bonus
bsr.w print_bonus
.not2 cmp.b #5,_wave
beq.b .is5
btst #6,b_fromwho(a0) ; shot by sheriff?
beq.b .no2
.is5 tst.b _mustshoot
beq.b .no2
lea _player1(pc),a2
tst.b p_dead(a2)
bne.b .no2
lea _player2(pc),a2
tst.b p_dead(a2)
bne.b .no2
subq.b #1,_mustshoot
.no2 cmp.b #(OT_KIDNAPPER),p_type(a3)
bne.b .no
move.l p_outlawhooker(a3),d0
beq.b .no
move.l d0,a1
clr.l p_hookeroutlaw(a1)
st.b p_runhome(a1)
.no cmp.b #(OT_HORSEMAN),p_type(a3)
bne.b .no4
clr.b p_nomove(a3)
.no4 rts
; ---- check hit if bullet up ----
chkh_up cmp d1,d3
blo.b .no
add #11,d1
cmp d1,d3
bhi.b .no
cmp d0,d2
blo.b .no
add #24,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet upleft ----
chkh_upleft cmp d1,d3
blo.b .no
add #11,d1
cmp d1,d3
bhi.b .no
cmp d0,d2
blo.b .no
add #12,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet upright ----
chkh_upright cmp d1,d3
blo.b .no
nbsp; add #11,d1
cmp d1,d3
bhi.b .no
add #12,d0
cmp d0,d2
blo.b .no
add #12,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet down ----
chkh_down add #11,d1
cmp d1,d3
blo.b .no
add #11,d1
cmp d1,d3
bhi.b .no
cmp d0,d2
blo.b .no
add #20,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet downleft ----
chkh_downleft add #11,d1
cmp d1,d3
blo.b .no
add #11,d1
cmp d1,d3
bhi.b .no
cmp d0,d2
blo.b .no
add #12,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet downright ----
chkh_downright add #11,d1
cmp d1,d3
blo.b .no
add #11,d1
cmp d1,d3
bhi.b .no
add #12,d0
cmp d0,d2
blo.b .no
add #12,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- check hit if bullet left or right ----
chkh_leftright cmp d1,d3
blo.b .no
add #22,d1
cmp d1,d3
bhi.b .no
addq #8,d0
cmp d0,d2
blo.b .no
addq #8,d0
cmp d0,d2
blo.w bullet_hit
.no rts
; ---- UPDATE BULLETS ----
update_bullets subq.b #1,_bulletspeed
beq.b .ok
rts
.ok move.b #3,_bulletspeed
bsr.w move_bullets
bra.b check_bullets
_bulletspeed dc.b 1,0
; ---- ADD A BULLET ----
; X (D0) Y (D1) DIRECTION (D2)
add_bullet lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d4
.1 tst.b b_active(a0)
beq.b .ok
add #(B_SIZEOF),a0
dbf d4,.1
rts
.ok move.b p_type(a3),b_fromwho(a0)
st.b b_active(a0)
lsr #3,d0
move d0,b_x(a0)
move d1,b_y(a0)
move.b d2,b_direction(a0)
rts
; ---- CHECK BULLET LIMITS (BORDERS) ----
check_bullets lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d0
.1 tst.b b_active(a0)
beq.b .next
moveq #0,d1
move.b b_direction(a0),d1
lsl #2,d1
jsr _checktable(pc,d1.l)
.next add #(B_SIZEOF),a0
dbf d0,.1
rts
_checktable jmp chkb_none(pc)
jmp chkb_up(pc)
jmp chkb_upleft(pc)
jmp chkb_upright(pc)
jmp chkb_down(pc)
jmp chkb_downleft(pc)
jmp chkb_downright(pc)
jmp chkb_left(pc)
jmp chkb_right(pc)
chkb_none rts
BULL_MINY = 10*8+8
BULL_MAXY = 25*8-4
BULL_MINX = 4
BULL_MAXX = 44
chkb_up cmp #(BULL_MINY),b_y(a0)
ble.b chkb_clear
rts
chkb_upleft cmp #(BULL_MINY),b_y(a0)
ble.b chkb_clear
cmp #(BULL_MINX),b_x(a0)
ble.b chkb_clear
rts
chkb_upright cmp #(BULL_MINY),b_y(a0)
ble.b chkb_clear
cmp #(BULL_MAXX),b_x(a0)
bge.b chkb_clear
rts
chkb_down cmp #(BULL_MAXY),b_y(a0)
bge.b chkb_clear
rts
chkb_downleft cmp #(BULL_MAXY),b_y(a0)
bge.b chkb_clear
cmp #(BULL_MINX),b_x(a0)
ble.b chkb_clear
rts
chkb_downright cmp #(BULL_MAXY),b_y(a0)
bge.b chkb_clear
cmp #(BULL_MAXX),b_x(a0)
bge.b chkb_clear
rts
chkb_left cmp #(BULL_MINX),b_x(a0)
ble.b chkb_clear
rts
chkb_right cmp #(BULL_MAXX),b_x(a0)
bge.b chkb_clear
rts
chkb_clear clr.b b_active(a0)
rts
; ---- MOVE BULLETS ----
move_bullets lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d0
.1 tst.b b_active(a0)
beq.b .next
moveq #0,d1
move.b b_direction(a0),d1
lsl #2,d1
move _bulldirtable(pc,d1.l),d2
add d2,b_x(a0)
move _bulldirtable+2(pc,d1),d2
add d2,b_y(a0)
.next add #(B_SIZEOF),a0
dbf d0,.1
rts
_bulldirtable dc.l 0 ; none
dc 0,-4 ; up
dc -1,-6 ; upleft
dc 1,-6 ; upright
dc 0,4 ; down
dc -1,6 ; downleft
dc 1,6 ; downright
dc -1,0 ; left
dc 1,0 ; right
; ---- DRAW BULLETS TO SCREEN ----
draw_bullets lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d2
.1 tst.b b_active(a0)
beq.b .next
bsr.b set_bullet
.next add #(B_SIZEOF),a0
dbf d2,.1
rts
; ---- CLEAR BULLETS FROM SCREEN ----
clear_bullets lea _bullets(pc),a0
moveq #(MAXBULLETS-1),d2
.1 tst.b b_active(a0)
beq.b .next
bsr.b clear_oldbullet
.next add #(B_SIZEOF),a0
dbf d2,.1
rts
clear_oldbullet movem b_oldx(a0),d0/d1
bra.b set_bull
set_bullet clr.b b_first(a0)
move b_x(a0),d0
move d0,b_oldx(a0)
moveq #0,d1
move b_y(a0),d1
move d1,b_oldy(a0)
set_bull mulu #(SCRWIDTH),d1
add d0,d1
move.l _dscreen(pc),a1
lea (a1,d1.w),a1
move.l _screen(pc),a2
lea (a2,d1.w),a2
move.b #%00011000,d0
eor.b d0,(SCRWIDTH*0)(a1)
eor.b d0,(SCRWIDTH*1)(a1)
eor.b d0,(SCRWIDTH*0)(a2)
eor.b d0,(SCRWIDTH*1)(a2)
rts
RSRESET
b_x RS 1 ; bullet x position (:8)
b_y RS 1 ; bullet y position
b_oldx RS 1 ; old x
b_oldy RS 1 ; old y
b_first RS.B 1 ; first flag
b_active RS.B 1 ; active flag
b_direction RS.B 1 ; which direction
b_fromwho RS.B 1 ; from who was the bullet fired
b_sizeof RS.B 0
_bullets blk.b (B_SIZEOF*MAXBULLETS),0
; ---- DRAW ARENA TO SCREEN ----
draw_arena cmp.b #5,_wave
beq.b .wave5
move.l #_arena1,_blockptr
move.l #_arena1map,_mapptr
bra.w draw_screen
.wave5 move.l #_arena2,_blockptr
move.l #_arena2map,_mapptr
bra.w draw_screen
; ---- DRAW TITLE TO SCREEN/HISCORE TO DSCREEN ----
draw_title move.l #_title,_blockptr
move.l #_titlemap,_mapptr
bsr.w draw_screen
bsr swap_screens
move.l #_highscore,_blockptr
move.l #_highscoremap,_mapptr
bsr.w draw_screen
moveq #10+4,d0
moveq #12,d1
moveq #19,d2
lea _halltxt(pc),a0
bsr print_text2 ; print hall of..
bsr print_hiscoretable
bsr swap_screens
lea _hisctxt(pc),a0
moveq #12+4,d0
moveq #13,d1
moveq #15,d2
bsr print_text2 ; print highscore
lea _leveltxt(pc),a0
moveq #16+4,d0
moveq #15,d1
moveq #6,d2
bsr print_text2
lea _presstxt(pc),a0 ; print "press" stuff
moveq #5+4,d0
moveq #21,d1
moveq #29,d2
bsr print_text2
lea _lastsctxt(pc),a0 ; print last score
moveq #5+4,d0
moveq #23,d1
moveq #29,d2
bsr print_text2
bsr print_level
lea _hiscoretable(pc),a0
move 10(a0),_hiscore
move _hiscore(pc),d0
moveq #5,d1
lea _score1txt(pc),a0
bsr.w numtoasc
moveq #23+4,d0
moveq #13,d1
moveq #4,d2
lea _score1txt(pc),a0 ; print highscore
bsr.w print_text2
moveq #0,d0
lea _player1(pc),a0
move p_plscore(a0),d0
moveq #5,d1
lea _score1txt(pc),a0
bsr.w numtoasc
moveq #21+4,d0
moveq #23,d1
moveq #4,d2
lea _score1txt(pc),a0
bsr.w print_text2
moveq #0,d0
lea _player2(pc),a0
move p_plscore(a0),d0
moveq #5,d1
lea _score1txt(pc),a0
bsr.w numtoasc
moveq #30+4,d0
moveq #23,d1
moveq #4,d2
lea _score1txt(pc),a0
bra.w print_text2
print_level moveq #22+4,d0
moveq #15,d1
moveq #0,d2
lea _level(pc),a0 ; print level
bra print_text2
_hisctxt dc.b "H"-55,"I"-55,"G"-55,"H"-55,37,"S"-55,"C"-55,"O"-55
dc.b "R"-55,"E"-55,37,0,0,0,0,0
_leveltxt dc.b "L"-55,"E"-55,"V"-55,"E"-55,"L"-55,37,0
_presstxt dc.b "F"-55,1,37,"O"-55,"N"-55,"E"-55,37
dc.b "P"-55,"L"-55,"A"-55,"Y"-55,"E"-55,"R"-55,37,36,37
dc.b "F"-55,2,37,"T"-55,"W"-55,"O"-55,37
dc.b "P"-55,"L"-55,"A"-55,"Y"-55,"E"-55,"R"-55,"S"-55
_lastsctxt dc.b "L"-55,"A"-55,"S"-55,"T"-55,37,"S"-55,"C"-55,"O"-55
dc.b "R"-55,"E"-55,"S"-55,37,37,37,1,37,0,0,0,0,0,37,37
dc.b 2,37,0,0,0,0,0
even
; ---- PRINT HISCORE TABLE ----
MAXENTRIES = 10
print_hiscoretable
lea _hiscoretable(pc),a1
moveq #11+4,d0
moveq #14,d1 ; start Y
moveq #(MAXENTRIES-1),d2
.loop movem.l d0-d2/a1,-(sp)
move.l a1,a0
moveq #9,d2
bsr print_text2
move d0,d3
move d1,d4
move 10(a1),d0 ; score
moveq #5,d1
lea _score1txt(pc),a0
bsr numtoasc
lea _score1txt(pc),a0
add #13,d3
move d3,d0
move d4,d1
moveq #4,d2
bsr print_text2
movem.l (sp)+,d0-d2/a1
add.l #12,a1
addq #1,d1
dbf d2,.loop
rts
_halltxt dc.b 37,37,37,37,"H"-55,"A"-55,"L"-55,"L"-55,37
dc.b "O"-55,"F"-55,37,"F"-55,"A"-55,"M"-55,"E"-55,37,37,37,37
even
_entertxt dc.b "E"-55,"N"-55,"T"-55,"E"-55,"R"-55,37
dc.b "Y"-55,"O"-55,"U"-55,"R"-55,37
dc.b "N"-55,"A"-55,"M"-55,"E"-55,37
dc.b "P"-55,"L"-55,37
_enterpl dc.b 1
;ABCDEFGHIJ 00000
_hiscoretable dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 10000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 9000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 8000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 7000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 6000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 5000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 4000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 3000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 2000
dc.b "S"-55,"E"-55,"A"-55,"S"-55,"O"-55,"N"-55,"S"-55
dc.b 37,37,37
dc 1000
d
blk.b 12,0 ; safety buffer
; ---- ENTER NAME IN HISCORE TABLE ----
enter_hiscore bsr swap_screens
move.l #_highscore,_blockptr
move.l #_highscoremap,_mapptr
bsr.w draw_screen
bsr print_hiscoretable
moveq #10+4,d0
moveq #12,d1
moveq #19,d2
lea _halltxt(pc),a0
bsr print_text2 ; print hall of..
clr _stringpos
lea _player1(pc),a0
move p_plscore(a0),d1
bsr check_entry
tst d0
bmi.b .nopl1
move d0,_which1
moveq #10+4,d0
moveq #12,d1
moveq #19,d2
lea _entertxt(pc),a0
move.b #1,_enterpl
bsr print_text2 ; print hall of..
move _which1(pc),d0
move d0,_which
lea _player1(pc),a0
move p_plscore(a0),d1
bsr.b .doit
.nopl1 lea _player2(pc),a0
move p_plscore(a0),d1
bsr check_entry
tst d0
bmi.b .nothing
move d0,_which2
moveq #10+4,d0
moveq #12,d1
moveq #19,d2
lea _entertxt(pc),a0
move.b #2,_enterpl
bsr print_text2 ; print hall of..
move _which2(pc),d0
move d0,_which
lea _player2(pc),a0
move p_plscore(a0),d1
.doit bsr insert_score
bsr print_hiscoretable
bsr clear_string
bsr print_string
clr _stringpos
bsr entermainloop
.nothing rts
_nohiscpl1 dc.b 0
_nohiscpl2 dc.b 0
entermainloop bsr get_key
moveq #0,d0
move.b _rawkey(pc),d0
beq.b entermainloop
cmp.b #$44,d0 ; ENTER
beq outta
cmp.b #$41,d0 ; BACKSPACE
bne.b .nono
tst _stringpos
beq.b .nono
subq #1,_stringpos
move.l _stringptr(pc),a0
add _stringpos(pc),a0
move.b #36,(a0)
move.b #37,1(a0)
bra.b .nocurs
.nono moveq #0,d1
move.b _rawtoascii(pc,d0),d1
bmi.b entermainloop
move.l _stringptr(pc),a0
add _stringpos(pc),a0
move.b d1,(a0)
cmp #9,_stringpos
beq.b .nocurs
addq #1,_stringpos
move.b #36,1(a0)
.nocurs bsr print_string
clr.b _rawkey
bsr release_key
bra entermainloop
outta clr.b _rawkey
bsr release_key
move.l _stringptr(pc),a0
add _stringpos(pc),a0
move.b #37,(a0)
bsr print_hiscoretable
moveq #10+4,d0
moveq #12,d1
moveq #19,d2
lea _halltxt(pc),a0
bsr print_text2 ; print hall of..
rts
_stringpos dc 0
_stringptr dc.l 0
_rawtoascii dc.b 0,1,2,3,4,5,6,7,8,9,0,$FF,$FF,$FF;$d
dc.b $FF,$FF,"Q"-55,"W"-55,"E"-55,"R"-55,"T"-55,"Y"-55
dc.b "U"-55,"I"-55,"O"-55,"P"-55,$FF,$FF;$1b
dc.b $FF,1,2,3,"A"-55,"S"-55,"D"-55,"F"-55
dc.b "G"-55,"H"-55,"J"-55,"K"-55,"L"-55,$FF,$FF,$FF;$2b
dc.b $FF,4,5,6,$FF,"Z"-55,"X"-55,"C"-55,"V"-55
dc.b "B"-55,"N"-55,"M"-55,$FF,$FF,$FF;$3a
dc.b $FF,$FF,7,8,37,37,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
dc.b $FF,$FF,$FF,$FF,$FF,$FF,$FF
EVEN
; ---- INSERT A SCORE ----
insert_score moveq #(MAXENTRIES-1),d3
sub d0,d3
lea _hiscoretable+12*(MAXENTRIES-1)(pc),a0
.nxt moveq #11,d2
.1 move.b (a0,d2.l),12(a0,d2.l)
dbf d2,.1
lea -12(a0),a0
dbf d3,.nxt
.okok mulu #12,d0
lea _hiscoretable(pc),a0
lea (a0,d0.w),a0
lea _blankscore(pc),a1
moveq #11,d0
.2 move.b (a1)+,(a0)+
dbf d0,.2
sub #12,a0
move d1,10(a0) ; insert score
move.l a0,_stringptr
rts
; ---- CHECK IF PLAYER GOT AN ENTRY ----
; score (d1)
check_entry moveq #0,d0
lea _hiscoretable(pc),a0
.next cmp 10(a0),d1
bhi.b .insert
addq #1,d0
lea 12(a0),a0
cmp #(MAXENTRIES),d0
bne.b .next
moveq #-1,d0
.insert rts
; ---- PRINT TEXT STRING ----
print_string move.l _stringptr(pc),a0
moveq #11+4,d0
move _which(pc),d1
add #14,d1
moveq #9,d2
bra print_text2
; ---- CLEAR INPUT STRING ----
clear_string lea _blankscore2(pc),a0
lea _blankscore(pc),a1
moveq #9,d0
.1 move.b (a0)+,(a1)+
dbf d0,.1
rts
_blankscore dc.b 36,37,37,37,37,37,37,37,37,37
dc 0
_blankscore2 dc.b 36,37,37,37,37,37,37,37,37,37
dc 0
_which dc 0
_which1 dc 0
_which2 dc 0
; ---- DRAW CHUNKY DISPLAY ----
draw_screen move.l _mapptr(pc),a0
.draw moveq #0,d2
moveq #0,d1
.row moveq #0,d0
.line moveq #0,d2
move.b (a0)+,d2
bsr set_block
addq #1,d0
cmp #40,d0
bne.b .line
addq #1,d1
cmp #25,d1
bne.b .row
rts
_blockptr dc.l 0
_mapptr dc.l 0
; ---- SET A BLOCK TO SCREEN ----
; x (d0) y (d1) block (d2)
set_block movem.l d0-d2/a0-a1,-(sp)
lsl #3,d1
mulu #(SCRWIDTH),d1
add d0,d1
addq #4,d1
move.l _dscreen(pc),a1
lea (a1,d1.l),a1
move.l _blockptr(pc),a0
lsl #5,d2
lea (a0,d2.l),a0
moveq #(NUMPLANES-1),d2
.1 move.b (a0)+,SCRWIDTH*0(a1)
move.b (a0)+,SCRWIDTH*1(a1)
move.b (a0)+,SCRWIDTH*2(a1)
move.b (a0)+,SCRWIDTH*3(a1)
move.b (a0)+,SCRWIDTH*4(a1)
move.b (a0)+,SCRWIDTH*5(a1)
move.b (a0)+,SCRWIDTH*6(a1)
move.b (a0)+,SCRWIDTH*7(a1)
lea PLANE_SIZE(a1),a1
dbf d2,.1
movem.l (sp)+,d0-d2/a0-a1
rts
; ---- DRAW SNIPER TO SCREEN ----
; sniper 0-4 (d0)
draw_sniper move.l _dscreen(pc),a1
lea 84*SCRWIDTH(a1),a1
lea _sniperdata,a0
moveq #0,d1
move.b _sniperxpos(pc,d0.l),d1
add d1,a1
move.l d0,d1
mulu #(88),d1
lea (a0,d1.l),a0 ; sniper gfx
moveq #(NUMPLANES-1),d1
.1 move (a0)+,SCRWIDTH*0(a1)
move (a0)+,SCRWIDTH*1(a1)
move (a0)+,SCRWIDTH*2(a1)
move (a0)+,SCRWIDTH*3(a1)
move (a0)+,SCRWIDTH*4(a1)
move (a0)+,SCRWIDTH*5(a1)
move (a0)+,SCRWIDTH*6(a1)
move (a0)+,SCRWIDTH*7(a1)
move (a0)+,SCRWIDTH*8(a1)
move (a0)+,SCRWIDTH*9(a1)
move (a0)+,SCRWIDTH*10(a1)
lea PLANE_SIZE(a1),a1
dbf d1,.1
rts
_sniperxpos dc.b 5,15,23,25,33
even
; ---- CLEAR SNIPER FROM SCREEN ----
; sniper 0-4 (d0)
clear_sniper move.l _dscreen(pc),a1
lea 84*SCRWIDTH(a1),a1
lea _sniperdata+440,a0
moveq #0,d1
move.b _sniperxpos(pc,d0.l),d1
add d1,a1
move.l d0,d1
mulu #(88),d1
lea (a0,d1.l),a0 ; sniper gfx
moveq #(NUMPLANES-1),d1
.1 move (a0)+,SCRWIDTH*0(a1)
move (a0)+,SCRWIDTH*1(a1)
move (a0)+,SCRWIDTH*2(a1)
move (a0)+,SCRWIDTH*3(a1)
move (a0)+,SCRWIDTH*4(a1)
move (a0)+,SCRWIDTH*5(a1)
move (a0)+,SCRWIDTH*6(a1)
move (a0)+,SCRWIDTH*7(a1)
move (a0)+,SCRWIDTH*8(a1)
move (a0)+,SCRWIDTH*9(a1)
move (a0)+,SCRWIDTH*10(a1)
lea PLANE_SIZE(a1),a1
dbf d1,.1
rts
; ---- CHECK TOP OF SCREEN ----
check_top cmp.b #5,_wave
beq.b check_top5
move.l p_bob(a3),a0
cmp #83,bo_y(a0)
beq.b .checkzone
clr.b p_noshoot(a3)
cmp #82,bo_y(a0)
bne.b .no
st.b p_noshoot(a3)
st.b p_noup(a3)
tst p_zone(a3)
beq.b .nodown
move p_zone(a3),p_building(a3)
clr.b p_nodown(a3)
rts
.nodown st.b p_nodown(a3)
rts
.no clr p_building(a3)
clr.b p_noup(a3)
clr.b p_nodown(a3)
rts
.checkzone tst p_zone(a3)
seq p_noup(a3)
rts
; ---- CHECK TOP OF SCREEN FOR WAVE 5 ----
check_top5 move.l p_bob(a3),a0
cmp #83,bo_y(a0)
bge.b .ok
st.b p_noup(a3)
rts
.ok clr.b p_noup(a3)
rts
; ---- GET ZONE FOR ACTOR ----
get_zone move.l p_bob(a3),a0
move bo_x(a0),d0
move bo_y(a0),d1
add #(BOBHEIGHT),d1
move d0,d2
moveq #24,d3
add d3,d2
moveq #1,d3 ; start, zone 1
lea _zonetable(pc),a0
.loop tst (a0)
bmi.b .done
cmp (a0),d1 ; y
bhi.b .no
cmp 2(a0),d0 ; x1
blo.b .no
cmp 4(a0),d2 ; x2
bhi.b .no
move d3,p_zone(a3)
rts
.no addq #1,d3
addq #6,a0
bra.b .loop
.done clr p_zone(a3)
rts
_zonetable dc (80+25),(116+28),(116+32+28) ; saloon entrance
dc (80+25),(196+28),(196+32+28) ; bank entrance
dc (80+25),(270+28),(268+32+28) ; rig.mortis entrance
dc -1
; ---- SET LIMITATIONS FOR WALKING ----
set_walklimitations
move p_building(a3),d0
beq.b .normal
subq #1,d0
beq.b .saloon
subq #1,d0
beq.b .bank
.rigmortis move #(250+31),p_xlimit1(a3)
move #(250+32+61),p_xlimit2(a3)
rts
.saloon move #(87+32),p_xlimit1(a3)
move #(87+32+81),p_xlimit2(a3)
rts
.bank move #(170+32),p_xlimit1(a3)
move #(170+32+78),p_xlimit2(a3)
rts
.normal move #(32),p_xlimit1(a3)
move #(32+320),p_xlimit2(a3)
rts
; ---- CHECK FOR WALK LIMITATIONS ----
check_walklimitations
move.l p_bob(a3),a0
move bo_x(a0),d0
move d0,d1
moveq #24,d2
add d2,d1
move bo_y(a0),d2
cmp p_xlimit1(a3),d0 ; x1
slo.b p_noleft(a3)
cmp p_xlimit2(a3),d1 ; x2
shi.b p_noright(a3)
cmp #173,d2 ; bottom of screen?
bne.b .ok
st.b p_nodown(a3)
.ok rts
; ---- SET SALOON DOOR OPEN ----
saloon_open tst.b _swapflag
bne.b .1
moveq #9,d0
moveq #80,d1
moveq #24,d2
lea _doordata+480,a0
bsr.w blit_block
bra.b .mask
.1
moveq #9,d0
moveq #80,d1
moveq #24,d2
lea _doordata+480,a0
bsr.w swap_screens
bsr.w blit_block
; bsr blit_block
bsr.w swap_screens
.mask lea _doordata+480+384+4*2,a0
moveq #7,d0
moveq #0,d1
moveq #22,d2
bra.w blit_mask
; ---- SET JAIL DOOR OPEN ----
jail_open moveq #5,d0
moveq #78,d1
moveq #26,d2
lea _doordata+480*2,a0
bsr.w blit_block
bsr.w swap_screens
moveq #5,d0
moveq #78,d1
moveq #26,d2
lea _doordata+480*2,a0
bsr.w blit_block
bsr.w swap_screens
rts
; ---- SET JAIL DOOR CLOSED ----
jail_close movem.l d0-d2/a0,-(sp)
moveq #5,d0
moveq #78,d1
moveq #26,d2
lea _doordata+480*2+520,a0
bsr.w blit_block
movem.l (sp)+,d0-d2/a0
rts
; ---- SET SALOON DOOR CLOSED ----
saloon_close moveq #9,d0
moveq #80,d1
moveq #24,d2
lea _doordata,a0
bsr.w blit_block
bsr.w swap_screens
bsr.w blit_block
bsr.w swap_screens
lea _doordata+384+4*2,a0
moveq #7,d0
moveq #0,d1
moveq #22,d2
bra.w blit_mask
; ---- PLAYER MOVEMENT ----
move_actor tst.b p_dead(a3)
beq.b .ok2
rts
.ok2 tst.b p_nomove(a3)
beq.b .ok3
rts
.ok3 move.l p_bob(a3),a0
tst.b bo_inactive(a0)
beq.b .isactive
rts
.isactive subq.b #1,p_walkspdcount(a3)
beq.b .ok
rts
.ok move.b p_walkspeed(a3),p_walkspdcount(a3)
moveq #0,d0
move.b p_joystick(a3),d0
move.l p_bob(a3),a0
jmp _movetable(pc,d0.l)
_movetable jmp no_move(pc)
jmp move_up(pc)
jmp move_upleft(pc)
jmp move_upright(pc)
jmp move_down(pc)
jmp move_downleft(pc)
jmp move_downright(pc)
jmp move_left(pc)
jmp move_right(pc)
no_move tst.b p_direction(a3)
beq.b .ok
move.b p_direction(a3),p_lastdirection(a3)
clr.b p_direction(a3)
.ok rts
move_up tst.b p_noup(a3)
bne.b .no
move p_addwalky(a3),d0
sub d0,bo_y(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_UP),p_direction(a3)
rts
move_upleft tst.b p_noup(a3)
bne.b .no
tst.b p_noleft(a3)
bne.b .no
move p_addwalky(a3),d0
sub d0,bo_y(a0)
move p_addwalkx(a3),d0
sub d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_UPLEFT),p_direction(a3)
rts
move_upright tst.b p_noup(a3)
bne.b .no
tst.b p_noright(a3)
bne.b .no
move p_addwalky(a3),d0
sub d0,bo_y(a0)
move p_addwalkx(a3),d0
add d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_UPRIGHT),p_direction(a3)
rts
move_down tst.b p_nodown(a3)
bne.b .no
move p_addwalky(a3),d0
add d0,bo_y(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_DOWN),p_direction(a3)
rts
move_downleft tst.b p_nodown(a3)
bne.b .no
tst.b p_noleft(a3)
bne.b .no
move p_addwalky(a3),d0
add d0,bo_y(a0)
move p_addwalkx(a3),d0
sub d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_DOWNLEFT),p_direction(a3)
rts
move_downright tst.b p_nodown(a3)
bne.b .no
tst.b p_noright(a3)
bne.b .no
move p_addwalky(a3),d0
add d0,bo_y(a0)
move p_addwalkx(a3),d0
add d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_DOWNRIGHT),p_direction(a3)
rts
move_left tst.b p_noleft(a3)
bne.b .no
move p_addwalkx(a3),d0
sub d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_LEFT),p_direction(a3)
rts
move_right tst.b p_noright(a3)
bne.b .no
move p_addwalkx(a3),d0
add d0,bo_x(a0)
.no move.b p_direction(a3),p_lastdirection(a3)
move.b #(DI_RIGHT),p_direction(a3)
rts
; ---- ANIMATE DYNAMITE/HORSE ----
animate_dynahorse
lea _dynamite(pc),a3
tst.b _dynaset
beq.b .no
bsr.b animate
cmp #-4,d1
bne.b .nofx
move #$0502,d0
moveq #1,d2
bsr.w play_sfx ; explosion
st.b _dynablow
.nofx cmp #-3,d1
bne.b .no
; ---- dynamite finish exploding ----
move.l p_bob(a3),a0
move.b #2,bo_inactive(a0)
clr.b _dynablow
clr.b _dynaset
.no tst.b _horseactive
beq.b .nono
lea _horse(pc),a3
bsr.b animate
move.l _horseman(pc),a0
tst.b p_dead(a0)
bne.b .nono
tst.b p_nomove(a0)
bne.b .nono
move.l p_bob(a0),a1
cmp.b #(DI_LEFT),p_direction(a3)
bne.b .right
move #(127),bo_image(a1)
rts
.right move #(135),bo_image(a1)
rts
.nono rts
animate subq.b #1,p_animspdcount(a3)
beq.b .ok
rts
.ok move.b p_animspeed(a3),p_animspdcount(a3)
move.l p_animation(a3),a0
moveq #0,d0
move.b p_animpos(a3),d0
move (a0,d0.l),d1
cmp #-1,d1
beq.b .reset
cmp #-2,d1
beq.b .dontcare
cmp #-3,d1
beq.b .is3
cmp #-4,d1
beq.b .is3
addq.b #2,p_animpos(a3)
move.l p_bob(a3),a0
move d1,bo_image(a0)
.dontcare rts
.is3 addq.b #2,p_animpos(a3)
rts
.reset clr.b p_animpos(a3)
move.b #1,p_animspdcount(a3)
rts
; ---- ANIMATE ACTORS ----
animate_actors move.l p_bob(a3),a0
tst.b bo_inactive(a0)
beq.b .isactive
rts
.isactive tst.b p_animoff(a3)
beq.b .animok
rts
.animok moveq #0,d0
tst.b p_rigorgot(a3)
bne.w a_rigor
tst.b p_shooting(a3)
bne.w a_shoot
cmp.b #1,p_dead(a3)
beq.w ai_die
tst.b p_dead(a3)
bmi.b continue_anim
move.b p_direction(a3),d0
cmp.b p_lastdirection(a3),d0
beq.b continue_anim
move.b #1,p_animspdcount(a3)
lsl #2,d0
jmp _animinittable(pc,d0.l)
_animinittable jmp ai_stop(pc)
jmp ai_up(pc)
jmp ai_upleft(pc)
jmp ai_upright(pc)
jmp ai_down(pc)
jmp ai_downleft(pc)
jmp ai_downright(pc)
jmp ai_left(pc)
jmp ai_right(pc)
; ---- CONTINUE ANIMATIONS ----
continue_anim subq.b #1,p_animspdcount(a3)
beq.b .ok
rts
.ok move.b p_animspeed(a3),p_animspdcount(a3)
move.l p_animation(a3),a0
moveq #0,d0
move.b p_animpos(a3),d0
move (a0,d0.l),d1
cmp #-1,d1
beq.b .reset
cmp #-2,d1
beq.b .dontcare
cmp #-3,d1
beq.b .addy
addq.b #2,p_animpos(a3)
move.l p_bob(a3),a0
move d1,bo_image(a0)
.dontcare rts
.addy addq.b #4,p_animpos(a3)
move 2(a0,d0.l),d1
move.l p_bob(a3),a0
add d1,bo_y(a0)
move.b #1,p_animspdcount(a3)
bra.b continue_anim
.reset clr.b p_animpos(a3)
move.b #1,p_animspdcount(a3)
bra.b continue_anim
; ---- RIGOR MORTIS DRAGS THIS BODY ----
a_rigor lea _rigormortis(pc),a0
move.l p_bob(a3),a1
moveq #0,d0
move.b p_direction(a0),d0 ; rigor direction
add d0,d0
&nnbsp; move.l p_dragimages(a3),a0
move (a0,d0.w),bo_image(a1)
rts
; ---- INITIALISE ANIMATIONS ----
ai_stop moveq #0,d0
move.b p_lastdirection(a3),d0
move.l p_stopimages(a3),a1
add d0,d0
move.l p_bob(a3),a0
move (a1,d0.l),bo_image(a0)
rts
a_shoot moveq #0,d0
move.b p_lastdirection(a3),d0
move.l p_shootimages(a3),a1
add d0,d0
move.l p_bob(a3),a0
move (a1,d0.l),bo_image(a0)
rts
ai_up move.l p_animup(a3),a0
bra.b ai_init
ai_upleft move.l p_animupleft(a3),a0
bra.b ai_init
ai_upright move.l p_animupright(a3),a0
bra.b ai_init
ai_down move.l p_animdown(a3),a0
bra.b ai_init
ai_downleft move.l p_animdownleft(a3),a0
bra.b ai_init
ai_downright move.l p_animdownright(a3),a0
bra.b ai_init
ai_left move.l p_animleft(a3),a0
bra.b ai_init
ai_right move.l p_animright(a3),a0
ai_init move (a0)+,d0
move.b d0,p_animspeed(a3) ; first byte is animspeed
move.b #1,p_animspdcount(a3)
move.l a0,p_animation(a3)
clr.b p_animpos(a3)
rts
ai_die move.l p_animdie(a3),a0
clr.b p_direction(a3)
clr.b p_lastdirection(a3)
st.b p_dead(a3)
bsr.b ai_init
bra.w continue_anim
_animtablesheriff dc.l _sheriffup
dc.l _sheriffupleft
dc.l _sheriffupright
dc.l _sheriffdown
dc.l _sheriffdownleft
dc.l _sheriffdownright
dc.l _sheriffleft
dc.l _sheriffright
_animtableoutlaw dc.l _outlawup
dc.l _outlawupleft
dc.l _outlawupright
dc.l _outlawdown
dc.l _outlawdownleft
dc.l _outlawdownright
dc.l _outlawleft
dc.l _outlawright
_animtableoutlawmoney dc.l _outlawup
dc.l _outlawupleft
dc.l _outlawupright
dc.l _outlawdownm
dc.l _outlawdownleftm
dc.l _outlawdownrightm
dc.l _outlawleftm
dc.l _outlawrightm
_animtablehooker dc.l _hookerup
dc.l _hookerupleft
dc.l _hookerupright
dc.l _hookerdown
dc.l _hookerdownleft
dc.l _hookerdownright
dc.l _hookerleft
dc.l _hookerright
_animtablerigor dc.l _rigorup
dc.l _rigorupleft
dc.l _rigorupright
dc.l _rigordown
dc.l _rigordownleft
dc.l _rigordownright
dc.l _rigorleft
dc.l _rigorright
; first word is animation speed
; -1 to loop animation
; -2 to end animation
; -3,(VAL) to add to bob's y position (used when dying)
_sheriffup dc 5,05,04,05,06,06,-1
_sheriffupleft dc 5,29,28,29,30,30,-1
_sheriffupright dc 5,25,24,25,26,26,-1
_sheriffdown dc 5,01,00,01,02,02,-1
_sheriffdownleft dc 5,21,20,21,22,22,-1
_sheriffdownright dc 5,17,16,17,18,18,-1
_sheriffleft dc 4,13,12,13,14,14,-1
_sheriffright dc 4,09,08,09,10,10,-1
_sheriffstop dc 0,5,29,25,1,21,17,13,9
_sheriffshoot dc 0,7,31,27,3,23,19,15,11
_sheriffdie dc 16,32,33,-2
_sheriffdrag dc 0,34,38,37,34,34,34,35,36
_outlawup dc 4,44,43,44,45,45,-1
_outlawupleft dc 4,62,61,62,63,63,-1
_outlawupright dc 4,59,58,59,60,60,-1
_outlawdown dc 4,41,40,41,42,42,-1
_outlawdownleft dc 4,56,55,56,57,57,-1
_outlawdownright dc 4,53,52,53,54,54,-1
_outlawleft dc 6,50,49,50,51,51,-1
_outlawright dc 6,47,46,47,48,48,-1
_outlawstop dc 0,44,62,59,41,56,53,50,47
_outlawshoot dc 0,44,62,59,41,56,53,50,47
_outlawdrag dc 0,120,124,123,120,120,120,121,122
_outlawdownm dc 4,65,64,65,66,66,-1
_outlawdownleftm dc 4,77,76,77,78,78,-1
_outlawdownrightm dc 4,71,70,71,72,72,-1
_outlawleftm dc 6,74,73,74,75,75,-1
_outlawrightm dc 6,68,67,68,69,69,-1
_outlawdie dc 16,125,-3,6,126,-2
_horsemanshootleft dc 0,133,134,132,129,128,130,127,131
_horsemanshootright dc 0,141,140,142,137,138,136,139,135
_horsemanstop dc 0,44,62,59,41,56,53,146,138
_horsemandrag dc 0,147,39,79,120,120,120,148,149
_horsemandieleft dc 8,143,143,-3,11,145,146,-2
_horsemandieright dc 8,144,144,-3,11,145,146,-2
_drawmanleft dc 4,153,150,153,151,151,-1
_drawmandie &nnbsp; dc 16,154,-3,6,155,-2
_hookerup dc 6,90,91,-1
_hookerupleft dc 6,92,93,-1
_hookerupright dc 6,94,95,-1
_hookerdown dc 6,80,81,-1
_hookerdownleft dc 6,88,89,-1
_hookerdownright dc 6,86,87,-1
_hookerleft dc 6,84,85,-1
_hookerright dc 6,82,83,-1
_hookerstop dc 80,80,80,80,80,80,80,80,80
_rigorup dc 3,100,099,100,101,101,-1
_rigorupleft dc 3,118,117,118,119,119,-1
_rigorupright dc 3,115,114,115,116,116,-1
_rigordown dc 3,097,096,097,098,098,-1
_rigordownleft dc 3,109,108,109,110,110,-1
_rigordownright dc 3,112,111,112,113,113,-1
_rigorleft dc 4,103,102,103,104,104,-1
_rigorright dc 4,106,105,106,107,107,-1
_rigorstop dc 100,100,118,115,097,109,112,103,106
_animdynamite dc 4,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
dc -4,2,5,2,3,4,3,2,6,5,6,-3
_animhorseleft dc 3,8,9,10,11,-1
_animhorseright dc 3,12,13,14,15,-1
;--------------------------------------
; Game Engine © 1997 Seasons.
;
; GRAPHICS: BLITTER OPERATIONS
;--------------------------------------
;---- BLIT A BOB TO SCREEN ----
; X (d0) Y (d1) BOB (d2) BOB (a3)
blit_bob lea _boblookuptable(pc),a1
moveq #2,d3
lsl d3,d2
move.l (a1,d2.l),a0 ; bob image
move.l bo_maskoff(a3),d3
lea (a0,d3.l),a1 ; bob mask
tst.b bo_maskmade(a3)
beq.b .3
move.l bo_newmask(a3),a1
.3 move.l _dscreen(pc),a2
mulu #(SCRWIDTH),d1
lea (a2,d1.l),a2 ; bpl address
move d0,d1
moveq #4,d3
lsr d3,d0
add d0,d0
lea (a2,d0.l),a2 ; bpl
move.l #$0FCA,d3 ; ABC|ABc|aBC|abC/UABCD
tst.b bo_maskmade(a3)
bne.b .noshift
moveq #15,d0
and d0,d1
moveq #4,d0
ror d0,d1
or d1,d3
swap d3
move d1,d3 ; d0=bltcon0/1
bra.b .1
.noshift moveq #15,d0
and d0,d1
moveq #4,d0
ror d0,d1
swap d3
move d1,d3
.1 move bo_height(a3),d2
moveq #6,d1
lsl d1,d2
addq #(BOBWIDTH/2),d2 ; bltsize
move bo_height(a3),d1
mulu #(BOBWIDTH),d1 ; one plane
moveq #-1,d0
CALLGRAF WaitBlit
move.l d0,BLTAFWM(a5) ; mask=$FFFFFFFF
moveq #(SCRWIDTH-BOBWIDTH),d0
move.l d0,BLTAMOD(a5) ; amod=0/dmod=34
swap d0
move.l d0,BLTCMOD(a5) ; cmod=34/bmod=0
moveq #(NUMPLANES-1),d0
.2 CALL WAITBLIT
move.l a0,BLTBPT(a5) ; image ptr
move.l a1,BLTAPT(a5) ; mask
move.l a2,BLTCPT(a5)
move.l a2,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5) ; bltcon0/1 set
move d2,BLTSIZE(a5) ; blit!
lea PLANE_SIZE(a2),a2
add d1,a0
dbf d0,.2
rts
;---- BLIT AN EXPANDED (48PIX WIDE/42PIX HIGH) BOB TO SCREEN ----
; X (d0) Y (d1) BOB (d2) BOB (a3)
blit_expbob lea _expbobdata,a0
mulu #(8*42*NUMPLANES)+(8*42),d2
add.l d2,a0 ; image
lea 8*42*NUMPLANES(a0),a1 ; mask
move.l _dscreen(pc),a2
mulu #(SCRWIDTH),d1
lea (a2,d1.l),a2 ; bpl address
move d0,d1
moveq #4,d3
lsr d3,d0
add d0,d0
lea (a2,d0.l),a2 ; bpl
move.l #$0FCA,d3 ; ABC|ABc|aBC|abC/UABCD
moveq #15,d0
and d0,d1
moveq #4,d0
ror d0,d1
or d1,d3
swap d3
move d1,d3 ; d0=bltcon0/1
.1 move #(42*64+4),d2 ; bltsize
move #(42*8),d1 ; one plane
moveq #-1,d0
CALLGRAF WaitBlit
&nbsnbsp; move.l d0,BLTAFWM(a5) ; mask=$FFFFFFFF
moveq #(SCRWIDTH-8),d0
move.l d0,BLTAMOD(a5) ; amod=0/dmod=34
swap d0
move.l d0,BLTCMOD(a5) ; cmod=34/bmod=0
moveq #(NUMPLANES-1),d0
.2 CALL WAITBLIT
move.l a0,BLTBPT(a5) ; image ptr
move.l a1,BLTAPT(a5) ; mask
move.l a2,BLTCPT(a5)
move.l a2,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5) ; bltcon0/1 set
move d2,BLTSIZE(a5) ; blit!
lea PLANE_SIZE(a2),a2
add d1,a0
dbf d0,.2
rts
; ---- BLIT 32WIDE BLOCK TO SCREEN ----
; X (D0) Y (D1) HEIGHT (D2)
; Mask (A0)
blit_block movem.l d0-d3/a0-a1,-(sp)
move.l _dscreen(pc),a1
mulu #(SCRWIDTH),d1
lea (a1,d1.l),a1 ; bpl
add d0,d0
add d0,a1
move.l d2,d1
lsl #6,d2
addq #2,d2 ; size of blit
lsl #2,d1 ; size of plane
moveq #(SCRWIDTH-4),d0
move.l #$09F0,d3
swap d3
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5) ; Amod=XX/Dmod=0
moveq #-1,d0
move.l d0,BLTAFWM(a5) ; mask=$FFFFFFFF
moveq #(NUMPLANES-1),d0
.2 CALL WaitBlit
move.l a0,BLTAPT(a5) ; data
move.l a1,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5)
move d2,BLTSIZE(a5) ; start blitter
lea PLANE_SIZE(a1),a1
add d1,a0
dbf d0,.2
movem.l (sp)+,d0-d3/a0-a1
rts
; ---- BLIT 32WIDE MASK TO BACKMASK ----
; X (D0) Y (D1) HEIGHT (D2)
; Graph (A0)
blit_mask lea _backmask,a1
mulu #40,d1
lea (a1,d1.l),a1 ; bpl
add d0,d0
add d0,a1
move.l d2,d1
moveq #6,d3
lsl d3,d2
addq #2,d2 ; size of blit
moveq #2,d3
lsl d3,d1 ; size of plane
moveq #(40-4),d0
move.l #$09F0,d3
swap d3
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5) ; Amod=XX/Dmod=0
moveq #-1,d0
move.l d0,BLTAFWM(a5) ; mask=$FFFFFFFF
move.l a0,BLTAPT(a5) ; data
move.l a1,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5)
move d2,BLTSIZE(a5) ; start blitter
CALL WaitBlit
rts
;---- SAVE BACKGROUND BENEATH BOB ----
; x (d0) y (d1) buffer (a0)
save_back move.l #$09F0,d3
swap d3
move.l _dscreen(pc),a1
mulu #(SCRWIDTH),d1
lea (a1,d1.l),a1 ; bpl
moveq #4,d1
lsr d1,d0
add d0,d0
lea (a1,d0),a1 ; bpl
move bo_height(a3),d2
moveq #6,d1
lsl d1,d2
addq #3,d2 ; blitsize
move bo_height(a3),d1
mulu #(BOBWIDTH),d1 ; one plane
moveq #(SCRWIDTH-BOBWIDTH),d0
swap d0
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5)
moveq #(NUMPLANES-1),d0
.2 CALL WaitBlit
move.l a1,BLTAPT(a5) ; mask
move.l a0,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5)
move d2,BLTSIZE(a5) ; start blitter
lea PLANE_SIZE(a1),a1
add d1,a0
dbf d0,.2
rts
;---- RESTORE BACKGROUND OVER BOB ----
; x (d0) y (d1) buffer (a0)
restore_back move.l #$09F0,d3
swap d3
move.l _dscreen(pc),a1
mulu #(SCRWIDTH),d1
lea (a1,d1.l),a1 ; bpl
moveq #4,d1
lsr d1,d0
add d0,d0
lea (a1,d0),a1 ; bpl
move bo_height(a3),d2
moveq #6,d1
lsl d1,d2
addq #3,d2 ; bltsize
move bo_height(a3),d1
mulu #(BOBWIDTH),d1  nbsp; ; one plane
moveq #(SCRWIDTH-BOBWIDTH),d0
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5) ; A/D = 34/0
moveq #(NUMPLANES-1),d0
.2 CALL WaitBlit
move.l a0,BLTAPT(a5) ; mask
move.l a1,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5) ; 0/1 set
move d2,BLTSIZE(a5) ; start blitter
lea PLANE_SIZE(a1),a1
add d1,a0
dbf d0,.2
rts
;---- SAVE BACKGROUND BENEATH EXPANDED BOB ----
; x (d0) y (d1) buffer (a0)
save_expback move.l #$09F0,d3
swap d3
move.l _dscreen(pc),a1
mulu #(SCRWIDTH),d1
lea (a1,d1.l),a1 ; bpl
moveq #4,d1
lsr d1,d0
add d0,d0
lea (a1,d0),a1 ; bpl
move #(42*64+4),d2 ; bltsize
move #(42*8),d1 ; oneplane
moveq #(SCRWIDTH-8),d0
swap d0
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5)
moveq #(NUMPLANES-1),d0
.2 CALL WaitBlit
move.l a1,BLTAPT(a5) ; mask
move.l a0,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5)
move d2,BLTSIZE(a5) ; start blitter
lea PLANE_SIZE(a1),a1
add d1,a0
dbf d0,.2
rts
;---- RESTORE BACKGROUND OVER EXPANDED BOB ----
; x (d0) y (d1) buffer (a0)
restore_expback move.l #$09F0,d3
swap d3
move.l _dscreen(pc),a1
mulu #(SCRWIDTH),d1
lea (a1,d1.l),a1 ; bpl
moveq #4,d1
lsr d1,d0
add d0,d0
lea (a1,d0),a1 ; bpl
move #(42*64+4),d2 ; bltsize
move #(42*8),d1 ; oneplane
moveq #(SCRWIDTH-8),d0
CALLGRAF WaitBlit
move.l d0,BLTAMOD(a5) ; A/D = 34/0
moveq #(NUMPLANES-1),d0
.2 CALL WaitBlit
move.l a0,BLTAPT(a5) ; mask
move.l a1,BLTDPT(a5) ; C/D=dest
move.l d3,BLTCON0(a5) ; 0/1 set
move d2,BLTSIZE(a5) ; start blitter
lea PLANE_SIZE(a1),a1
add d1,a0
dbf d0,.2
rts
; ---- CREATE NEW MASK FOR BOB ("BEHIND BACKGROUNDS") ----
create_mask move.l p_bob(a3),a0
tst.b bo_inactive(a0)
beq.w .isactive
.isactive cmp #82,bo_y(a0)
beq.b .makemask
clr.b bo_maskmade(a0)
rts
.makemask st.b bo_maskmade(a0)
moveq #0,d2
move bo_image(a0),d2
lea _boblookuptable(pc),a1
moveq #2,d3
lsl d3,d2
move.l (a1,d2.l),a1 ; bob image
add.l bo_maskoff(a0),a1 ; mask
; mulu #(BOBWIDTH*BOBHEIGHT*NUMPLANES)+132,d2
; add #(BOBSIZE),d2
; lea (a1,d2.l),a1 ; A1 = image mask
lea _backmask,a2 ; A2 = backmask
move.l #$0D00+(A&B),d3
moveq #0,d0
move bo_x(a0),d0
moveq #32,d1
sub d1,d0
move d0,d1
lsr #4,d0
add d0,d0
lea (a2,d0),a2 ; bpl
moveq #15,d0
and d0,d1
moveq #4,d0
ror d0,d1
or d1,d3
swap d3
move #(BOBHEIGHT*64+(BOBWIDTH/2)),d2 ; bltsize
moveq #-1,d0
moveq #0,d1
CALLGRAF WaitBlit
move.l d0,BLTAFWM(a5) ; mask=$FFFFFFFF
move d1,BLTAMOD(a5)
move d1,BLTDMOD(a5)
moveq #(40-BOBWIDTH),d0
move d0,BLTBMOD(a5)
move.l a1,BLTAPT(a5) ; image mask
move.l a2,BLTBPT(a5) ; background mask
move.l bo_newmask(a0),a0
move.l a0,BLTDPT(a5)
move.l d3,BLTCON0(a5)
move d2,BLTSIZE(a5) ; blit!
CALL WaitBlit
rts
;---- WAIT FOR BEAM SYNC ----
wait_sync btst #0,5(a5)
bne.b wait_sync
.1 btst #0,5(a5)
beq.b .1
rts
;---- SHOW SCREEN -----
show_screen lea _copbitplaneptrs+2,a0
move.l _screenswap1(pc),a1
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
addq #4,a0
move (a1)+,(a0)
rts
;---- SWAP SCREENS ----
swap_screens not.b _swapflag
move.l _screen(pc),d7
move.l _dscreen(pc),_screen
move.l d7,_dscreen
move.l _screenswap1(pc),d7
move.l _screenswap2(pc),_screenswap1
move.l d7,_screenswap2
rts
;---- INITIALISE SCREEN SWAPPING ----
init_screenswap
move.l _screen(pc),d0
lea _screen1swap(pc),a0
move.l a0,_screenswap1
moveq #(NUMPLANES-1),d1
.1 swap d0
move d0,(a0)+
swap d0
move d0,(a0)+
add.l #(PLANE_SIZE),d0
dbf d1,.1
move.l _dscreen(pc),d0
lea _screen2swap(pc),a0
move.l a0,_screenswap2
moveq #(NUMPLANES-1),d1
.2 swap d0
move d0,(a0)+
swap d0
move d0,(a0)+
add.l #(PLANE_SIZE),d0
dbf d1,.2
rts
;---- READ SELECTED CONTROL DEVICE FOR PLAYER ----
; playerstructure (a3)
read_device move.l p_bob(a3),a0
tst.b bo_inactive(a0)
bne.b .no
move.l p_device(a3),d0
tst.b p_dead(a3)
beq.b .notdead
tst.b _bonusdraw
bne.b .notdead
moveq #(DEV_CPU),d0
.notdead jmp _devicetable(pc,d0.l)
.no rts
CNOP 0,4
_devicetable jmp read_joystick0(pc)
jmp read_joystick1(pc)
jmp computer_control(pc)
jmp read_none(pc)
read_none rts
; ---- DEVICE: JOYSTICK 1 ----
read_joystick1 tst.b _bonusdraw
bne.b .onlybutton
move JOY1DAT(a5),d0
and #$0303,d0
bclr #8,d0
beq.b .1
or.b #%00000100,d0
.1 bclr #9,d0
beq.b .2
or.b #%00001000,d0
.2 move.b _joyreference(pc,d0.l),p_joystick(a3)
btst.b #7,$BFE0FF
seq p_fire(a3)
rts
.onlybutton btst.b #7,$BFE0FF
seq p_fire(a3)
clr.b p_joystick(a3)
rts
; ---- DEVICE: JOYSTICK 0 ----
read_joystick0 tst.b _bonusdraw
bne.b .onlybutt
move JOY0DAT(a5),d0
and #$0303,d0
bclr #8,d0
beq.b .1
or.b #%00000100,d0
.1 bclr #9,d0
beq.b .2
or.b #%00001000,d0
.2 move.b _joyreference(pc,d0.l),p_joystick(a3)
btst #6,$BFE001
seq p_fire(a3)
rts
.onlybutt btst #6,$BFE001
seq p_fire(a3)
clr.b p_joystick(a3)
rts
CNOP 0,4
_joyreference dc.b 0,D_DOWN,D_DOWNRIGHT,D_RIGHT,D_UP
dc.b 0,0,D_UPRIGHT,D_UPLEFT,0,0,0,D_LEFT,D_DOWNLEFT,0,0
; ---- WALKSEQUENCE CODE FOR BANK ROBBERS ----
; -> sequence info data (D0)
walkseqcode_bankrobbery
cmp #-1,d0
beq.w remove_outlaw
cmp #1,d0
beq.b .gotmoney
rts
.gotmoney lea _animtableoutlawmoney(pc),a0
lea p_animup(a3),a1
moveq #7,d0
.2 move.l (a0)+,(a1)+
dbf d0,.2
st.b p_noshoot(a3)
rts
; ---- WALKSEQUENCE CODE FOR KIDNAPPERS ----
; -> sequence info data (D0)
walkseqcode_kidnapping
cmp #-1,d0
beq.w remove_outlaw
cmp #1,d0
beq.b .hookertaken
rts
.hookertaken move.l a3,a0
bsr.w add_hooker
tst.l d0
bmi.b .nono
st.b p_noshoot(a0)
move.l a3,p_outlawhooker(a0)
move.l a0,p_hookeroutlaw(a3)
move.l p_bob(a0),a0
move bo_x(a0),bo_x(a2)
move bo_y(a0),bo_y(a2)
.nono rts
; ---- WALKSEQUENCE CODE FOR DYNAMITE MAN ----
; -> sequence info data (D0)
walkseqcode_dynamite
cmp #-1,d0
beq.w remove_outlaw
cmp #1,d0
beq.b put_dynamite
rts
put_dynamite move.l p_bob(a3),a1
clr.b p_nevershoot(a3)
lea _animdynamite(pc),a0
lea _dynamite(pc),a0
lea _animdynamite(pc),a2
move (a2)+,d0
move.b d0,p_animspeed(a0) ; first byte is animspeed
move.b #1,p_animspdcount(a0)
move.l a2,p_animation(a0)
clr.b p_animpos(a0)
st.b _dynaset
clr.b _dynamiteinrange
move.l p_bob(a0),a0
move bo_x(a1),d0
sub #16,d0
move d0,bo_x(a0)
move bo_y(a1),d0
sub #16,d0
move d0,bo_y(a0)
clr.b bo_inactive(a0)
st.b bo_firstflag(a0)
move #0,bo_image(a0)
clr.b _dynamiteactive
subq.b #1,_numoutlaws
bra.w type_bankrobber
; ---- WALK SEQUENCE CODE FOR KILLERS ----
walkseqcode_killer
cmp #1,d0
beq.b .newposition
rts
.newposition clr p_walkseqpos(a3)
lea p_walksequence(a3),a0
move.l #272,d0
bsr.w random
add #32,d0
move d0,(a0) ; new dest. x
moveq #83,d0
bsr.w random
add #88,d0
move d0,2(a0) ; new dest. y
rts
WALKCOUNT = 16
; ---- DEVICE: COMPUTER CONTROL ----
computer_control
tst.b p_rigorgot(a3)
bne.w follow_rigor
.wa cmp.b #(OT_HORSE),p_type(a3)
beq.w control_horse
cmp.b #(OT_HORSEMAN),p_type(a3)
beq.w control_horseman
cmp.b #(OT_DYNAMAN),p_type(a3)
beq.w control_dynaman
.ok cmp.b #(OT_HOOKER),p_type(a3)
beq.w control_hooker
must_walk tst.b p_dead(a3)
bne.b .nowalk
tst.b p_nomove(a3)
beq.b .walk
.nowalk tst.b _bonusdraw
bne.b .noclr
clr.b p_joystick(a3)
clr.b p_fire(a3)
.noclr rts
.walk move.l p_bob(a3),a0
movem bo_x(a0),d0/d1
cmp.b #5,_wave
beq.b .ddd
tst.b p_noshoot(a3)
bne.b .ddd
cmp #82,d1
seq p_noshoot(a3)
.ddd lea p_walksequence(a3),a1
add p_walkseqpos(a3),a1
movem (a1)+,d2/d3
lsr #2,d2
add d2,d2
add d2,d2
lsr #2,d0
add d0,d0
add d0,d0
cmp d2,d0
bne.b .1
cmp d3,d1
bne.b .1
lea p_walksequence(a3),a1
add p_walkseqpos(a3),a1
move 4(a1),d0
addq #6,p_walkseqpos(a3)
move.l p_walkseqcode(a3),a1
jmp (a1) ; walkseq checking
.1 addq #1,p_scorecount(a3)
move _scorecounter(pc),d0
cmp p_scorecount(a3),d0
bne.b .nono
move _scoresub(pc),d0
sub d0,p_score(a3)
tst p_score(a3)
bpl.b .okokok
add d0,p_score(a3) ; minus not allowed
.okokok clr p_scorecount(a3)
.nono tst.b p_noshoot(a3)
bne.b .noshoot
move _shootfrequency(pc),d0
bsr.w random
tst d0
bne.b .noshoot
st.b p_fire(a3)
rts
.noshoot clr.b p_fire(a3)
movem bo_x(a0),d0/d1
cmp d3,d1 ; y positions equal?
beq.w .leftright
cmp d2,d0 ; x positions equal?
beq.w .updown
cmp d3,d1
blo.b .downdown
cmp d2,d0
blo.b .mupright
bra.b .mupleft
.downdown cmp d2,d0
blo.w .mdownright
bra.w .mdownleft
; ---- walk up and right ----
.mupright tst.b p_walkcntx(a3)
beq.b .no
subq.b #1,p_walkcntx(a3)
bne.w .right
.no tst.b p_noup(a3)
bne.w .right
move bo_y(a0),d0 ; horizontal distance
sub p_desty(a3),d0
move d0,d1
add bo_x(a0),d1
sub p_destx(a3),d1 ; overflow
beq.w .upright ; no, will reach
cmp #8,d0 ; distance less than 8?
ble.w .right ; forced alignment
tst.b p_xalign(a3)
bne.b .align
move.b d0,p_xalign(a3)
rts
.align moveq #10,d0
bsr.w random
cmp #8,d0
ble.b .no11
move.b #(WALKCOUNT),p_walkcntx(a3)
subq.b #1,p_xalign(a3)
rts
.no11 clr.b p_walkcntx(a3)
bra.w .upright
; ---- walk up and left ----
.mupleft tst.b p_walkcntx(a3)
beq.b .no21
subq.b #1,p_walkcntx(a3)
bne.w .left
.no21 tst.b p_noup(a3)
bne.w .left
move bo_y(a0),d0 ; horizontal distance
sub p_desty(a3),d0
move d0,d1
add bo_x(a0),d1
sub p_destx(a3),d1 ; overflow
beq.w .upleft ; no, will reach
cmp #8,d0 ; distance less than 8?
ble.w .left ; forced alignment
tst.b p_xalign(a3)
bne.b .align2
move.b d0,p_xalign(a3)
rts
.align2 moveq #10,d0
bsr.w random
cmp #8,d0
ble.b .no12
move.b #(WALKCOUNT),p_walkcntx(a3)
subq.b #1,p_xalign(a3)
rts
.no12 clr.b p_walkcntx(a3)
bra.w .upleft
; ---- walk down and left ----
.mdownleft tst.b p_walkcntx(a3)
beq.b .no22
subq.b #1,p_walkcntx(a3)
bne.w .left
.no22 tst.b p_nodown(a3)
bne.w .left
move bo_y(a0),d0 ; horizontal distance
sub p_desty(a3),d0
move d0,d1
add bo_x(a0),d1
sub p_destx(a3),d1 ; overflow
beq.w .downleft ; no, will reach
cmp #192,d0 ; distance less than 8?
bge.w .left ; forced alignment
tst.b p_xalign(a3)
bne.b .align3
move.b d0,p_xalign(a3)
rts
.align3 moveq #10,d0
bsr.w random
cmp #8,d0
ble.b .no13
move.b #(WALKCOUNT),p_walkcntx(a3)
subq.b #1,p_xalign(a3)
rts
.no13 clr.b p_walkcntx(a3)
bra.w .downleft
; ---- walk down and right ----
.mdownright tst.b p_walkcntx(a3)
beq.b .no23
subq.b #1,p_walkcntx(a3)
bne.b .right
.no23 tst.b p_nodown(a3)
bne.b .right
move bo_y(a0),d0 ; horizontal distance
sub p_desty(a3),d0
move d0,d1
add bo_x(a0),d1
sub p_destx(a3),d1 ; overflow
beq.b .downright ; no, will reach
cmp #192,d0 ; distance less than 8?
bge.b .left ; forced alignment
tst.b p_xalign(a3)
bne.b .align4
move.b d0,p_xalign(a3)
rts
.align4 moveq #10,d0
bsr.w random
cmp #8,d0
ble.b .no14
move.b #(WALKCOUNT),p_walkcntx(a3)
subq.b #1,p_xalign(a3)
rts
.no14 clr.b p_walkcntx(a3)
bra.b .downright
; ---- walk left or right ----
.leftright cmp d2,d0
blo.b .right
.left move.b #(D_LEFT),p_joystick(a3)
rts
.right move.b #(D_RIGHT),p_joystick(a3)
rts
; ---- walk up or down ----
.updown cmp d3,d1
blo.b .down
.up move.b #(D_UP),p_joystick(a3)
rts
.down move.b #(D_DOWN),p_joystick(a3)
rts
.upleft move.b #(D_UPLEFT),p_joystick(a3)
rts
.upright move.b #(D_UPRIGHT),p_joystick(a3)
rts
.downleft move.b #(D_DOWNLEFT),p_joystick(a3)
rts
.downright move.b #(D_DOWNRIGHT),p_joystick(a3)
rts
; ---- UPDATE HOOKER ----
control_hooker tst.b p_runhome(a3)
bne.w must_walk
move.l p_hookeroutlaw(a3),d0
beq.b .runhome
move.l d0,a0
tst.b p_dead(a0)
bne.b .runhome
move.b p_direction(a0),p_direction(a3)
move.l p_bob(a3),a3
move.l p_bob(a0),a1
move bo_x(a1),bo_x(a3)
move bo_y(a1),bo_y(a3)
rts
.runhome st.b p_runhome(a3)
rts
; ---- FOLLOW RIGOR (DRAGGING) ----
follow_rigor lea _rigormortis(pc),a2
move.l p_bob(a2),a0
move.l p_bob(a3),a1
move bo_x(a0),d2
move bo_y(a0),d3
moveq #0,d0
move.b p_direction(a2),d0
lsl #2,d0
add _dragoffsets(pc,d0.w),d2
add _dragoffsets+2(pc,d0.w),d3
move d2,bo_x(a1)
move d3,bo_y(a1)
rts
_dragoffsets dc.l 0
dc -2,2 ; up
dc 2,4 ; upleft
dc -4,4 ; upright
dc.l 0 ; down
dc.l 0 ; downl
dc.l 0 ; downr
dc 10,0 ; left
dc -10,0 ; right
; ---- CONTROL DYNAMITE MANIAC ----
control_dynaman tst.b _dynamiteactive
bne.b .ok
rts
.ok cmp #$FFFF,_hero1dead ; both heros dead?
beq.w gotohell
.ok2 lea _player1(pc),a0
tst.b _dynamitepl2
beq.b .nono
lea _player2(pc),a0
.nono move.l _dynamiteman(pc),a3
tst.b p_dead(a3)
bne.b .ok23
lea p_walksequence(a3),a2
move.l p_bob(a0),a0
movem bo_x(a0),d0/d1
move d0,(a2)
move d1,2(a2)
move.l p_bob(a3),a2
movem bo_x(a2),d2/d3
sub #24,d0
cmp d2,d0
bhi.b .3
add #24+24,d0
cmp d2,d0
blo.b .3
sub #20,d1
cmp d3,d1
bhi.b .3
add #20+22,d1
cmp d3,d1
blo.b .3
bsr.w put_dynamite
.3 lea _player1(pc),a0
tst.b _hero1dead
bne.b .pl2
tst.b _dynamitepl2
beq.b .no22
.pl2 lea _player2(pc),a0
.no22 move.l p_bob(a0),a0
tst.b bo_maskmade(a0)
bne.b .rt
.ok23 bra.w must_walk
.rt clr.b p_joystick(a3)
rts
gotohell clr.b _dynamiteactive
clr.b p_type(a3)
subq.b #1,_numoutlaws
bra.w type_bankrobber
; ---- CONTROL HORSE ----
control_horse tst.b _horseactive
bne.b .ok22
rts
.ok22 move.l p_bob(a3),a0
tst.b bo_inactive(a0)
beq.b .ok
rts
.ok subq.b #1,_horsefxcount
bne.b .nonewfx
move #$0503,d0
moveq #2,d2
bsr.w play_sfx
move.b #20,_horsefxcount
.nonewfx move _horseshootfreq(pc),d0
bsr.w random
move.l _horseman(pc),a0
tst d0
seq.b p_fire(a0) ; horseman shoots
.nono move.l p_bob(a3),a0
cmp.b #(DI_RIGHT),p_direction(a3)
beq.b .isright
tst bo_x(a0)
ble.b .removehorse
subq #2,bo_x(a0)
rts
.isright cmp #320,bo_x(a0)
beq.b .removehorse
addq #2,bo_x(a0)
rts
.removehorse move.b #2,bo_inactive(a0)
clr.b _horseactive
move.l _horseman(pc),a3
tst.b p_dead(a3)
bne.b .nomove
bra.w remove_outlaw
.nomove rts
_horsefxcount dc.b 1,0
; ---- CONTROL HORSEMAN ----
control_horseman
tst.b _horseactive
bne.b .ok
rts
.ok move.l _horseman(pc),a3
tst.b p_dead(a3)
bmi.b .nono
move.l p_bob(a3),a1
lea _horse(pc),a0
move.l p_bob(a0),a0
movem bo_x(a0),d0/d1
addq #8,d0
move d0,bo_x(a1)
addq #3,d1
move d1,bo_y(a1#41;
.nono rts
; -----------------------------------------
;
; PLAYER STRUCTURE
;
; -----------------------------------------
RSRESET
p_bob RS.L 1 ; APTR general bob structure
p_device RS.L 1 ; selected device for player
p_animation RS.L 1 ; APTR animation sequence
p_animup RS.L 1
p_animupleft RS.L 1
p_animupright RS.L 1
p_animdown RS.L 1
p_animdownleft RS.L 1
p_animdownright RS.L 1
p_animleft RS.L 1
p_animright RS.L 1
p_animdie RS.L 1
p_stopimages RS.L 1 ; images used when idle
p_shootimages RS.L 1 ; images used when shooting
p_dragimages RS.L 1 ; images used when dragged
p_walkseqcode RS.L 1 ; APTR code for checking in sequences
p_hookeroutlaw RS.L 1 ; APTR which outlaw took the hooker
p_outlawhooker RS.L 1 ; APTR which hooker took the outlaw
p_rigorbody RS.L 1 ; APTR which body has Rig. Mortis
p_plscore RS 1 ; score for player
p_lifescore RS 1 ; score to get extra life
p_zone RS 1 ; zone for actor
p_building RS 1 ; which building actor's in
p_xlimit1 RS 1 ; horiz. walk limitation x1
p_xlimit2 RS 1
p_destx RS 1 ; destination x
p_desty RS 1 ; destination y
p_walkseqpos RS 1
p_score RS 1 ; current score for this outlaw
p_scorecount RS 1
p_lives RS 1 ; number of lives yet
p_addwalkx RS 1
p_addwalky RS 1
p_walkdirx RS.B 1 ; * must be even
p_walkdiry RS.B 1
p_joystick RS.B 1 ; joystick input
p_direction RS.B 1 ; current direction
p_lastdirection RS.B 1 ; previous direction
p_fire RS.B 1 ; firebutton status
p_walkspeed RS.B 1 ; speed of walking
p_walkspdcount RS.B 1 ; * auto
p_animpos RS.B 1 ; * auto
p_animspeed RS.B 1 ; * auto
p_animspdcount RS.B 1 ; * auto
p_nomove RS.B 1 ; set if no move
p_noup RS.B 1 ; set if can't move up
p_nodown RS.B 1
p_noleft RS.B 1
p_noright RS.B 1
p_shootcounter RS.B 1
p_shootdelay RS.B 1
p_shooting RS.B 1 ; set if shooting
p_walkcntx RS.B 1
p_walkcnty RS.B 1
p_xalign RS.B 1
p_dead RS.B 1 ; set if dead
p_noshoot RS.B 1 ; set if (outlaw) can't shoot
p_cantdie RS.B 1 ; set if can't die
p_rigorgot RS.B 1 ; set if Rig. got this body
p_type RS.B 1 ; type of bob
p_runhome RS.B 1 ; set if hooker running home
p_animoff RS.B 1 ; set if autoanimation off
p_nevershoot RS.B 1 ; set if neverever shooting
p_notwalking RS.B 2 ; drawman stuff
p_walksequence RS.B 36
p_sizeof RS.B 0
_player1 blk.b (P_SIZEOF),0
_player2 blk.b (P_SIZEOF),0
_outlaws blk.b (P_SIZEOF*MAXOUTLAWS),0
_hookers blk.b (P_SIZEOF*MAXHOOKERS),0
_rigormortis blk.b (P_SIZEOF),0
_dynamite blk.b (P_SIZEOF),0
_horse blk.b (P_SIZEOF),0
; -----------------------------------------
;
; INITIALISATIONS FOR GAME
;
; -----------------------------------------
init_allstructs bsr.w init_sheriffstructures
bsr.w init_outlawstructures
bsr.w init_hookerstructures
bsr.w init_rigorstructure
bsr.w init_dynastructure
bsr.w init_horsestructure
; bsr.w init_drawlist
rts
; ---- INITIALISE BOBSTRUCTURES ----
init_bobstructures
moveq #(MAXBOBS-1),d0
lea _player1(pc),a2
move.l _bobmemory(pc),a1
lea _bobstructs(pc),a0
.initloop move.l a1,bo_buffer1(a0)
add.l #(BOBSIZE),a1
move.l a1,bo_buffer2(a0)
add.l #(BOBSIZE),a1
move.l a1,bo_newmask(a0)
add.l #(BOBPLANE),a1
move.l #(BOBSIZE),bo_maskoff(a0)
clr.l bo_x(a0) ; clear x/y
clr.l bo_oldx1(a0)
clr.l bo_oldx2(a0)
st.b bo_inactive(a0)
st.b bo_firstflag(a0)
clr.b bo_maskmade(a0)
clr.b bo_expanded(a0)
move #(BOBHEIGHT),bo_height(a0)
move.l a0,p_bob(a2)
lea BO_SIZEOF(a0),a0
lea P_SIZEOF(a2),a2
dbf d0,.initloop
rts
; ---- SET ALL BOBS INACTIVE ----
bobs_inactive moveq #(MAXBOBS-3),d0
lea _outlaws(pc),a2
.initloop st.b bo_inactive(a0)
st.b bo_firstflag(a0)
lea BO_SIZEOF(a0),a0
dbf d0,.initloop
rts
; ---- SET ALL BULLETS INACTIVE ----
bullets_inactive
moveq #(MAXBULLETS-1),d0
lea _bullets(pc),a0
.initloop clr.b b_active(a0)
add #(B_SIZEOF),a0
dbf d0,.initloop
rts
; ---- INITIALISE SHERIFF STRUCTURES ----
init_sheriffstructures
lea _player1(pc),a3
move.l p_bob(a3),a0
tst.b _hero1dead
sne bo_inactive(a0)
st.b bo_firstflag(a0)
move.l #(DEV_JOY1),p_device(a3)
move.b #(OT_SHERIFF1),p_type(a3)
bsr.b .setsheriff
lea _player2(pc),a3
move.l p_bob(a3),a0
tst.b _hero2dead
sne bo_inactive(a0)
st.b bo_firstflag(a0)
move.l #(DEV_JOY0),p_device(a3)
move.b #(OT_SHERIFF2),p_type(a3)
.setsheriff move.l #_sheriffstop,p_stopimages(a3)
move.l #_sheriffshoot,p_shootimages(a3)
move.l #_sheriffdie,p_animdie(a3)
move.l #_sheriffdrag,p_dragimages(a3)
clr.l p_walkseqcode(a3)
clr p_zone(a3)
clr p_building(a3)
move #2,p_addwalkx(a3)
move #1,p_addwalky(a3)
move.b #2,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
move.b #(DI_DOWN),p_direction(a3)
clr.b p_lastdirection(a3)
clr.b p_joystick(a3)
clr.b p_fire(a3)
clr.b p_nomove(a3)
clr.b p_noup(a3)
clr.b p_nodown(a3)
clr.b p_noleft(a3)
clr.b p_noright(a3)
clr.b p_noshoot(a3)
clr.b p_dead(a3)
clr.b p_animpos(a3)
clr.b p_shooting(a3)
clr.b p_cantdie(a3)
clr.b p_rigorgot(a3)
clr.b p_animoff(a3)
clr.b p_nevershoot(a3)
move.b #1,p_shootcounter(a3)
move.b #22,p_shootdelay(a3)
lea _animtablesheriff(pc),a2
lea p_animup(a3),a1
moveq #7,d0
.1 move.l (a2)+,(a1)+
dbf d0,.1
.out rts
; ---- INITIALISE OUTLAW STRUCTURES ----
init_outlawstructures
clr.b _numoutlaws
lea _outlaws(pc),a3
moveq #(MAXOUTLAWS-1),d0
.outlawloop move.l #(DEV_CPU),p_device(a3)
move.l #_outlawstop,p_stopimages(a3)
move.l #_outlawshoot,p_shootimages(a3)
move.l #_outlawdrag,p_dragimages(a3)
move #1,p_addwalkx(a3)
move #1,p_addwalky(a3)
move.b #2,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
move.b #(DI_RIGHT),p_direction(a3)
st.b p_lastdirection(a3)
move.b #10,p_shootdelay(a3)
clr.b p_dead(a3)
clr.b p_nevershoot(a3)
clr p_score(a3)
clr.b p_animpos(a3)
clr.b p_cantdie(a3)
clr.b p_animoff(a3)
clr.b p_shooting(a3)
clr.b p_noshoot(a3)
lea _animtableoutlaw(pc),a2
lea p_animup(a3),a1
moveq #7,d1
.2 move.l (a2)+,(a1)+
dbf d1,.2
lea _outlawdie(pc),a2
move.l a2,p_animdie(a3)
lea P_SIZEOF(a3),a3
dbf d0,.outlawloop
rts
; ---- INITIALISE HOOKER STRUCTURES ----
init_hookerstructures
lea _hookers(pc),a3
moveq #(MAXHOOKERS-1),d0
.outlawloop move.l #(DEV_CPU),p_device(a3)
lea _hookersequence(pc),a0
lea p_walksequence(a3),a1
moveq #1,d1
.1 move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
dbf d1,.1
move.l (a0)+,(a1)+
lea walkseqcode_hooker(pc),a0
move.l a0,p_walkseqcode(a3)
move.l #_hookerstop,p_stopimages(a3)
move.b #(OT_HOOKER),p_type(a3)
move #1,p_addwalkx(a3)
move #1,p_addwalky(a3)
st.b p_noshoot(a3)
st.b p_cantdie(a3)
clr.b p_dead(a3)
clr.l p_hookeroutlaw(a3)
move.b #2,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
move.b #(DI_RIGHT),p_direction(a3)
move.b #(DI_RIGHT),p_lastdirection(a3)
move.l p_bob(a3),a0
move #80,bo_image(a0)
st.b bo_inactive(a0)
lea _animtablehooker(pc),a2
lea p_animup(a3),a1
moveq #7,d1
.2 move.l (a2)+,(a1)+
dbf d1,.2
lea P_SIZEOF(a3),a3
dbf d0,.outlawloop
rts
_hookersequence dc&nnbsp; 19*8-4,84,0 ; sal. entrance
dc 19*8-4,82,0 ; inside
dc 16*8-4,82,-1 ; inside saloon left
dc 0,0,0 ; inside
dc 0,0,0 ; sal. entrance
dc 0,0,0 ; and run away
; ---- WALK SEQUENCE CODE FOR HOOKERS ----
walkseqcode_hooker
tst d0
bmi.b remove_hooker
rts
remove_hooker clr p_walkseqpos(a3)
clr.b p_runhome(a3)
move.l p_bob(a3),a0
move.b #2,bo_inactive(a0)
rts
; ---- INITIALISE RIGOR MORTIS STRUCTURE ----
init_rigorstructure
lea _rigormortis(pc),a3
.outlawloop move.l #(DEV_CPU),p_device(a3)
move.l #_rigorstop,p_stopimages(a3)
st.b p_noshoot(a3)
move.b #(OT_RIGOR),p_type(a3)
move #2,p_addwalkx(a3)
move #1,p_addwalky(a3)
st.b p_cantdie(a3)
move.b #1,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
move.b #(DI_RIGHT),p_direction(a3)
st.b p_lastdirection(a3)
lea _animtablerigor(pc),a2
lea p_animup(a3),a1
moveq #7,d1
.2 move.l (a2)+,(a1)+
dbf d1,.2
rts
; ---- INIT DYNAMITE STRUCTURE ----
init_dynastructure
lea _dynamite(pc),a3
move.l #(DEV_NONE),p_device(a3)
st.b p_nomove(a3)
st.b p_noshoot(a3)
move.b #(OT_DYNA),p_type(a3)
st.b p_cantdie(a3)
move.b #1,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
; move.b #(DI_UP),p_direction(a3)
; st.b p_lastdirection(a3)
; lea _animdynamite(pc),a0
; lea p_animup(a3),a1
; move.l a0,(a1)
move.l p_bob(a3),a0
lea _dynabuff1,a1
move.l a1,bo_buffer1(a0)
lea _dynabuff2,a1
move.l a1,bo_buffer2(a0)
st.b bo_expanded(a0)
move #42,bo_height(a0)
st.b p_animoff(a3)
rts
; ---- INITIALISE HORSESTRUCTURE ----
init_horsestructure
lea _horse(pc),a3
move.l #(DEV_CPU),p_device(a3)
st.b p_nomove(a3)
st.b p_noshoot(a3)
st.b p_nevershoot(a3)
move.b #(OT_HORSE),p_type(a3)
st.b p_cantdie(a3)
move.b #1,p_walkspeed(a3)
move.b #1,p_walkspdcount(a3)
move.b #1,p_animspdcount(a3)
clr.b p_direction(a3)
clr.b p_lastdirection(a3)
move.l p_bob(a3),a0
lea _horsebuff1,a1
move.l a1,bo_buffer1(a0)
lea _horsebuff2,a1
move.l a1,bo_buffer2(a0)
st.b bo_expanded(a0)
move #42,bo_height(a0)
st.b p_animoff(a3)
rts
CNOP 0,4
_drawlist blk.l (MAXBOBS+1),0
; ---- SORT DRAWLIST BY Y POSITION ----
sort_drawlist lea _bobstructs(pc),a0
lea _drawlist(pc),a2
move.l a2,a1
moveq #(MAXBOBS-1),d0
.clr clr.l (a1)+
dbf d0,.clr
moveq #(MAXBOBS-1),d4
.sort move BO_Y(a0),d0 ; ypos
add BO_HEIGHT(a0),d0 ; add height
move.l a2,a1 ; drawlist -> a1
moveq #0,d1
.1 move.l (a1)+,d2 ; get bobstruct
beq.b .insert
move.l d2,a4
move BO_Y(a4),d2 ; ypos in list
add BO_HEIGHT(a4),d2
cmp d0,d2
ble.b .insert
addq.b #1,d1
cmp.b #(MAXBOBS),d1
bne.b .1
.insert moveq #(MAXBOBS-2),d2
move.l a2,a1 ; drawlist -> a1
.llop move d2,d3
moveq #2,d5
lsl d5,d3
move.l (a1,d3.w),4(a1,d3.w)
cmp.b d2,d1
beq.b .fin2
dbf d2,.llop
.fin2 moveq #2,d5
lsl d5,d1
move.l a0,(a1,d1.w) ; set bobstruct
add #(BO_SIZEOF),a0
dbf d4,.sort
rts
;--------------------------------------
; Game Engine © 1997 Seasons.
;
; DOUBLE BUFFER SUPPORT: BOBS
;--------------------------------------
; ---- DRAW ACTIVE BOBS TO SCREEN ----
draw_bobs lea _drawlist+(MAXBOBS*4)(pc),a4
clr.b _numbobs
moveq #(MAXBOBS-1),d4
.draw move.l -(a4),a3
tst.b bo_inactive(a3)
bne.b .skipdraw
addq.b #1,_numbobs
movem bo_x(a3),d0/d1
move bo_image(a3),d2
tst.b bo_expanded(a3)
beq.b .no
bsr.w blit_expbob
dbf d4,.draw
rts
.no bsr.w blit_bob
.skipdraw dbf d4,.draw
rts
; ---- SAVE BACKGROUNDS -----
save_backgrounds
lea _bobstructs(pc),a3
moveq #(MAXBOBS-1),d4
tst.b _swapflag
bne.b .s2
.s1 tst.b bo_inactive(a3)
bne.b .nono
move.l bo_x(a3),bo_oldx1(a3)
movem bo_x(a3),d0/d1
move.l bo_buffer1(a3),a0
tst.b bo_expanded(a3)
beq.b .no
bsr.w save_expback
bra.b .nono
.no bsr.w save_back
.nono lea bo_sizeof(a3),a3
dbf d4,.s1
rts
.s2 tst.b bo_inactive(a3)
bne.b .nono2
move.l bo_x(a3),bo_oldx2(a3)
movem bo_x(a3),d0/d1
move.l bo_buffer2(a3),a0
tst.b bo_expanded(a3)
beq.b .no222
bsr.w save_expback
bra.b .nono2
.no222 bsr.w save_back
.nono2 lea bo_sizeof(a3),a3
dbf d4,.s2
rts
; ---- RESTORE BACKGROUNDS -----
restore_backgrounds
lea _bobstructs(pc),a3
moveq #(MAXBOBS-1),d4
tst.b _swapflag
bne.b .s2
.s1 tst.b bo_firstflag(a3)
bne.b .sk
tst.b bo_inactive(a3)
bmi.b .sk
movem bo_oldx1(a3),d0/d1
move.l bo_buffer1(a3),a0
tst.b bo_expanded(a3)
beq.b .nn
bsr.w restore_expback
bra.b .no
.nn bsr.w restore_back
.no cmp.b #2,bo_inactive(a3)
bne.b .skk
subq.b #1,bo_inactive(a3)
bra.b .sk
.skk cmp.b #1,bo_inactive(a3)
bne.b .sk
st.b bo_inactive(a3)
.sk clr.b bo_firstflag(a3)
lea bo_sizeof(a3),a3
dbf d4,.s1
rts
.s2 tst.b bo_firstflag(a3)
bne.b .sk2
tst.b bo_inactive(a3)
bmi.b .sk2
movem bo_oldx2(a3),d0/d1
move.l bo_buffer2(a3),a0
tst.b bo_expanded(a3)
beq.b .nonono
bsr.w restore_expback
bra.b .no2
.nonono bsr.w restore_back
.no2 cmp.b #2,bo_inactive(a3)
bne.b .skk2
subq.b #1,bo_inactive(a3)
bra.b .sk2
.skk2 cmp.b #1,bo_inactive(a3)
bne.b .sk2
st.b bo_inactive(a3)
.sk2 clr.b bo_firstflag(a3)
lea bo_sizeof(a3),a3
dbf d4,.s2
rts
; -----------------------------------------
;
; SYSTEM/ENGINE DATA AREA
;
; -----------------------------------------
_gfxbase dc.l 0
_intbase dc.l 0
_dosbase dc.l 0
_dosname dc.b "dos.library",0
even
_screen dc.l 0
_dscreen dc.l 0
_screenswap1 dc.l _screen1swap
_screenswap2 dc.l _screen2swap
_bobmemory dc.l 0
_swapflag dc.b 0
_firstdone dc.b 0
_screen1swap blk.l (NUMPLANES),0
_screen2swap blk.l (NUMPLANES),0
; ---- INITIALISE EVERYTHING AND START ----
init_all IFND DEBUG
sub.l a1,a1
move.l 4.w,a6
CALL FindTask
move.l d0,a1
moveq #127,d0
CALL SetTaskPri ; set priority max
ENDIF
lea $dff000,a5 ; custom chips
clr.b d0
IFD DEBUG
st.b d0
ENDIF
lea _copperlist,a0
callvideo WAKERESOURCE ; wake video resource
move.l d0,_gfxbase
move.l d1,_intbase
lea _screen1,a0
move.l a0,_screen
lea _screen2,a0
move.l a0,_dscreen
lea _copbitplaneptrs,a0
move.l _screen,a1
move.l #(PLANE_SIZE),d0
moveq #(NUMPLANES),d1
callvideo INITBITPLANES
lea _copspriteptrs,a0
lea _blanksprite,a1
callvideo INITBLANKSPRITES ; init spriteptrs
callvideo FIXSPRITES
callvideo SYSTEMVIEWOFF
move.l 4.w,a6
&nbnbsp; lea _dosname(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,_dosbase
rts
; ---- CLEAN UP EVERYTHING AND QUIT ----
cleanup_all bsr.b free_bobs ; free bobs memory
IFND DEBUG
CALLGRAF DisOwnBlitter
ENDIF
callvideo RETURNSPRITES
callvideo SYSTEMVIEWRESTORE ; restore system
callvideo KILLRESOURCE ; kill video resource
rts
; ---- ALLOCATE MEMORY FOR BOBS ----
allocate_bobs
move.l #((BOBSIZE*2+BOBPLANE)*MAXBOBS),d0
CALLVIDEO ALLOCCHIP
move.l d0,_bobmemory
rts
free_bobs move.l _bobmemory(pc),d0
move.l #((BOBSIZE*2+BOBPLANE)*MAXBOBS),d1
CALLVIDEO FLUSHCHIP
rts
; ---- MAKE BOBLOOKUP TABLE ----
make_boblookup lea _bobdata,a0
lea _boblookuptable(pc),a1
move #(NUMBOBS-1),d0
.1 move.l a0,(a1)+
add.l #(BOBSIZEFULL),a0
dbf d0,.1
rts
;---- SET RANDOM SEED ----
set_random move.l _intbase(pc),a6
lea _cut1(pc),a0
lea _cut2(pc),a1
CALL CurrentTime ; for random number generator
move.l _cut1(pc),d0
move.l _cut2(pc),d1
;---- RANDOM NUMBER ROUTINE -----
randomseed add.l d0,d1 ;user seed in d0 (d1 too)
movem.l d0/d1,_rnd
longrnd movem.l d2-d3,-(sp)
movem.l _rnd(pc),d0/d1 ;d0=lsb's, d1=msb's of random number
andi.b #$0e,d0 ;ensure upper 59 bits are an...
ori.b #$20,d0 ;...odd binary number
move.l d0,d2
move.l d1,d3
add.l d2,d2 ;accounts for 1 of 17 left shifts
addx.l d3,d3 ;[d2/d3] = rnd*2
add.l d2,d0
addx.l d3,d1 ;[d0/d1] = rnd*3
swap d3 ;shift [d2/d3] additional 16 times
swap d2
move.w d2,d3
clr d2
add.l d2,d0 ;add to [d0/d1]
addx.l d3,d1
movem.l d0/d1,_rnd ;save for next time through
move.l d1,d0 ;most random part to d0
movem.l (sp)+,d2-d3
rts
random move.w d2,-(sp)
move.w d0,d2 ;save upper limit
beq.s .1 ;range of 0 returns 0 always
bsr.s longrnd ;get a longword random number
clr.w d0 ;use upper word (it's most random)
swap d0
divu.w d2,d0 ;divide by range...
clr.w d0 ;...and use remainder for the value
swap d0 ;result in d0.w
.1 move.w (sp)+,d2
rts
_rnd dc.l 0,0
_cut1 dc.l 0 ; int-currenttime values
_cut2 dc.l 0
; ---- PRINT TEXT TO SCREEN ----
; X (d0) Y (d1) length (d2) screen (a1)
print_text lsl #3,d1
mulu #(SCRWIDTH),d1
add d0,d1
move.l _dscreen(pc),a1
add d1,a1
bsr.b print_txt
move.l _screen(pc),a1
add d1,a1
print_txt move.l d2,d3
move.l a0,a3
.print moveq #0,d4
move.b (a3)+,d4
bmi.b .space
lsl #3,d4
lea _fontdata(pc),a2
lea (a2,d4.l),a2
move.b (a2)+,SCRWIDTH*0(a1)
move.b (a2)+,SCRWIDTH*1(a1)
move.b (a2)+,SCRWIDTH*2(a1)
move.b (a2)+,SCRWIDTH*3(a1)
move.b (a2)+,SCRWIDTH*4(a1)
move.b (a2)+,SCRWIDTH*5(a1)
move.b (a2)+,SCRWIDTH*6(a1)
move.b (a2)+,SCRWIDTH*7(a1)
.space addq #1,a1
dbf d3,.print
rts
print_text2 movem.l d0-d4/a0-a2,-(sp)
lsl #3,d1
mulu #(SCRWIDTH),d1
add d0,d1
move.l _dscreen(pc),a1
add d1,a1
.print moveq #0,d4
move.b (a0)+,d4
bmi.b .space
lsl #3,d4
lea _fontdata(pc),a2
lea (a2,d4.l),a2
move.b (a2)+,SCRWIDTH*0(a1)
move.b (a2)+,SCRWIDTH*1(a1)
move.b (a2)+,SCRWIDTH*2(a1)
move.b (a2)+,SCRWIDTH*3(a1)
move.b (a2)+,SCRWIDTH*4(a1)
move.b (a2)+,SCRWIDTH*5(a1)
move.b (a2)+,SCRWIDTH*6(a1)
move.b (a2)+,SCRWIDTH*7(a1)
.space addq #1,a1
dbf d2,.print
movem.l (sp)+,d0-d4/a0-a2
rts
_maintext dc.b "S"-55,"C"-55,"O"-55,"R"-55,"E"-55,37
dc.b 0,0,0,0,0,37,37,"H"-55,"I"-55,37
dc.b 0,0,0,0,0,37,37,"B"-55,"O"-55,"N"-55,"U"-55,"S"-55
dc.b 37
dc.b 0,0,0,0,37,37,37,37,37,37,0
_score1txt dc.b 0,0,0,0,0
_hiscoretxt dc.b 0,0,0,0,0
_bonustxt dc.b 0,0,0,0
_lifetxt dc.b 0
_score2txt dc.b 0,0,0,0,0
_maintext2 dc.b 37,"P"-55,"L"-55,1,37
dc.b 0,0,0,0,0,37,36
_lives21txt dc.b 0,37,37
dc.b "P"-55,"L"-55,2,37
dc.b 0,0,0,0,0,37,36
_lives22txt dc.b 0,37,37
dc.b "B"-55,"O"-55,"N"-55,"U"-55,"S"-55,37
dc.b 0,0,0,0,37
EVEN
; ---- PRINT MAIN LINE ----
print_mainline moveq #4,d0
moveq #0,d1
cmp.b #2,_numplayers
bne.b .1pl
lea _maintext2(pc),a0
bra.b .pr
.1pl lea _maintext(pc),a0
.pr moveq #39,d2
bra.w print_text
; ---- PRINT SCORE (1 PLAYER MODE) ----
print_score movem.l d0-d4/a0-a3,-(sp)
moveq #0,d0
lea _player1(pc),a0
move p_plscore(a0),d0
moveq #5,d1
lea _score1txt(pc),a0
bsr.w numtoasc
cmp.b #2,_numplayers
beq.b .2pl
moveq #10,d0
moveq #0,d1
moveq #4,d2
lea _score1txt(pc),a0
bsr.w print_text
movem.l (sp)+,d0-d4/a0-a3
rts
.2pl moveq #0,d0
lea _player2(pc),a0
move p_plscore(a0),d0
moveq #5,d1
lea _score2txt(pc),a0
bsr.w numtoasc
moveq #9,d0
moveq #0,d1
moveq #4,d2
lea _score1txt(pc),a0
bsr.w print_text
moveq #23,d0
moveq #0,d1
moveq #4,d2
lea _score2txt(pc),a0
bsr.w print_text
movem.l (sp)+,d0-d4/a0-a3
rts
; ---- PRINT HISCORE (1 PLAYER MODE) ----
print_hiscore cmp.b #1,_numplayers
beq.b .ik
rts
.ik move _hiscore(pc),d0
moveq #5,d1
lea _hiscoretxt(pc),a0
bsr.w numtoasc
moveq #20,d0
moveq #0,d1
moveq #4,d2
lea _hiscoretxt(pc),a0
bra.w print_text
; ---- PRINT BONUS (1 PLAYER MODE) ----
print_bonus movem.l d0-d4/a0-a3,-(sp)
moveq #0,d0
move _bonus(pc),d0
moveq #4,d1
lea _bonustxt(pc),a0
bsr.w numtoasc
cmp.b #2,_numplayers
beq.b .bonus2
moveq #33,d0
moveq #0,d1
moveq #3,d2
lea _bonustxt(pc),a0
bsr.w print_text
bra.b .ut
.bonus2 moveq #39,d0
moveq #0,d1
moveq #3,d2
lea _bonustxt(pc),a0
bsr.w print_text
.ut movem.l (sp)+,d0-d4/a0-a3
rts
; ---- PRINT LIVES (1 PLAYER MODE) ----
print_lives movem.l d0-d4/a0-a3,-(sp)
cmp.b #2,_numplayers
beq.b .2pl
moveq #0,d0
lea _player1(pc),a0
move p_lives(a0),d0
move.b d0,_lifetxt
moveq #39+4,d0
moveq #0,d1
moveq #0,d2
lea _lifetxt(pc),a0 ; number
bsr.w print_text
moveq #0,d0
lea _player1(pc),a0
move p_lives(a0),d0
cmp #4,d0
bhi.b .nono
subq #1,d0
lsl #2,d0
lea _lifedata(pc,d0.l),a0
moveq #38,d0
moveq #0,d1
moveq #3,d2
bsr.w print_text ; gfx
.nono movem.l (sp)+,d0-d4/a0-a3
rts
.2pl moveq #0,d0
lea _player1(pc),a0
move p_lives(a0),d0
move.b d0,_lifetxt
moveq #4+12,d0
moveq #0,d1
moveq #0,d2
lea _lifetxt(pc),a0 ; number
bsr.w print_text
moveq #0,d0
lea _player2(pc),a0
move p_lives(a0),d0
move.b d0,_lifetxt
moveq #4+26,d0
moveq #0,d1
moveq #0,d2
lea _lifetxt(pc),a0 ; number
bsr.w print_text
movem.l (sp)+,d0-d4/a0-a3
rts
_lifedata dc.b 37,37,37,36 ; 1 life
dc.b 37,37,36,36
dc.b 37,36,36,36
dc.b 36,36,36,36
_hiscore dc 0
_bonus dc 100
; ---- GET A KEY ----
get_key move.b $bfec01,d0
st.b d1
sub.b d0,d1
ror.b #1,d1
btst #7,d1
bne .no
move.b d1,_rawkey
rts
.no clr.b _rawkey
rts
release_key move.b $bfec01,d0
st.b d1
sub.b d0,d1
ror.b #1,d1
; move.b d1,_rawkey
btst #7,d1
beq release_key
rts
_rawkey dc.b 0,0
; ---- NUMBER TO ASCII CONVERSION ----
; number (d0) / number of digits (d1) / dest (a0)
numtoasc sub #9,d1
neg d1
add d1,d1
add d1,d1
lea _powersof10(pc,d1.w),a1
.next_pow move.l (a1)+,d1
moveq #0,d2
.weigh sub.l d1,d0
bcs.b .gotya
addq #1,d2
bra.b .weigh
.gotya add.l d1,d0
move.b d2,(a0)+
subq.l #1,d1
bne.s .next_pow
rts
_powersof10 dc.l 100000000
dc.l 10000000
dc.l 1000000
dc.l 100000
dc.l 10000
dc.l 1000
dc.l 100
dc.l 10
dc.l 1
; ---- SET VBL INTERRUPT HANDLER ----
set_vbintserver moveq #5,d0
lea vbintserver,a1
move.l 4.w,a6
CALL addintserver
rts
; ---- REMOVE VBL INTERRUPT HANDLER ----
reset_vbintserver
moveq #5,d0
lea vbintserver,a1
move.l 4.w,a6
CALL remintserver
rts
; ---- VBL INTERRUPT CODE ----
vbint movem.l d0-d7/a0-a6,-(sp)
lea _musicdata,a0
jsr FM_PLAYSONG(a0)
movem.l (sp)+,d0-d7/a0-a6
moveq #0,d0
rts
VBIntServer dc.l 0,0
dc.b 2,0 ; type, priority
dc.l _vbintname
dc.l 0,vbint
_vbintname dc.b "Seasons VBL Interrupt!",0
EVEN
; ---- READ HIGHSCORE TABLE FROM DISK ----
read_highscoretable
movem.l d0-a6,-(sp)
lea _htablename(pc),a0
move.l a0,d1
move.l #1005,d2
move.l _dosbase(pc),a6
CALL Open
tst.l d0
beq.b .useinternal
move.l d0,d1
move.l d0,d5
lea _hiscoretable(pc),a0
move.l a0,d2
moveq #120,d3
CALL Read
cmp d0,d3
bne.b .useint
move.l d5,d1
CALL Close
movem.l (sp)+,d0-a6
moveq #0,d0
rts
.useint move.l d5,d1
CALL Close
.useinternal lea _internaltable(pc),a0
lea _hiscoretable(pc),a1
moveq #29,d0
.1 move.l (a0)+,(a1)+ ; copy internal table
dbf d0,.1
movem.l (sp)+,d0-a6
rts
; ---- WRITE HIGHSCORE TABLE TO DISK ----
write_highscoretable
movem.l d0-a6,-(sp)
lea _htablename(pc),a0
move.l a0,d1
move.l #1006,d2
move.l _dosbase(pc),a6
CALL Open
tst.l d0
beq.b .cantdo
move.l d0,d1
move.l d0,d5
lea _hiscoretable(pc),a0
move.l a0,d2
moveq #120,d3
CALL Write
move.l d5,d1
CALL Close
.cantdo movem.l (sp)+,d0-a6
moveq #0,d0
rts
_internaltable
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
dc.b "L"-55,37,"R"-55,"O"-55,"S"-55,"E"-55,"N"-55
dc.b 37,37,37,0,0
_htablename dc.b "Highnoon.HOF",0
EVEN
; ------------------------------------------------------------------------
;
; DATA STRUCTURES
;
; ------------------------------------------------------------------------
_boblookuptable blk.l (NUMBOBS),0
; -----------------------------------------
;
; GENERAL BOB STRUCTURE
;
; -----------------------------------------
RSRESET
bo_inactive RS.B 1 ; set if no draw
bo_firstflag RS.B 1 ; set if first time draw
bo_buffer1 RS.L 1 ; APTR save buffer 1
bo_buffer2 RS.L 1 ; APTR save buffer 2
bo_newmask RS.L 1 ; APTR new mask (backgrounds)
bo_maskoff RS.L 1 ; LONG mask offset
bo_oldx1 RS 1 ; old x position, 1
bo_oldy1 RS 1 ; old y position, 1
bo_oldx2 RS 1 ; old x position, 2
bo_oldy2 RS 1 ; old y position, 2
bo_x RS 1 ; x position
bo_y RS 1 ; y position
bo_image RS 1 ; object image
bo_height RS 1 ; object height
bo_maskmade RS.B 1 ; set if new mask made
bo_expanded RS.B 1 ; set if bob "expanded"
bo_sizeof RS.B 0
_bobstructs blk.b (BO_SIZEOF*MAXBOBS),0
INCDIR DH1:DEV/RSC/
_videoresource INCBIN VIDEO.RESOURCE
INCDIR SOURCE:GAMES/CLASSIC/HIGH_NOON/
_fontdata INCBIN DATA/FONT.DATA
_arena1 INCBIN DATA/ARENA1.DATA
_arena1map INCBIN DATA/ARENA1MAP.DATA
_arena2 INCBIN DATA/ARENA2.DATA
_arena2map INCBIN DATA/ARENA2MAP.DATA
_sniperdata INCBIN DATA/SNIPERS.DATA
_title INCBIN DATA/TITLE.DATA
_titlemap INCBIN DATA/TITLEMAP.DATA
_highscore INCBIN DATA/HISCORE.DATA
_highscoremap INCBIN DATA/HISCOREMAP.DATA
; ------------------------------------------------------------------------
;
; CHIP DATA HUNK
;
; ------------------------------------------------------------------------
INCDIR SOURCE:GAMES/CLASSIC/HIGH_NOON/
SECTION BRUCE_II,DATA_C
CWAIT = -2
CO SET $0180
CB SET $0
cnop 0,8
_copperlist dc $2107,CWAIT
_copspriteptrs dc SPR0PTH,$0000,SPR0PTL,$0000
dc SPR1PTH,$0000,SPR1PTL,$0000
dc SPR2PTH,$0000,SPR2PTL,$0000
dc SPR3PTH,$0000,SPR3PTL,$0000
dc SPR4PTH,$0000,SPR4PTL,$0000
dc SPR5PTH,$0000,SPR5PTL,$0000
dc SPR6PTH,$0000,SPR6PTL,$0000
dc SPR7PTH,$0000,SPR7PTL,$0000
dc DIWSTRT,$2C81,DIWSTOP,$3CC1
dc DDFSTRT,$0028,DDFSTOP,$00D4
dc BPLCON1,$0000,BPLCON2,$0024
dc BPL1MOD,2,BPL2MOD,2
dc BPLCON0,(NUMPLANES<<12)!$200
; dc FMODE,$4
; dc BPLCON3,$40
_copbitplaneptrs
dc BPL1PTH,$0000,BPL1PTL,$0000
dc BPL2PTH,$0000,BPL2PTL,$0000
dc BPL3PTH,$0000,BPL3PTL,$0000
dc BPL4PTH,$0000,BPL4PTL,$0000
dc BPL5PTH,$0000,BPL5PTL,$0000
dc CO+14,$000C
dc CO+12,$0000
dc $3407,CWAIT
_copcolors dc CO+00,$0000,CO+02,$0FFF,CO+04,$0C00,CO+06,$00FF
dc CO+08,$0F0F,CO+10,$00C0,CO+12,$000C,CO+14,$0CC0
dc CO+16,$0F80,CO+18,$0800,CO+20,$0F88,CO+22,$0444
dc CO+24,$0888,CO+26,$00F8,CO+28,$0000,CO+30,$0CCC
dc $D407,CWAIT
dc CO+12
_textcolor dc $0000
dc CO+08
_textcolor2 dc $0000
dc $F2EF,CWAIT
dc BPLCON0,$0200
dc BPL1MOD,$0000,BPL2MOD,$0000
dc $FFFF,CWAIT
dc $FFFF,CWAIT
cnop 0,8
_blanksprite blk.l 16,0
_bobdata INCBIN DATA/SPRITES.DATA
_expbobdata INCBIN DATA/EXPSPRITES.DATA
_dynabuff1 blk.b (8*42*NUMPLANES),0
_dynabuff2 blk.b (8*42*NUMPLANES),0
_horsebuff1 blk.b (8*42*NUMPLANES),0
_horsebuff2 blk.b (8*42*NUMPLANES),0
CNOP 0,4
_backmask INCBIN DATA/BACKGROUND.MSK
_newmask BLK.B (BOBPLANE),0
_newmask2 BLK.B (BOBPLANE),0
_doordata INCBIN DATA/DOORS.DATA
_musicdata INCBIN DATA/SOUND.DATA
cnop 0,8
_screen1 blk.l (PLANE_SIZE*NUMPLANES)/4,0
cnop 0,8
_screen2 blk.l (PLANE_SIZE*NUMPLANES)/4,0