the cutting room mirror

HUD

This article has a talk page!
view on tcrf.net

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