This is a sub-page of Development:Cybermorph.
;=====================================================================
;Header file to be included by any files using ENEMY routines.
;---------------------------------------------------------------------
global hud,hudinit
global hud,domessage
global hud,stopholly
global hud,doHUD
global hud,displayStatus
global hud,bcdtoa
global hud,stripzeros
global hud,audiomsgptr
global hud,audiocurptr
global hud,audiocurpri
global hud,audionxtptr
global hud,audionxtpri
global hud,audiotime
global hud,audiosync
global hud,slidemons
;Macro for message system interface ----------------------------------
DOMSG macro
IFNC '\1','d0'
IFNC '\1','D0'
move.w #\1,d0
ENDC
ENDC
bsr domessage
endm
;Message numbers for DOMSG macro -------------------------------------
MSG_ENERGY equ 0*DWORD
MSG_WEAPNLOW equ 1*DWORD
MSG_START equ 2*DWORD
MSG_WELLDONE equ 3*DWORD
MSG_POWERLOW equ 4*DWORD
MSG_PORTAL equ 5*DWORD
MSG_JAMMED equ 6*DWORD
MSG_INTRANSIT equ 7*DWORD
MSG_DOUBLESHOT equ 8*DWORD
MSG_TRIPLESHOT equ 9*DWORD
MSG_FLAMETHROW equ 10*DWORD
MSG_BOMB equ 11*DWORD
MSG_MINE equ 12*DWORD
MSG_THUNDER equ 13*DWORD
MSG_QUAKE equ 14*DWORD
MSG_EXTRALIFE equ 15*DWORD
MSG_NITRO equ 16*DWORD
MSG_SPEEDUP equ 17*DWORD
MSG_PODDYING equ 18*DWORD
MSG_PODDEAD equ 19*DWORD
MSG_INWORLD equ 20*DWORD
MSG_SECRET equ 21*DWORD
MSG_SHOTPOWER equ 22*DWORD
MSG_SHOTRADAR equ 23*DWORD
MSG_ONEMORE equ 24*DWORD
MSG_OUCH equ 25*DWORD
MSG_WHERE equ 26*DWORD
MSG_GOODSHOT equ 27*DWORD
MSG_AVOIDGND equ 28*DWORD
MSG_GOODPLAY equ 29*DWORD
MSG_FNDSECRET equ 30*DWORD
; Macro for defining a hologram frame (offset,time) ------------------
HOLOFRAME macro
dc.w \1,\2 ;frame offset, time (0-65535)
endm
HOLOSOUND macro
dc.w -2,\1 ;play sound effect now
endm
;Frame offsets for above macro ---------------------------------------
holo0 equ 0
holo1 equ 1*(57*24)
holo2 equ 2*(57*24)
holo3 equ 3*(57*24)
holo4 equ 4*(57*24)
holo5 equ 5*(57*24)
holo6 equ 6*(57*24)
holo7 equ 7*(57*24)
holo8 equ 8*(57*24)
holo9 equ 9*(57*24)
holo10 equ 10*(57*24)
holo11 equ 11*(57*24)
holo12 equ 12*(57*24)
holo13 equ 13*(57*24)
holo14 equ 14*(57*24)
holo15 equ 15*(57*24)
holo16 equ 16*(57*24)
holo17 equ 17*(57*24)
holo18 equ 18*(57*24)
holo19 equ 19*(57*24)
holo20 equ 20*(57*24)
holo21 equ 21*(57*24)
holo22 equ 22*(57*24)
holo23 equ 23*(57*24)
holo24 equ 24*(57*24)
holo25 equ 25*(57*24)
holo26 equ 26*(57*24) ;appear / disappear frames
holo27 equ 27*(57*24)
holo28 equ 28*(57*24)
HUD.M68#
;=====================================================================
;Status panel / HUD code. Complex due to a large amount of information
;being displayed. Energy, number of pods remaining, weapons available
;for selection are all present with a scanner showing what is around
;the player's ship. Complex code as the status panel object swaps!
;
;
;Copyright 1992, Attention To Detail Ltd. Version 1.9g
;---------------------------------------------------------------------
;Routines contained herein:
;
; 3 initialisers : system, new game and new level initialisers
;
; hudinit : level initialiser - ordering problems
;
; domessage : start a message going (sound / visual)
; stopholly : stop audio messages
;
; doHUD : calculate player information + display some
; displayStatus : display Radar and other status information
;
; calcScanner : calculate scanner display information
; calcArrow : calculate angle to PODs / portal
; displayScanner : display all the calculated radar info
; displayArrow : display arrow
;
; bcdtoa : convert BCD to ASCIIZ for display
; stripzeros : remove leading zeros from strings
;
;=====================================================================
NEWOBJS equ 0 ;new object list?
include .\atd.inc
modulename hud
include jag.inc
include jdos.inc
include .\global.inc
include .\demo.inc
include .\game.inc
include .\system.inc
include .\misc.inc
include .\maths.inc
include .\grafix.inc
include .\hud.inc
include .\collide.inc
include .\support.inc
include .\player.inc
include .\obj3d.inc
include .\olist.inc
include .\hostage.inc
include .\sound.inc
global sinetab,sinetable
global hostage,remhostages
global hostage,saved
global level,bonuslvlflg
;---------------------------------------------------------------------
;Defines for the Radar display
RADARX equ 300-32-3 ;top rhs of game screen
RADARY equ 24+32+3
WORLDDIST equ (4096<<DSHIFT)
SCALESHIFT equ (7+DSHIFT) ;4096 / 128 is 32 pixels
PLAYRCOLOUR equ $88bf88bf ;light grey for player +
ALTCOLOUR1 equ $00200020 ;grey
ALTCOLOUR2 equ $74C074C0 ;bluey purple
ALTIMETERX equ RADARX-4 ;RADARX-48
ALTIMETERY equ RADARY+48 ;RADARY-15
ALTIMETERW equ 11
ALTIMETERH equ 48 ;CEILINGHT/16
ALTMAXHT equ 1024 ;maximum height represented
POINTASZ equ 30 ;polar coordinate definitions of
POINTABCSZ equ 8 ;the radar arrow.
POINTBTHETA equ (ANGLE90+ANGLE60)*2
POINTCTHETA equ (ANGLE90+ANGLE120)*2
ARROWCOLOUR1 equ $ffffffff ;arrow for exit / hostages
ARROWCOLOUR2 equ $88ff88ff ;arrow for pollutant towers
;---------------------------------------------------------------------
;Various status panel / HUD positions for read-outs etc.
HILIGHTADD equ 9 ;2-10 collected frames, 11 are active
BLANKMON equ 20 ;21st frame is blank
BACKGNDCOL equ $08080808 ;background colour
HEALTHCOL equ $0E0E0E0E ;health bar colour
PODWINX equ 289
PODWINY equ 17
PODWINW equ 13
PODWINH equ 7 ;pod count window
TEXTWINX equ 104
TEXTWINY equ 38
TEXTWINW equ 112
TEXTWINH equ 7 ;dimensions of the text window
HEALTHX equ 27
HEALTHY equ 11
HEALTHW equ 7
HEALTHH equ 32 ;health meter dimensions
SPEEDX equ 13
SPEEDY equ HEALTHY
SPEEDW equ HEALTHW
SPEEDH equ HEALTHH ;speedo dimensions
SPEEDOCOL1 equ $0A0A0A0A ;speedo colour 1
SPEEDOCOL2 equ $01010101 ;speedo colour 2
SPEEDOCOL3 equ $04040404 ;speedo colour 2
LHSPLOTX equ 68
RHSPLOTX equ 194
LRHSPLOTY equ 10 ;plot positions for sliding mons
;---------------------------------------------------------------------
;Structure for knobs and dials on the status panel / hud - swapping.
STRUCT statusvars
ELEMENT superwf,BYTE ;last superweapon frame
ELEMENT superwc,BYTE ;last superweapon count
ELEMENT healthm,WORD ;health meter
ELEMENT speedo,WORD ;speedometer
ELEMENT podcnt,WORD ;remaining pod count
ELEMENT msgnum,WORD ;message number
ENDS statusvars,ALIGNWORD
;---------------------------------------------------------------------
;Bit positions for the HUDFLAGS (only 8 bits of word are used).
DISP_SCANNER equ 0 ;bit position
DISP_ARROW equ 1 ;bit position (arrow flag)
DISP_BONUS equ 2 ;bit position (show time)
DISP_POLLUTANT equ 4 ;bit position (show pollutant arrow)
;---------------------------------------------------------------------
BEGVARS
VAR ,NULL,ALIGNLONG ;align data
VAR hudptrF,DWORD ;currently displayed panel
VAR hudptrB,DWORD ;back panel
VAR gamepal,DWORD ;palette for HUD
VAR monitordef,DWORD ;monitors for HUD
VAR scannerdef,DWORD ;scanner bits definition
VAR radardef,DWORD ;scanner graphics
VAR fonts,DWORD ;small counter font
VAR fonth,DWORD ;256 colour HUD message font
VAR lhsmondef,DWORD ;LHS slidy panels
VAR rhsmondef,DWORD ;RHS slidy panels
VAR hudexpcnt,WORD ;HUD explosion counter
VAR slidemons,WORD ;slide monitors out?
VAR svars1,statusvars ;status variables 1
VAR svars2,statusvars ;status variables 2 (must follow 1)
VAR lastscore,DWORD ;stop unecessary conversion to ASCII
VAR visualmsgptr,DWORD ;current message pointer
VAR visualcurpri,WORD ;current message priority
VAR visualnxtptr,DWORD ;next message pointer
VAR visualnxtpri,WORD ;next message priority
VAR visualtime,WORD ;how long to display msg
VAR visualmsgnum,WORD ;minimalise HUD updates
VAR audiomsgptr,DWORD ;pointer thru audio message
VAR audiocurptr,DWORD ;pointer to base of audio
VAR audiocurpri,WORD ;current message priority
VAR audionxtptr,DWORD ;next message pointer
VAR audionxtpri,WORD ;next message priority
VAR audiotime,WORD ;how long to display frame
VAR audiosync,WORD ;S/W bug workaround
VAR altgndht,WORD
VAR hudflags,WORD ;display flags
VAR radarlist,6*MAXRADARBLOBS ;list of blobs for scanner
VAR radarptr,DWORD ;ptr into above scanner list
VAR arrowa,DWORD*3 ;space for 3 coordinate pairs
VAR arrowb,DWORD*3 ;space for 3 coordinate pairs
VAR HUDinworld,32 ;1,5,0,20,'PODS REMAINING 00',0
VAR HUDremhostgstr,4
VAR HUDbonusstr,4
VAR HUDscorestr,10
VAR HUDweapcnt,4
VAR HUDsupercnt,4
VAR HUDlifestr,4 ;various strings (padded to boundary)
ENDVARS
;---------------------------------------------------------------------
BEGCONST
hudobj1: dc.l panelmem1
dc.w panelht,screenw,7
dc.l A1PITCH1+A1PIXEL8+A1WIDTH320
dc.l svars1 ;extra item
hudobj2: dc.l panelmem2
dc.w panelht,screenw,7
dc.l A1PITCH1+A1PIXEL8+A1WIDTH320
dc.l svars2 ;extra item
hudlist: dc.w 8 ;sprite decompression list
dc.l hudpal,gamepal
dc.l monitors,monitordef
dc.l radarblobs,radardef
dc.l smlfont,fonts
dc.l hudfont,fonth
dc.l scanner,scannerdef
dc.l lhsmons,lhsmondef
dc.l rhsmons,rhsmondef
moninfo: dc.w 16,44,3 ;DOUBLE SHOT
dc.w 16,72,4 ;TRIPLE SHOT
dc.w 15,100,6 ;BOMB
dc.w 15,204,5 ;MINE
dc.w 16,232,7 ;FIRE
messglist: dc.l mess_energy
dc.l mess_weapnlow
dc.l mess_start ;'Good Luck'
dc.l mess_welldone ;'Well Played'
dc.l mess_powerlow
dc.l mess_portalup ;'Portal Now Open'
dc.l mess_jammed ;'Your Scanner Jammed'
dc.l mess_intransit
dc.l mess_double
dc.l mess_triple
dc.l mess_flame
dc.l mess_bomb
dc.l mess_mine
dc.l mess_thunder
dc.l mess_quake
dc.l mess_extralife
dc.l mess_nitro
dc.l mess_speedup
dc.l mess_poddying ;'Pod In Trouble'
dc.l mess_poddead
dc.l HUDinworld ;RAM based message
dc.l mess_secret
dc.l mess_shotpower
dc.l mess_shotradar
dc.l mess_onemore
dc.l mess_ouch
dc.l mess_where
dc.l mess_goodshot
dc.l mess_avoidgnd
dc.l mess_goodplay
dc.l mess_fndsecret
;Visual Messages (pri,chan,snd?,time) --------------------------------
mess_energy: dc.b 2,1,0,20,'ENERGISING',0
mess_weapnlow: dc.b 5,1,1,20,'WEAPON LOW',0
mess_powerlow: dc.b 5,1,1,20,'POWER LOW',0
mess_double: dc.b 4,1,0,12,'TWIN SHOT',0
mess_triple: dc.b 4,1,0,12,'THREE WAY',0
mess_flame: dc.b 4,1,0,12,'INCINERATOR',0
mess_bomb: dc.b 4,1,0,12,'CRUISE BOMBS',0
mess_mine: dc.b 4,1,0,12,'MINES',0
mess_thunder: dc.b 4,1,0,12,'THUNDERQUAKER',0
mess_quake: dc.b 4,1,0,12,'DETONATOR',0
mess_extralife: dc.b 4,1,0,15,'EXTRA TGRIFFON SHIP',0
mess_nitro: dc.b 4,1,0,12,'NITRO',0
mess_poddead: dc.b 6,1,1,12,'POD DESTROYED',0
mess_speedup: dc.b 4,1,0,12,'RAPID FIRE',0
mess_secret: dc.b 4,1,0,20,'BONUS LEVEL',0
mess_shotpower: dc.b 8,1,1,30,'FORCE FIELD DOWN',0
mess_shotradar: dc.b 8,1,1,30,'ENEMY RADAR JAMMED',0
mess_fndsecret: dc.b 8,1,1,30,'BONUS WORLD AWARDED',0
mess_intransit: dc.b 10,1,1,80,'IN TRANSIT TO WORLD',0
secretstr: dc.b 'BONUS LEVEL',0
demostr: dc.b 'DEMO',0
inworldstr: dc.b 'PODS REMAINING ',0
hudexptable: dc.l freememory
dc.l freememory+53*320*1
dc.l freememory+53*320*2
dc.l freememory+53*320*3
dc.l freememory+53*320*4
dc.l freememory+53*320*5
dc.l freememory+53*320*6
dc.l freememory+53*320*7
;Audio Messages (pri,channel,frame offsets x N,-1) -------------------
align ALIGNWORD
mess_start: dc.b 1,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_GOODLUCK
HOLOFRAME holo18,1*4
HOLOFRAME holo3,2*4
HOLOFRAME holo11,1*4
HOLOFRAME holo18,1*4
HOLOFRAME holo3,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo0,2*4
HOLOFRAME holo19,1*4
HOLOFRAME holo18,1*4 ;'GOOD LUCK'
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_welldone: dc.b 1,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_WELLDONE
HOLOFRAME holo18,1*4
HOLOFRAME holo22,2*4
HOLOFRAME holo11,2*4
HOLOFRAME holo18,2*4
HOLOFRAME holo11,2*4
HOLOFRAME holo22,2*4
HOLOFRAME holo18,2*4
HOLOFRAME holo19,2*4
HOLOFRAME holo18,2*4 ;'GOOD WORK'
;-------------------
HOLOFRAME holo20,2*5 ;smile
HOLOFRAME holo21,6*5
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_portalup: dc.b 4,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_PORTALUP
HOLOFRAME holo18,1*4
HOLOFRAME holo1,1*4
HOLOFRAME holo22,1*4
HOLOFRAME holo23,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo9,1*4
HOLOFRAME holo0,1*4
HOLOFRAME holo14,2*4
HOLOFRAME holo23,1*4
HOLOFRAME holo11,1*4
HOLOFRAME holo23,1*4
HOLOFRAME holo1,1*4
HOLOFRAME holo14,2*4
HOLOFRAME holo18,1*4 ;'PORTAL NOW OPEN'
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_jammed: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_SCANNERJ
HOLOFRAME holo18,1*4
HOLOFRAME holo19,1*4
HOLOFRAME holo18,1*4
HOLOFRAME holo22,3*4
HOLOFRAME holo2,1*4
HOLOFRAME holo18,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo0,2*4
HOLOFRAME holo5,1*4
HOLOFRAME holo2,2*4
HOLOFRAME holo18,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo5,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo19,1*4
HOLOFRAME holo5,1*4
HOLOFRAME holo0,1*4
HOLOFRAME holo7,2*4
HOLOFRAME holo5,1*4
HOLOFRAME holo18,1*4 ;'YOUR SCANNER IS JAMMED'
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_poddying: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_INTROUBLE
HOLOFRAME holo18,1*4
HOLOFRAME holo1,1*4
HOLOFRAME holo22,1*4
HOLOFRAME holo4,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo5,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo12,2*4
HOLOFRAME holo22,2*4
HOLOFRAME holo24,2*4
HOLOFRAME holo14,2*4
HOLOFRAME holo18,1*4 ;'POD IN TROUBLE'
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_onemore: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_ONEMORE
HOLOFRAME holo18,1*4
HOLOFRAME holo23,2*4
HOLOFRAME holo14,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo23,2*4
HOLOFRAME holo24,1*4
HOLOFRAME holo23,2*4
HOLOFRAME holo4,1*4
HOLOFRAME holo9,3*4
HOLOFRAME holo0,1*4
HOLOFRAME holo5,1*4
HOLOFRAME holo18,1*4 ;'ONLY ONE MORE' (check)
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_ouch: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_OUCH
HOLOFRAME holo18,1*4
HOLOFRAME holo25,2*4
HOLOFRAME holo11,2*4
HOLOFRAME holo9,2*4
HOLOFRAME holo18,1*4 ;'OUCH'
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_where: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_WHERE
HOLOFRAME holo18,1*4
HOLOFRAME holo23,1*4
HOLOFRAME holo11,1*4
HOLOFRAME holo0,2*4
HOLOFRAME holo9,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo6,1*4
HOLOFRAME holo11,2*4
HOLOFRAME holo14,1*4
HOLOFRAME holo22,2*4
HOLOFRAME holo5,1*4
HOLOFRAME holo9,1*4
HOLOFRAME holo11,3*4
HOLOFRAME holo8,3*4
HOLOFRAME holo13,3*4
HOLOFRAME holo0,3*4
HOLOFRAME holo18,1*4 ;'WHERE DID YOU LEARN TO FLY' (check)
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_goodshot: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_GOODSHOT
HOLOFRAME holo18,1*4
HOLOFRAME holo12,1*4
HOLOFRAME holo23,1*4
HOLOFRAME holo0,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo5,2*4
HOLOFRAME holo22,4*4
HOLOFRAME holo9,4*4
HOLOFRAME holo18,1*4 ;'GOOD SHOT' (check)
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_avoidgnd: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_AVOIDGND
HOLOFRAME holo18,1*4
HOLOFRAME holo2,1*4
HOLOFRAME holo0,1*4
HOLOFRAME holo13,2*4
HOLOFRAME holo23,1*4
HOLOFRAME holo9,4*4 ;pause ? (2 before)
HOLOFRAME holo5,2*4
HOLOFRAME holo2,1*4
HOLOFRAME holo22,1*4
HOLOFRAME holo9,2*4
HOLOFRAME holo0,2*4
HOLOFRAME holo3,2*4
HOLOFRAME holo18,1*4 ;'AVOID THE GROUND' (check)
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
mess_goodplay: dc.b 2,0
HOLOFRAME holo26,2*3
HOLOFRAME holo27,2*3
HOLOFRAME holo26,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo28,1*3
HOLOSOUND SFX_GOODPLAY
HOLOFRAME holo18,1*4
HOLOFRAME holo22,2*4
HOLOFRAME holo23,2*4
HOLOFRAME holo0,1*4
HOLOFRAME holo3,1*4
HOLOFRAME holo14,1*4
HOLOFRAME holo18,2*4
HOLOFRAME holo3,4*4
HOLOFRAME holo18,1*4 ;'WELL DONE' (check)
;-------------------
HOLOFRAME holo28,1*3
HOLOFRAME holo27,1*3
HOLOFRAME holo26,1*3
dc.w -1
ENDCONST
BEGCODE
;=====================================================================
;HUD system initialiser. Decompress 2 copies of the status panel / HUD
;into object RAM (different from game RAM) and leave them there for
;the whole of the game.
INITIALISER iSYSTEM
lea hudobj1,a0
move.l a0,hudptrF(a6)
lea hudobj2,a0
move.l a0,hudptrB(a6) ;for panel swapping!
lea freememory,a1
lea hudexp1,a0
bsr dcompress ;exploding panel frame 1
lea freememory+16960,a1
lea hudexp2,a0
bsr dcompress ;exploding panel frame 2
lea freememory+33920,a1
lea hudexp3,a0
bsr dcompress ;exploding panel frame 3
lea freememory+50880,a1
lea hudexp4,a0
bsr dcompress ;exploding panel frame 4
lea freememory+67840,a1
lea hudexp5,a0
bsr dcompress ;exploding panel frame 5
lea freememory+84800,a1
lea hudexp6,a0
bsr dcompress ;exploding panel frame 6
lea freememory+101760,a1
lea hudexp7,a0
bsr dcompress ;exploding panel frame 7
lea freememory+118720,a1
lea hudexp8,a0
bsr dcompress ;exploding panel frame 8
clr.w hudexpcnt(a6)
lea headmemory,a1
lea head1,a0
bsr dcompress
lea headmemory+18*(headw/2)*headht,a1
lea head2,a0
bsr dcompress ;29 hologram head frames
move.l d1,lastscore(a6) ;minimise conversion to ASCIIZ
;Fill in parts of strings that are constant - awful way of doing it.
lea HUDlifestr(a6),a0
move.b #'#',(a0)+ ;fill in parts of life string
lea HUDinworld(a6),a1
move.b #1,(a1)+
move.b #1,(a1)+
clr.b (a1)+
move.b #14,(a1)+ ;pri,chan,sound?,time
lea inworldstr,a0 ;'PODS REMAINING '
bra strcpy
;
;---------------------------------------------------------------------
;=====================================================================
;HUD initialiser when a new game begins - decompress some HUD graphics
;at the start of a new game. Only required and used by the routines
;contained in this file.
INITIALISER iNEWGAME
clr.w visualcurpri(a6)
clr.w visualnxtpri(a6)
clr.w visualtime(a6)
clr.w visualmsgnum(a6) ;force update!
lea hudlist,a0
bsr getdatalist ;expand graphics for HUD
move.l gamepal(a6),a0
bra setpalette ;set palette for 8 plane objects
;
;---------------------------------------------------------------------
;=====================================================================
;New level initialiser! Here because Atari want the monitors to slide
;out when we start a level! Due to the fact that we overwrite the last
;information plotted to the panels from the last level played, we must
;clear all the plotting minimising stuff!
INITIALISER iNEWLEVEL
lea panelmem1,a1
lea hudgfx,a0
bsr dcompress ;first status panel (of 2)
lea panelmem2,a1
lea hudgfx,a0
bsr dcompress ;second status panel (of 2)
clr.w slidemons(a6)
lea svars1(a6),a0
sub.l d0,d0
moveq #-1,d1
move.b d1,superwf(a0) ;last super weapon frame
move.b d1,superwc(a0) ;last super weapon count
move.w d0,healthm(a0) ;last health meter reading
move.w d1,speedo(a0) ;last speedometer reading
move.w d1,podcnt(a0) ;last pod count
move.w d1,msgnum(a0) ;last message status
lea svars2(a6),a0
move.b d1,superwf(a0) ;last super weapon frame
move.b d1,superwc(a0) ;last super weapon count
move.w d0,healthm(a0) ;last health meter reading
move.w d1,speedo(a0) ;last speedometer reading
move.w d1,podcnt(a0) ;last pod count
move.w d1,msgnum(a0) ;last message status
rts
;
;---------------------------------------------------------------------
;=====================================================================
;HUD Init stuff. Not an initialiser because of ordering problems! The
;main use of this routine is to ensure that the 'IN TRANSIT TO WORLD'
;message appears properly (and not the 'PODS REMAINING ..').
hudinit: move.w remhostages(a6),d0
move.w d0,podcnt+svars1(a6)
move.w d0,podcnt+svars2(a6)
lea HUDinworld+15+4(a6),a0
PUSH a0
bsr utoa2
POP a0
bsr stripzeros ;ensure pod message correct!
clr.w visualtime(a6)
DOMSG MSG_INTRANSIT
bra.s stopholly
;
;---------------------------------------------------------------------
;=====================================================================
;This routine processes messages being output to the display window or
;via a sample and the holographic head. Simple system with priorities
;to ensure the best messages are displayed. Currently, neither audio
;or visual channels can be interrupted. Later we might want the visual
;to have this capability?
;
;ON ENTRY: D0 is message number (scaled)
;CORRUPTED:
;ON EXIT:
domessage: PUSH a0
lea messglist,a0
move.l (a0,d0.w),a0 ;at correct message 'string'
sub.w d0,d0
move.b (a0)+,d0 ;get priority (0-255)
tst.b (a0)+
beq.s audiochan ;audio or visual channel?
cmp.w visualnxtpri(a6),d0
blt.s 9$ ;greater or equal pri, use it
move.w d0,visualnxtpri(a6) ;leave it pointing at snd flag
move.l a0,visualnxtptr(a6) ;display routine uses it
9$: POP a0
rts
;Process the audio channel (which includes holographic head) ---------
audiochan: cmp.w audionxtpri(a6),d0
blt.s 9$ ;greater or equal pri, use it
cmp.l audiocurptr(a6),a0
beq.s 9$ ;don't trigger same message!
move.w d0,audionxtpri(a6) ;next priority
move.l a0,audionxtptr(a6) ;points to frame data
9$: POP a0
rts
;
;---------------------------------------------------------------------
;=====================================================================
;Stop any audio message currently being played. This removed the head
;(HOLOGRAPHIC) from the display and also kills the sound associated
;with that animation.
;
;ON ENTRY:
;CORRUPED:
;ON EXIT:
stopholly: tst.w audiocurpri(a6) ;'HOLOGRAPHIC' head active?
beq.s 0$
IFEQ NEWOBJS
moveq #4,d0
ENDC
IFNE NEWOBJS
moveq #2,d0
ENDC
bsr set_op_list_sz ;remove 'HOLOGRAPHIC' head
0$: clr.w audionxtpri(a6)
clr.w audiosync(a6)
clr.w audiocurpri(a6)
clr.l audiocurptr(a6) ;reset message flags
rts
;
;---------------------------------------------------------------------
;=====================================================================
;This routine calculates almost everything associated with the HUD and
;proceeds to plot some of them now and the rest later. These include
;the scanner, number of pods remaining, energy etc. Where possible in
;this routine A4 contains the contents of MAINOBJECT and A3 points to
;the base of SVARS1 or SVARS2.
;
;ON ENTRY:
;CURRUPTED: just about everything
;EXIT:
doHUD: clr.w hudflags(a6) ;flags for display later
bsr calcScanner ;search for enemies, powers, PODs
move.l fonts(a6),a0
SET_FONT a0 ;select small font for numbers
move.l hudptrB(a6),a3 ;back HUD object
SET_CUROBJPTR a3 ;all writes to this object
move.l atdobjsz(a3),a3 ;A3 to base of SVARS1 or SVARS2
move.l mainobject(a6),a4
;---------------------------------------------------------------------
;Slide the monitors out if we are landing on the planet now...........
move.w slidemons(a6),d1
beq superwdone
cmp.w #27,d1
bge.s dispweaps ;1-27 are animations
addq.w #1,d1 ;increment frame count
move.w d1,slidemons(a6)
lsr.w #1,d1 ;ensure frames go to both panels
subq.w #1,d1 ;0-12 are frames!
move.l #$00070044,d0
move.l lhsmondef(a6),a0
PUSH d1
bsr plotgrobject ;plot LHS
POP d1
move.l #$000700C2,d0
move.l rhsmondef(a6),a0
bsr plotgrobject ;plot RHS
bra superwdone
;---------------------------------------------------------------------
;Display the player's weapons in their monitor areas or not...........
dispweaps: lea moninfo,a1 ;monitor information
lea plr.weapon(a4),a2 ;weapon slots
move.w #MAXWEAPON-1,d7 ;loop count
move.w plr.weaponidx(a4),d6 ;selected weapon IDX
move.w #2,d1 ;BLANK FRAME now is SINGLE SHOT
0$: move.w (a2)+,d0 ;weapon count
beq.s 1$
;Found a weapon. Display a picture of it and counter if required.
move.w WORD*2(a1),d1 ;frame
1$: sub.w d4,d4 ;display count flag
or.w d6,d6
bne.s 2$ ;selected?
add.w #HILIGHTADD,d1
move.w d0,d4 ;real weapon count
2$: move.l monitordef(a6),a0
move.l (a1),d0 ;relative plot coords
PUSHM <a1/a2/d0/d4>
bsr plotgrobject ;draw it in position
POPM <a1/a2/d0/d4>
;Does this weapon have a counter for remaining use - display if required.
or.w d4,d4 ;display a count?
beq.s 3$
exg d0,d4 ;D0.w is count
lea HUDweapcnt(a6),a0
bsr utoa3 ;convert count to string
exg d0,d4
add.l #(6*65536)+1,d0 ;offset to plot position
PUSHM <a1/a2/a3/a4>
lea HUDweapcnt(a6),a0
bsr ptext
POPM <a1/a2/a3/a4> ;display the count
3$: sub.w #WORD,d6
move.w #BLANKMON,d1 ;blank frame now is BLANK!
lea WORD+DWORD(a1),a1
dbra d7,0$
;---------------------------------------------------------------------
;Display any special weapon that may have been collected (count reqd!)
move.l gloopcount(a6),d1 ;use game loop counter
and.w #1,d1 ;to generate TV noise
move.b plr.superw(a4),d0
beq.s 4$
move.b d0,d1 ;proper frame (in LOW byte)
move.l gloopcount(a6),d5
and.w #8,d5
beq.s 4$
add.w #HILIGHTADD,d1
;Plot the required frame (noise or flashing GFX) if not already there!
4$: cmp.b superwf(a3),d1 ;same as last time?
bne.s 5$
move.b plr.superwcnt(a4),d2
cmp.b superwc(a3),d2
beq.s superwdone ;count and frame same as previous
5$: move.b d2,superwc(a3)
move.b d1,superwf(a3) ;store frame and count for next time
move.l monitordef(a6),a0
move.l #(16*65536)+260,d0
bsr plotgrobject
cmp.b #1,superwf(a3)
ble.s superwdone ;don't display number if NOISE!
lea HUDsupercnt(a6),a0
sub.w d0,d0
move.b plr.superwcnt(a4),d0
bsr utoa2
move.l #(24*65536)+263,d0
lea HUDsupercnt(a6),a0
PUSHM <a3/a4>
bsr ptext
POPM <a3/a4>
superwdone:
;---------------------------------------------------------------------
;Display the number of PODs requiring collection now. RHS of HUD panel
move.w minhostages(a6),d0
sub.w saved(a6),d0
bcc.s 0$
sub.w d0,d0 ;show number we are required to collect
0$:
lea HUDremhostgstr(a6),a0
bsr utoa2
move.l #(PODWINY*65536)+PODWINX,d0
move.l #(PODWINH*65536)+PODWINW,d1
move.l #BACKGNDCOL,d2
bsr rectfill ;clear to colour 8 (BLACK)
lea HUDremhostgstr(a6),a0
move.l #((PODWINY)*65536)+PODWINX+2,d0
PUSHM <a3/a4>
bsr ptext
POPM <a3/a4>
;Display the number of PODS remaining in the world for collection now.
move.w remhostages(a6),d0
cmp.w podcnt(a3),d0 ;same as last time?
beq.s poddone
move.w d0,podcnt(a3) ;store away for next time
;Also need to update the pod count for the player's benefit A.S.A.P.
move.w remhostages(a6),d0
lea HUDinworld+15+4(a6),a0
PUSH a0
bsr utoa2
POP a0
bsr stripzeros
DOMSG MSG_INWORLD ;issue high priority 'PODS ..'
clr.w visualtime(a6) ;force immediate update
poddone:
;---------------------------------------------------------------------
;Show the player's health (if it has changed) in the health bar window
sub.l d3,d3 ;clear top word for div - BUGFIX
move.w obj.energy(a4),d3
divu #(INITPOWER/HEALTHH),d3
cmp.w healthm(a3),d3
beq.s healthdone ;don't plot if same as last time
move.w d3,healthm(a3) ;store away for next time
tst.w d3 ;FIX - show at least 1 unit
bne.s 0$ ;when alive
moveq #1,d3
0$:
;Not the same as last time so we need to plot all of the health bar.
move.l #(HEALTHW*65536)+HEALTHH,d1
sub.w d3,d1
move.l d1,d4
swap d1
move.l #(HEALTHY*65536)+HEALTHX,d0
move.l #BACKGNDCOL,d2
bsr rectfill ;fill in BLACK bit first
add.w #HEALTHY,d4
swap d4
move.w #HEALTHX,d4 ;plot coords
move.l d4,d0
swap d3
move.l d3,d1
move.w #HEALTHW,d1 ;(height,HEALTHW)
move.l #HEALTHCOL,d2
bsr rectfill ;fill in health bar now
healthdone:
;---------------------------------------------------------------------
;Show the player's speed in a speedo on the HUD now...................
IFNE SPEEDH-32
error
ENDC
move.w plr.thrustix(a4),d3
cmp.w speedo(a3),d3
beq.s speedone ;any change?
move.w d3,speedo(a3) ;store for next time
;Not the same as last time. Clear the whole area to black first ------
move.l #(SPEEDY*65536)+SPEEDX,d0
move.l #(SPEEDH*65536)+SPEEDW,d1
move.l #BACKGNDCOL,d2
bsr rectfill ;fill in BLACK bit first
;Decide whether to plot -Ve or +Ve speed rectangle now ---------------
sub.w #64,d3 ;STOPSPD
beq.s speedone
blt.s 0$
move.l #SPEEDOCOL1,d2
cmp.w #100,d3 ;MAXFWDIDX-STOPSPD
ble.s 1$
move.l #SPEEDOCOL3,d2 ;must be Nitroing at the moment
1$: asr.w #2,d3 ;(MAXFWDIDX-STOPSPD)/24 ish
cmp.w #24,d3
ble.s 2$
move.w #24,d3
2$: move.l #(SPEEDX*65536)+SPEEDY+24,d0
move.l #(SPEEDW*65536),d1
sub.w d3,d0
move.w d3,d1
swap d0
swap d1
bsr rectfill
bra.s speedone
;Moving backwards so we need to draw the -VE rectangle ---------------
0$: asr.w #3,d3
move.l #((SPEEDY+24)*65536)+SPEEDX,d0
move.l #(SPEEDW*65536),d1
neg.w d3
move.w d3,d1
swap d1
move.l #SPEEDOCOL2,d2
bsr rectfill
speedone:
;---------------------------------------------------------------------
;Calculate various bits for the altimeter which is displayed later on
move.w plrthrust(a6),d1
ext.l d1
move.l d1,d0
swap d0
eor.w #240,d0 ;240 / -239
lsl.w #2,d1 ;speed x 4
add.w d0,d1 ;plus a minimum
move.w obj.ya(a4),d0
bsr polar2cart
add.w obj.x(a4),d0
add.w obj.z(a4),d1
bsr exactheight ;get ground height
cmp.w #ALTMAXHT,d0
ble.s 0$
move.w #ALTMAXHT,d0
0$: lsr.w #4,d0
move.w d0,altgndht(a6) ;store for later use
;---------------------------------------------------------------------
;Generate a number of 'arcade' strings to appear over the action later.
move.l plr.score(a4),d0
cmp.l lastscore(a6),d0
beq.s scoredone ;don't convert score unecessarily
move.l d0,lastscore
lea plr.score(a4),a1
lea HUDscorestr(a6),a0
PUSH a0
bsr bcdtoa ;generate score string
POP a0
bsr stripzeros ;strip leading zeros
scoredone:
sub.w d0,d0
move.b plr.lives(a4),d0
cmp.b #100,d0 ;show 99 lives maximum
bcs.s 0$
move.b #99,d0
0$: lea HUDlifestr+1(a6),a0
PUSH a0
bsr utoa2
POP a0
bsr stripzeros ;ensure pod message correct!
;Generate a time string if this is a bonus level. Display it later.
move.w ingameflag(a6),d0
ble.s notbonus
bset.b #DISP_BONUS,hudflags(a6) ;flag display
lsr.w #3,d0 ;divide by 8
lea HUDbonusstr(a6),a0
bsr utoa3 ;convert to string
lea HUDbonusstr(a6),a0
bsr stripzeros ;remove leading zeros
DOMSG MSG_SECRET
bra.s noinworld
notbonus:
;Inform the player how many hostages there are in the world periodically.
move.b LOWWORD+LOWBYTE+gloopcount(a6),d0
and.b #15,d0
bne.s noinworld ;update remaining count periodically
move.w remhostages(a6),d0
lea HUDinworld+15+4(a6),a0
PUSH a0
bsr utoa2
POP a0
bsr stripzeros
DOMSG MSG_INWORLD ;issue high priority 'PODS ..'
noinworld:
;=====================================================================
;Very important message display code for the text window in HUD centre
move.w visualtime(a6),d0
beq.s 0$
subq.w #1,d0
move.w d0,visualtime(a6)
0$: bne.s 1$ ;if time zero, we can change msg
move.w visualnxtpri(a6),d0
beq.s 1$ ;no message in queue!
;New message needs displaying. Update current info + ensure of update.
move.w d0,visualcurpri(a6) ;this is new priority
clr.w visualnxtpri(a6) ;start accumulating again
move.l visualnxtptr(a6),a0
tst.b (a0)+
beq.s 2$
PLAYSFX SFX_MESSAGEUP ;play sound effect
2$: move.b (a0)+,visualtime+LOWBYTE(a6) ;store time away
move.l a0,visualmsgptr(a6) ;ptr to string
addq.w #3,visualmsgnum(a6) ;force update
1$:
;Check if we are displaying the correct message at the moment or not.
move.w visualmsgnum(a6),d0
cmp.w msgnum(a3),d0
beq.s portarrow
move.w d0,msgnum(a3) ;correct message on display?
;We are not, so clear the background and centre the required message.
move.l #(TEXTWINY*65536)+TEXTWINX,d0
move.l #(TEXTWINH*65536)+TEXTWINW,d1
move.l #BACKGNDCOL,d2
bsr rectfill ;clear to background colour
tst.w visualcurpri(a6)
beq.s portarrow ;no message, so just clear
move.l fonth(a6),a0
SET_FONT a0 ;small HUD font
move.l visualmsgptr(a6),a0
bsr strwidth
exg d0,d1 ;pixel width into d1
lsr.w #1,d1 ;/2
move.l #(TEXTWINY*65536)+TEXTWINX+TEXTWINW/2,d0
sub.w d1,d0
move.l visualmsgptr(a6),a0
PUSHM <a3/a4>
bsr ptext
POPM <a3/a4>
;------------------------------------------------------------------
;Put up an arrow to the portal if one exists (No blob for this one)
portarrow: tst.w portalflag(a6)
beq.s swaphud
move.l mainobject(a6),a1
move.l portalptr(a6),a4
lea arrowa(a6),a0
bsr calcArrow
bset.b #DISP_ARROW,hudflags(a6)
;=================================================================
;Before we return, swap HUD's. Works because game slower than 50Hz
swaphud: lea hudptrF(a6),a0
move.l (a0)+,d0 ;front HUD
move.l (a0),a1 ;back HUD
move.l d0,(a0)
move.l a1,-(a0) ;front swapped with back
move.l obbase(a1),d0 ;ptr to actual HUD data
;If the player is dead, animate the panel exploding ------------------
move.l mainobject(a6),a4
cmp.l #movedormant,obj.mover(a4)
bne.s 0$
move.w hudexpcnt(a6),d0
move.w d0,d1
lsl.w #2,d0
lea hudexptable,a4
move.l (a4,d0.w),d0
cmp.w #7,d1
bge.s 1$ ;count 0 thru 7
addq.w #1,hudexpcnt(a6)
bra.s 1$
;Player not dead so swapping as normal -------------------------------
0$: clr.w hudexpcnt(a6)
1$:
IFEQ NEWOBJS
lea obj_list_buffer+96,a0
ENDC
IFNE NEWOBJS
lea obj_list_buffer+32,a0
ENDC
bra set_obj_dptr ;set new data ptr
;
;---------------------------------------------------------------------
;=====================================================================
;This routine displays (using 68000 and BLITTER) information which was
;calculated earlier but could not be used (CyberMorph landscape would
;over-write strings etc).
;
;ON ENTRY:
;CURRUPTED: just about everything
;EXIT:
displayStatus: move.l fontl(a6),a0
SET_FONT a0 ;select large font for text
;Display the radar blobs irrespective of whether the arrow is required.
move.l mainobject(a6),a0
cmp.l #moveplayer,obj.mover(a0)
bne 3$
btst.b #PFBIT.jammed,LOWBYTE+plr.flags(a0)
beq.s 0$
move.w gloopcount+LOWWORD(a6),d0
and.w #$01ff,d0
bne.s 5$
DOMSG MSG_JAMMED ;message every 512 game cycles
bra.s 5$
0$: bsr displayScanner ;display scanner
;Decide whether or not to display the arrow (for portal or PODS).
btst.b #DISP_ARROW,hudflags(a6)
beq.s 1$
move.l #ARROWCOLOUR1,d2
lea arrowa(a6),a0
bsr displayArrow
1$:
;Display the other arrow (POLLUTANT tower arrow) if required now.
btst.b #DISP_POLLUTANT,hudflags(a6)
beq.s 5$
move.l #ARROWCOLOUR2,d2
lea arrowb(a6),a0
bsr displayArrow
move.l arrowb+DWORD(a6),d0
move.l arrowb+DWORD*2(a6),d1
move.l #ARROWCOLOUR2,d2
bsr drawline
5$:
;Display an Altimeter so that the player knows how deep they're in.
move.l #((ALTIMETERX+1)*65536)+ALTIMETERY+ALTIMETERH,d0
move.l #((ALTIMETERW-2)*65536),d1
move.w altgndht(a6),d1
sub.w d1,d0
swap d1
swap d0
move.l #ALTCOLOUR2,d2
bsr rectfill
move.l mainobject(a6),a0
move.l #((ALTIMETERX+3)*65536)+ALTIMETERY+ALTIMETERH,d0
move.l #((ALTIMETERW-6)*65536),d1
move.w obj.y(a0),d1
lsr.w #4,d1
cmp.w #ALTIMETERH,d1
ble.s 6$
move.w #ALTIMETERH,d1
6$: sub.w d1,d0
swap d1
swap d0
move.l #ALTCOLOUR1,d2
bsr rectfill
move.l #(ALTIMETERY*65536)+ALTIMETERX,d0
move.l #($0001*65536)+ALTIMETERW,d1
move.l #$88ff88ff,d2
bsr rectfill
move.l #((ALTIMETERY+ALTIMETERH)*65536)+ALTIMETERX,d0
move.l #($0001*65536)+ALTIMETERW,d1
move.l #$88ff88ff,d2
bsr rectfill
3$:
;Display 'arcade' like strings over the play area now. Score + lives.
lea HUDscorestr(a6),a0
move.l #$001800B8,d0
bsr rightjustify ;player score top centre ish
;NEW. If the holographic head is up, do not display any lives for now.
tst.w audiocurpri(a6)
bne.s 2$ ;holographic head up?
lea HUDlifestr(a6),a0
move.l #$00180014,d0
bsr ptext ;remaining ship count
2$:
;Display a timer string if this is a bonus level - 'get out time'.
btst.b #DISP_BONUS,hudflags(a6)
beq.s 4$
lea HUDbonusstr(a6),a0
move.l #$00B00000,d0
bsr centretext
cmp.w #1,bonuslvlflg(a6)
ble.s 4$
subq.w #1,bonuslvlflg(a6)
lea secretstr,a0
move.l #$00900000,d0
bra centretext ;'SECRET LEVEL' message
;Check for 'DEMO' message --------------------------------------------
4$: tst.w demoflag(a6)
beq.s 9$
move.b LOWWORD+LOWBYTE+gloopcount(a6),d0
and.b #8,d0
beq.s 9$
lea demostr,a0
move.l #$00900000,d0
bra centretext ;'DEMO' message
9$: rts
;
;---------------------------------------------------------------------
;=====================================================================
;This routine runs through all the 3D objects in the world deciding
;what to plot on the short-range scanner. The scanner should be used
;for objects behind the player!
;
;ON ENTRY:
;CORRUPTED: D0-D7, A0-A4
;ON EXIT:
calcScanner: lea radarlist(a6),a0 ;destination list
move.l objlist(a6),a1
move.w numobj(a6),d7
subq.w #1+2,d7 ;for dbra + player + sights
bmi dunradar ;exit if none
lea DWORD*2(a1),a1 ;skip player + sights
lea sinetable,a4
move.l mainobject(a6),a2
move.l obj.collcell(a2),d0
rsrchl: move.l (a1)+,a3
move.w obj.sframe(a3),d6
bne.s 0$
dbra d7,rsrchl
bra dunradar ;finished
;Found potential candiate for the scanner - investigate some more.
0$: move.l d0,d1
and.l obj.collcell(a3),d1
bne.s 1$
dbra d7,rsrchl
bra dunradar ;finished
;Potentially within range - calculate approximate distance and angle.
1$: move.w obj.x(a3),d1
move.w obj.z(a3),d2
DISTANCE d1,d2,obj.x(a2),obj.z(a2),<bra.s gotdist>
gotdist: cmp.w #WORLDDIST,d1
bcs.s 0$
dbra d7,rsrchl
bra dunradar ;finished
;Definitely within range - calculate the angle to the object + insert.
0$: move.w obj.x(a3),d2
move.w obj.z(a3),d3
CALCANGLE d2,d3,obj.x(a2),obj.z(a2),<bra gotvect>
gotvect: sub.w obj.ya(a2),d2
add.w d2,d2 ;WORD sized table
and.w #(MASK360*2),d2 ;mask out angle
move.w (a4,d2.w),d3 ;sin(angle)
muls d1,d3
swap d3
asr.w #(14+SCALESHIFT-16),d3 ;FIXEDPTSHIFT + SCALESHIFT (22 bits)
add.w #RADARX,d3
add.w #ANGLE90*2,d2
move.w (a4,d2.w),d4 ;cos(angle)
muls d1,d4
asr.l #(14+SCALESHIFT-16),d4 ;FIXEDPTSHIFT + SCALESHIFT - 16
move.l #(RADARY*65536),d2
sub.l d4,d2
move.w d3,d2 ;D2 contains coordinates now
move.l d2,(a0)+ ;store coordinates away
move.w d6,(a0)+ ;store frame number away
dbra d7,rsrchl
;Mark the end of the scanner list. Check for specific types present?
dunradar: move.l a0,radarptr(a6) ;end of the radar plot list
move.b #$ff,d0
lea radarlist+DWORD(a6),a1
cmp.l a0,a1
bcc.s 0$ ;nothing in the list!
1$: move.w (a1),d1
cmp.b #HOSTAGEBLOB,d1
bne.s 2$
and.b #$0f,d0
beq.s 9$ ;both types present in list
2$: cmp.b #POLLUTEBLOB,d1
bne.s 3$
and.b #$f0,d0
beq.s 9$ ;both types present in list
3$: lea DWORD+WORD(a1),a1
cmp.l a0,a1
bcs.s 1$
;Either HOSTAGES or POLLUTANT towers are not present - find nearest!
0$: btst #0,d0
beq.s 4$ ;no pollutant required!
lea powerlist(a6),a0
move.l powerptr(a6),a2
cmp.l a0,a2
beq.s 4$ ;none in the list
PUSH d0
bsr getnearest
lea arrowb(a6),a0
bsr calcArrow
bset.b #DISP_POLLUTANT,hudflags(a6)
POP d0
4$: tst.w portalflag(a6)
bne.s 9$ ;if portal exists DO THAT instead
btst #4,d0
beq.s 9$ ;no hostage required!
lea hostglist(a6),a0
move.l hostgptr(a6),a2
cmp.l a0,a2
beq.s 9$ ;none in the list
bsr getnearest
lea arrowa(a6),a0
bset.b #DISP_ARROW,hudflags(a6)
bra calcArrow
9$: rts
;
;---------------------------------------------------------------------
;=====================================================================
;This routine obtains the nearest of a given type (currently HOSTAGES
;and POLLUTANTS). This routine is only called if there are none of the
;required type on the scanner!
;
;ON ENTRY: A0 ptr to list, A2 list end
;CORRUPTED: A1, A3, A4
;ON EXIT: A4 is ptr to nearest object of given type, A1 to player
getnearest: move.l mainobject(a6),a1
move.w #$ffff,d7
nrsrch: move.l (a0)+,a3
move.w obj.x(a3),d1
move.w obj.z(a3),d2
QUICKDIST d1,d2,obj.x(a1),obj.z(a1),<bra.s nrdist>
nrdist: cmp.w d7,d1
bcc.s 0$
lea (a3),a4 ;new minimum
move.w d1,d7 ;new minimum
0$: cmp.l a2,a0
bcs.s nrsrch ;loop until we reach end
rts
;
;---------------------------------------------------------------------
;=====================================================================
;This routine is used to calculate the 3 vertices of an arrow plotted
;when the nearest POD is out of scanner range or when the portal has
;been created.
;
;ON ENTRY: A1 points to player struct, A4 points to subject of arrow
;CORRUPTED: D0, D1, D2, D3, D4, A2
;ON EXIT: relevant bit has been set in HUDFLAGS
calcArrow: move.w obj.x(a4),d0
move.w obj.z(a4),d1
move.w obj.x(a1),d2
move.w obj.z(a1),d3
bsr getangle ;angle to nearest hostage
sub.w obj.ya(a1),d0 ;angle between player + hostage
;Using the above calculated angle, draw a large arrow to the survivor
lea sinetable,a1 ;sine table
lea ANGLE90*2(a1),a2 ;cosine table
add.w d0,d0
and.w #(MASK360*2),d0 ;angle of pointy bit
move.w (d0.w,a2),d4
muls #-POINTASZ,d4
FIXEDPTSHIFT d4 ;-cos(theta)*POINTASZ
add.w #RADARY+2,d4 ;about centre, Ycoord into D4
move.w (d0.w,a1),d3
muls #POINTASZ,d3
FIXEDPTSHIFT d3 ;sin(theta)*POINTASZ
add.w #RADARX+2,d3 ;about centre, Xcoord into D3
move.w d4,d1
swap d1
move.w d3,d1
move.l d1,(a0)+ ;first pair of coordinates
add.w #POINTBTHETA,d0 ;angle for B pointy bit
and.w #(MASK360*2),d0
move.w (d0.w,a2),d1
muls #-POINTABCSZ,d1
FIXEDPTSHIFT d1 ;-cos(theta)*POINTBCSZ
add.w d4,d1
swap d1
move.w d3,d1 ;Ycoord into top, centre X lower
move.w (d0.w,a1),d2
muls #POINTABCSZ,d2
FIXEDPTSHIFT d2 ;sin(theta)*POINTBCSZ
add.w d2,d1
move.l d1,(a0)+ ;second pair of coordinates
add.w #POINTCTHETA-POINTBTHETA,d0 ;angle for C pointy bit
and.w #(MASK360*2),d0
move.w (d0.w,a2),d1
muls #-POINTABCSZ,d1
FIXEDPTSHIFT d1 ;-cos(theta)*POINTBCSZ
add.w d4,d1
swap d1
move.w d3,d1 ;Ycoord into top, centre X lower
move.w (d0.w,a1),d2
muls #POINTABCSZ,d2
FIXEDPTSHIFT d2 ;sin(theta)*POINTBCSZ
add.w d2,d1
move.l d1,(a0) ;final pair of coordinates
rts
;
;---------------------------------------------------------------------
;=====================================================================
;This routine displays the results of calcScanner. The process has
;been split for the purposes of speeding up the game. As this process
;uses the BLITTER we must wait for it to become free and use it as
;fast as we possibly can.
;
;ON ENTRY:
;CURRUPTED: just about everything
;EXIT:
displayScanner: move.l scannerdef(a6),a0
move.l #((RADARY-31)*65536)+RADARX-31,d0
sub.w d1,d1
bsr plotgrobject
move.l scannerdef(a6),a0
move.l #((RADARY-31)*65536)+RADARX-31,d0
moveq #1,d1
bsr plotgrobject
;Plot any and all objects in the detection zone on the scanner now.
lea radarlist(a6),a2
move.l radarptr(a6),a3 ;end of list
cmp.l a3,a2
bcc.s 9$
0$: move.l radardef(a6),a0 ;pointer to sprite
move.l (a2)+,d0 ;coords
move.w (a2)+,d1 ;frame number
bsr plotgrobject
cmp.l a3,a2
bcs.s 0$ ;loop until it is finished
9$: rts
;
;---------------------------------------------------------------------
;=====================================================================
;Draw an arrow when required to. This will happen if there are no PODs
;in scanner distance (but there are in the world) or if the portal
;exists in the world.
;
;ON ENTRY: D2.l is CRY colour, A0 is ptr to arrow coord block
;CORRUPTED: just about everything!
;ON EXIT:
displayArrow: move.l (a0),d0
move.l DWORD(a0),d1
PUSHM <a0/d2>
bsr drawline
POPM <a0/d2>
move.l (a0),d0
move.l DWORD*2(a0),d1
bra drawline
;
;---------------------------------------------------------------------
;=====================================================================
;Convert a Binary Coded Decimal number to ASCIIZ ready for displaying.
;
;ON ENTRY: A0=ptr to string space, A1=ptr BCD number (DWORD)
;CORRUPTED: A1
;EXIT:
bcdtoa: move.b #'0',d2
move.b (a1)+,d0
move.b d0,d1
lsr.b #4,d0
and.b #$f,d1
add.b d2,d0
add.b d2,d1
move.b d0,(a0)+
move.b d1,(a0)+
move.b (a1)+,d0
move.b d0,d1
lsr.b #4,d0
and.b #$f,d1
add.b d2,d0
add.b d2,d1
move.b d0,(a0)+
move.b d1,(a0)+
move.b (a1)+,d0
move.b d0,d1
lsr.b #4,d0
and.b #$f,d1
add.b d2,d0
add.b d2,d1
move.b d0,(a0)+
move.b d1,(a0)+
move.b (a1)+,d0
move.b d0,d1
lsr.b #4,d0
and.b #$f,d1
add.b d2,d0
add.b d2,d1
move.b d0,(a0)+
move.b d1,(a0)+
clr.b (a0)
rts
;
;---------------------------------------------------------------------
;=====================================================================
;Strip leading zeros from a string. To do this it scrolls the string
;down. Bugfix to ensure that if the string consists entirely of zeros
;we leave at least one!
;
;ON ENTRY: A0 points to the string
;CORRUPTED:
;ON EXIT:
stripzeros: lea (a0),a1
0$: cmp.b #'0',(a1)+
beq.s 0$
lea -1(a1),a1
cmp.b #0,(a1)
bne.s 1$
lea -1(a1),a1
1$: move.b (a1)+,(a0)+
bne.s 1$
rts
;
;---------------------------------------------------------------------
ENDCODE
END