Skip to navigation


Ship hangar: HAS1

[BBC Micro disc version, Docked]

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) \ We now work our way through the ship blueprints table \ for the hangar, counting valid blueprints until we \ have found the Y-th valid blueprint (we do this as the \ hangar blueprint table at XX21 is not fully populated, \ so the Y-th ship is not necessarily at position Y) LDX #4 \ We can start looking from ship blueprint 3, because we \ don't show ship 1 (missile) or ship 2 (space station) \ in the hangar. Setting X to 4, which then gets \ incremented to 6, will start us at XX21(5 4), which is \ the address of ship blueprint 3 (escape pod) .hloop INX \ Increment X by 2 to point to the next blueprint in the INX \ table 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 hloop \ If the high byte of the blueprint address is 0, then \ the blueprint for this ship is not available, so jump \ back to hloop to try the next ship along in the table DEY \ We have found a valid blueprint, so decrement the ship \ number that we are looking for in Y BNE hloop \ If Y is not yet zero, we still haven't found the Y-th \ valid blueprint, so loop back to hloop to try the next \ ship along in the table 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