If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!
Development:Cybermorph/HUD
Jump to navigation
Jump to search
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