Skip to navigation

Ship hangar: HAS1

[BBC Master version]

Name: HAS1 [Show more] Type: Subroutine Category: Ship hangar Summary: Draw a ship in the ship hangar
Context: See this subroutine in context in the source code Variations: See code variations for this subroutine in the different versions References: This subroutine is called as follows: * HALL calls HAS1

The ship's position within the hangar is determined by the arguments and the size of the ship's targetable area, as follows: * The x-coordinate is (x_sign x_hi 0) from the arguments, so the ship can be left of centre or right of centre * The y-coordinate is negative and is lower down the screen for smaller ships, so smaller ships are drawn closer to the ground (because they are) * The z-coordinate is positive, with both z_hi (which is 1 or 2) and z_lo coming from the arguments
Arguments: XX15 Bits 0-7 = Ship's z_lo Bit 0 = Ship's x_sign XX15+1 Bits 0-7 = Ship's x_hi Bit 0 = Ship's z_hi (1 if clear, or 2 if set) XX15+2 Non-zero = Ship type to draw 0 = Don't draw anything
.HAS1 JSR ZINF \ Call ZINF to reset the INWK ship workspace and reset \ the orientation vectors, with nosev pointing out of \ the screen, so this puts the ship flat on the \ horizontal deck (the y = 0 plane) with its nose \ pointing towards us LDA XX15 \ Set z_lo = XX15 STA INWK+6 LSR A \ Set the sign bit of x_sign to bit 0 of A ROR INWK+2 LDA XX15+1 \ Set x_hi = XX15+1 STA INWK LSR A \ Set z_hi = 1 + bit 0 of XX15+1 LDA #1 ADC #0 STA INWK+7 LDA #%10000000 \ Set bit 7 of y_sign, so y is negative STA INWK+5 STA RAT2 \ Set RAT2 = %10000000, so the yaw calls in HAL5 below \ are negative LDA #&0B \ Set the ship line heap pointer in INWK(34 33) to point STA INWK+34 \ to &0B00 JSR DORND \ We now perform a random number of small angle (3.6 STA XSAV \ degree) rotations to spin the ship on the deck while \ keeping it flat on the deck (a bit like spinning a \ bottle), so we set XSAV to a random number between 0 \ and 255 for the number of small yaw rotations to \ perform, so the ship could be pointing in any \ direction by the time we're done .HAL5 LDX #21 \ Rotate (sidev_x, nosev_x) by a small angle (yaw) LDY #9 JSR MVS5 LDX #23 \ Rotate (sidev_y, nosev_y) by a small angle (yaw) LDY #11 JSR MVS5 LDX #25 \ Rotate (sidev_z, nosev_z) by a small angle (yaw) LDY #13 JSR MVS5 DEC XSAV \ Decrement the yaw counter in XSAV BNE HAL5 \ Loop back to yaw a little more until we have yawed \ by the number of times in XSAV LDY XX15+2 \ Set Y = XX15+2, the ship type of the ship we need to \ draw BEQ HA1 \ If Y = 0, return from the subroutine (as HA1 contains \ an RTS) TYA \ Set X = 2 * Y ASL A TAX LDA XX21-2,X \ Set XX0(1 0) to the X-th address in the ship blueprint STA XX0 \ address lookup table at XX21, so XX0(1 0) now points LDA XX21-1,X \ to the blueprint for the ship we need to draw STA XX0+1 BEQ HA1 \ If the high byte of the blueprint address is 0, then \ this is not a valid blueprint address, so return from \ the subroutine (as HA1 contains an RTS) LDY #1 \ Set Q = ship byte #1 LDA (XX0),Y STA Q INY \ Set R = ship byte #2 LDA (XX0),Y \ STA R \ so (R Q) contains the ship's targetable area, which is \ a square number JSR LL5 \ Set Q = SQRT(R Q) LDA #100 \ Set y_lo = (100 - Q) / 2 SBC Q \ LSR A \ so the bigger the ship's targetable area, the smaller STA INWK+3 \ the magnitude of the y-coordinate, so because we set \ y_sign to be negative above, this means smaller ships \ are drawn lower down, i.e. closer to the ground, while \ larger ships are drawn higher up, as you would expect JSR TIDY \ Call TIDY to tidy up the orientation vectors, to \ prevent the ship from getting elongated and out of \ shape due to the imprecise nature of trigonometry \ in assembly language JMP LL9 \ Jump to LL9 to display the ship and return from the \ subroutine using a tail call .HA1 RTS \ Return from the subroutine