[Question]
  [
Growing up, my first console game system was an Atari 2600 and I will always have a love for some of those games I so enjoyed as a child. Many of the graphics are still memorable, perhaps even iconic.
It turns out that these sprites are very simplistic bitmaps, 8 pixels wide with variable height where the binary representation is the arrangement of the pixels.
For example, the hex bytes 0x18, 0x24, 0x18 would draw a crude circle like so:
```
0x18: 00011000
0x24: 00100100
0x18: 00011000
```
As 8 pixels wide creates fairly small graphics (even by Atari 2600 standards) it was common to double or quadruple either the height, width or both to create a larger (though more blocky and distorted) version of the same image. They would commonly also be flipped vertically or horizontal for both player sprites and playfields. The game *Combat* is a good example of this.
The challenge is, to write code to display these sprites as "graphics" in ASCII form including the ability to stretch or flip them vertically, horizontally or both. This must be in the form of either a full program, or callable function.
## Input:
* An array of bytes, each representing the horizontal bits for that line.
* A non-zero integer value for each direction, horizontal and vertical representing the scaling factor for that dimension.
* A negative value indicates that the dimension should also be flipped along it's axis.
## Output:
* ASCII representation to STDOUT or a newline-separated string, using a space character for black (0) pixels and any printable, non-space character of your choice for white (1) pixels.
## Test data:
```
bmp1 = [ 0x06, 0x0F, 0xF3, 0xFE, 0x0E, 0x04, 0x04, 0x1E, 0x3F, 0x7F, 0xE3, 0xC3, 0xC3, 0xC7, 0xFF, 0x3C, 0x08, 0x8F, 0xE1, 0x3F ]
bmp2 = [ 0x07, 0xFD, 0xA7 ]
bmp3 = [ 0x00, 0x8E, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0x00 ]
bmp4 = [ 0x00, 0xFC, 0xFC, 0x38, 0x3F, 0x38, 0xFC, 0xFC]
```
Note: Above example input arrays of bytes are provided as hex. If your platform does not accept hex literals for byte representation you may convert them to a native byte-equivalent literal.
## Example Output:
```
f( bmp1, 1, 1 ) =>
--------
     XX 
    XXXX
XXXX  XX
XXXXXXX 
    XXX 
     X  
     X  
   XXXX 
  XXXXXX
 XXXXXXX
XXX   XX
XX    XX
XX    XX
XX   XXX
XXXXXXXX
  XXXX  
    X   
X   XXXX
XXX    X
  XXXXXX
--------
f( bmp1, -2, 1 ) =>
----------------
  XXXX          
XXXXXXXX        
XXXX    XXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXX        
    XX          
    XX          
  XXXXXXXX      
XXXXXXXXXXXX    
XXXXXXXXXXXXXX  
XXXX      XXXXXX
XXXX        XXXX
XXXX        XXXX
XXXXXX      XXXX
XXXXXXXXXXXXXXXX
    XXXXXXXX    
      XX        
XXXXXXXX      XX
XX        XXXXXX
XXXXXXXXXXXX    
----------------
f( bmp2, 1, 2 ) =>
--------
     XXX
     XXX
XXXXXX X
XXXXXX X
X X  XXX
X X  XXX
--------
f( bmp2, 2, 1 ) =>
----------------
          XXXXXX
XXXXXXXXXXXX  XX
XX  XX    XXXXXX
----------------
f( bmp2, -2, -2 ) =>
----------------
XXXXXX    XX  XX
XXXXXX    XX  XX
XX  XXXXXXXXXXXX
XX  XXXXXXXXXXXX
XXXXXX          
XXXXXX          
----------------
f( bmp3, 1, -1 ) =>
--------
    XXX 
     X  
XXXXXXXX
XXXXXXXX
X    X  
X   XXX 
--------
f( bmp3, 3, 3 ) =>
------------------------
XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX            XXX      
XXX            XXX      
XXX            XXX      
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
               XXX      
               XXX      
               XXX      
            XXXXXXXXX   
            XXXXXXXXX   
            XXXXXXXXX   
------------------------
f( bmp4, -1, -1 ) =>
--------
  XXXXXX
  XXXXXX
   XXX  
XXXXXX  
   XXX  
  XXXXXX
  XXXXXX
--------
f( bmp4, 4, 2 ) =>
--------------------------------
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
--------------------------------
```
Note: the horizontal lines above and below are to show the beginning and end of the output. They are not required in the output, however empty lines (represented by all zeros/spaces) at the beginning and/or end are required, as shown.
Note 2: these test bitmaps were inspired by and re-drawn/coded based on game screenshots tagged as "fair use" on Wikipedia.
## Winning Criteria
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code in bytes per language wins.
* Standard [loopholes](http://meta.codegolf.stackexchange.com/q/1061/42963) are forbidden.
  
[Answer]
# [Python 2](https://docs.python.org/2/), 117 bytes
```
def f(m,w,h):
 for r in m[::cmp(h,0)]:print(''.join(' X'[1<<i&r>0]*abs(w)for i in range(8)[::cmp(0,w)])+'\n')*abs(h),
```
[Try it online!](https://tio.run/##bZBRa4MwFIXf8yvu05JscUQTpkg3GK7@hoHLQ7vVasEoruD2611zU7GrhfgRzj3nekj3e6xaG43j166EkjViEBVPCZRtDz3UFpoiTT@bjlVCcpN2fW2PjNLHQ1tbRuGdFuFqVd/1L9Lcb7bfbOAuWbtkv7H7HUv4eYEUAzf8gX5YytFacTFumy6EZyhA/sgn4Zg75gq5RsVTzwxRUeiMkWv0Z5eMcQNOVYbZxDHx/tBvAENODaKpgc@8Ob7GfqammcQ0/jnR827PczvfVPqk/pfMs5kqmfv7@zQ1hJQM3KMIcAc4wRef1SBayhGao6V62xvgd6Ur3BGES9mdK1U75w33SdcXRcY/ "Python 2 – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~27~~ 26 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»
```
Takes the input as a list of 8-bit binary-strings, and outputs with `1` as non-space character.
-1 byte thanks to *@MagicOctopusUrn*.
[Try it online](https://tio.run/##yy9OTMpM/f//3NbgQ5sOtxye7nVo8@GWCzsObTJ41LAz8/Da2EObwayg2tNzDA5vsDq0@///aCUDEDA0NFDSUVCCMA0NQWwQDeLB2IaoauBsA6AqLGwk9RDNYLYhgg02Hm6@AW62IYobDBFmIuwFKQOrQXU/WArFDbFcusZcukYA) or [verify all test cases](https://tio.run/##yy9OTMpM/W9o5ubpGeoZ9v/c1uCIwy2Hp3tFHm65sCPC4FHDzszDa2trI8GsoNrTcwwOb7A6tPu/jrquqcHh6Ye26R3eofM/WskABAwNDZR0FJQgTENDEBtEg3gwtiGqGjjbAKgKCxtJPUQzmG2IYIONh5tvgJttiOIGQ4SZCHtBysBqUN0PlkJxQyyXIRCOOE/rGiH7GslkiEpDA0OIOCh4jIhTSLSJQLt14WaiOhnOhgWhIWpQIXkdNchRogJkJsjhuoa0t8UYCNEsMUTECjIbot0AMzUgiWPVGwvyCKZfqG@NCbFRbchlTmRUm8MdDrVcCRyghlAmVBQpE@JXZgRzIX5lpkBIlKVEKdM1BXoCAA).
**Explanation:**
```
ε         # Map the (implicit) input-list to:
 S        #  Convert the binary-String to a list of characters
  ²Ä      #  Take the absolute value of the second input
    ×     #  And repeat each character that many times
     J    #  And then join it back together to a single string again
 ³Ä       #  Take the absolute value of the third input
   и      #  Repeat that string as a list that many times
 ²0‹i     #  If the second input is negative:
     í    #   Reverse each string in the list
]         # Close both the if-statement and (outer) map
³0‹i }    # If the third input is negative:
    R     #  Reverse the list of lists
      ˜   # Flatten the list of lists to a list of strings
0ð:       # Replace all 0s with spaces " "
   »      # And join the strings by newlines (which is output implicitly)
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~24~~ 19 bytes
```
B,!i|1&Y"2M0<?XP]Zc
```
Inputs are an array of decimal numbers, horizontal scale, vertical scale.
[Try it online!](https://tio.run/##y00syfn/30lHMbPGUC1SycjXwMY@IiA2Kvn//2gzBSAwNAUSRibGINLUBCwCJhWQSGMDEGkGUmNoZA5SCSYNLU2RSEuwCaZglWD1ChZgw8AmG0HEjWO5dI24DAE)
### Explanation
```
B        % Implicit input: array of numbers. Convert to binary. Gives a zero-one
         % matrix, each row containing the binary expansion of a number
,        % Do twice
  !      %   Transpose
  i      %   Input: number
  |      %   Absolute value
  1&Y"   %   Repeat each row that many times
  2M     %   Push the latest input again
  0<     %   Is it negative?
  ?      %   If so:
    XP   %     Flip vertically
  ]      %   End
  Zc     %   Convert each nonzero into '#'. Zeros are displayed as space
         % Implicit end. Implicit display
```
[Answer]
# Dyalog APL, ~~46~~ ~~42~~ 33 bytes
```
' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]
```
[Try it online!](https://tio.run/##fY/BSsNAEIbv@xQLHraFluxmQ7MnoaQJPoIgHirSIlTaq9ReFLQurHhRvKuQmwfx4jGPMi8SZ6YuloIG8m1m//@fmYwXs/7pxXg2n7Zw/3g2h5sHLWB9KyetknvqCMId@Osl@CcILx29D@GrS3fhM4FQX2K5SjDYA3@FB/hXvHVJetxiD3FQHkpsKJdmAP6tqTtoGfUQwy6snyF8NDU2WomT84VhIwWUHihEhagsoaSSkUUYKi1ZckJJvuIXOcVIsAUlHMKxz2xiNDDdGsj@EWKYs2a3NE1hGuey2JWxWYbX0hzKdkJVEWFd3Ja/otBO@MeFkUao/s6jxI/avKf/6Cnr@P7psMJK@w0 "APL (Dyalog Unicode) – Try It Online")
-9 thanks to ngn!
[Answer]
# [Prolog (SWI)](http://www.swi-prolog.org), 252 bytes
```
N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).
```
[Try it online!](https://tio.run/##XZLdasJAEIXvfQrvzK4T82drqEqJmw1etKsmEZQ0AaG2FFoVLW0vpK9uZ2crSlg47M53zswEsttv37ev9uH77XRSbdlO72w18CAdFmVf2R5WMv2Qx6zsNBSXHA3pUIIkw8CF/fprvT@sLQkJA1vxhKf9YnzMSzSp9hjjiud8Dqvdbr15tjKYQ8qwlSOd61mWHCiIMZMMA7@PF1vp6w0D5fhO7AhtS44Ct6Du1aJaVtjA80Nn7ESw4BEfwZIXheceR2XJxXmigJiBleMQbBH3c0pmZxoDfh9jndO9HQ2Lpvvj3oLWRGsSkEqqGO1e1KNKQM4eqSS/uNYedSAaCMqGWkPj90yHZgmNkZlu/LHWqKfrwtRdStHEsHvpafR/K7Ohq1PxVSoRFw3Cy87mfqY6FVUengd42e4/Vp9W6/fwtGlB8VAyzSzbZ4gf6/hR4xESv1J1pgzzkU7qbGIYtSWZ1h1T7RCYtWyPVbM6nhkc4EnrLNUsNkGSrO7IjKOLy@V1lpf4R/wB "Prolog (SWI) – Try It Online")
### Explanation
```
N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].   Make `R` a list containing `E` repeated `N` times
       N<1,R=[]                    If `N<1`, let `R` be the empty list
       N-1+E+S                     Else recurse with `N-1`, `E` and `S`
           R=[E|S]                 Let `R` be a new list with `E` as head and `S` as tail
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
                                   Let `R` be a list
                                   with each element in `E` repeated `N` times
                                   e.g. 2*[3, 6] -> [3, 3, 6, 6]
       R=E,E=[]                    Let `R` be `E` if `E` is the empty list
       N<0,reverse(E,F)            Else if `N<0`, let `F` be the reverse of `E`
           -N*F*R                  Recurse with `-N`, `F` and `R`
       [H|T]=E                     Else let `H` be the head and `T` be the tail of `E`
           N+H+S                   Let `S` be `N+H+S` (our function, not addition)
           N*T*U                   Recurse with `N`, `T` and `U`
           append(S,U,R)           let `R` be the concatenation of `S` and `U`
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
                                   Make `R` the binary representation of `E`
                                   with `N` as the value of the current bit
                                   where 0 and 1 are space and hash respectively
    N<1,R=[]                       If `N<1` let `R` be the empty list
    (
        E<N,D=E,F=32               If `E<N` the bit isn't set, so `D=E`, `F=space`
        D=E-N,F=35                 Else `D=E-N`, `F=hash`
    )
        N/2/D/C                    Recurse with `N/2`, `D` and `C`
        R=[F|C]                    Let `R` be a new list with `F` as head and `C` as tail
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).
                                   Make `R` the result,
                                   with inputs being the list `[H|T]`
                                   and the scales `X` and `Y`
   128/H/A                         Let `A` be the binary representation of `H` (8 bits)
   X*A*B                           Let `B` be `A` with each element repeated `X` times
   Y*[[10|B]]*C                    Let `C` be `B` with a newline prepended,
                                   repeated `Y` times
   append(C,D)                     Let `D` be `C` flattened by one level (joining lines)
   (
       T=[],R=D                    If `T` is empty, let `R` be `D` 
       T^X^Y^S                     Else recurse with `T`, `X`, `Y` and `S`
           append(D,S,R)           Let `R` be the concatenation of `D` and `S`
   )
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 28 bytes
```
ＦθＥ↔ζ⭆⮌↨ι²×§ Xμ↔ηＦ›η⁰‖Ｆ‹ζ⁰‖↓
```
[Try it online!](https://tio.run/##VY1Ni8IwFEX38yseXb1AhNbKVOzK8WMYUBCdxYB0ETtPW6itpkFl/nxMXhGdLM7i3Ptu8kLpvFGVtftGA54FrHRZG1yqE453Lf4JCRvj1MGbNV1It4QfyqGU0Bcu/i6P1OLYfNW/dMMAfgIJR@f9eSH8S994/FOTMqSxkBAKAWvaV5QbfMQLat1//7PRtLnWIrV2u4XwFr5Lz7nnPGbO2HQcPBmxibmZMGfcn7wy4QVO4wnfDj2HXT/qFiCT0OtLiDLbu1R3 "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｆθ
```
Loop over the list of bytes.
```
Ｅ↔ζ
```
Map over the vertical scaling factor, thus multiplying the output lines.
```
⭆⮌↨ι²×§ Xμ↔η
```
Convert the input to base 2, reverse it, map the digits to space and `X`, then multiply each character by the horizontal scaling factor.
```
Ｆ›η⁰‖
```
If the horizontal scaling factor was positive, reflect to get the image the correct way around again.
```
Ｆ‹ζ⁰‖↓
```
Reflect vertically if the vertical scaling factor was negative.
[Answer]
# [C (clang)](http://clang.llvm.org/), 120 bytes
```
k,w,l,_;f(*o,z,x,y){for(w=z*y;w;)for(k=w>0?z*y-w--:++w,_=l=8*x;_;putchar(_?o[k/y]>>(l>0?--l/x:7-++l/x)&1?88:46:10))_=l;}
```
[Try it online!](https://tio.run/##bVDdboIwGL3vUzReLK20sVCiDQ2axelLMEOcG5sRwRAdqPHZWfuhotNeHOA7P98pC75I59l3Xa9YyVIW64R0c3ZgFdvTY5IXpAwP3b0uNbUfq7AcipEZ8JLzwHFKFodpqLqVjvVmt138zAsSj/Jo1dvPhkOSGjHnaa8KBtxxzJO@uCOlAr8fuIJS49WnGi2zLf5Yb9zIEzMc4iMWlegzi1OLUwk4gUmDfosuTCQoB4AT0I9vcQAJwMoxeJVF1ejdJgGf9KWKF8kZPldpvG8WXwc3Ghmpq0YIiIMqym@XNXiu21QXNxG@jQjxTcR03KJU7c2a9wtrIxD6zZefOI4JPW4KE5iQDr@e96xD9QnBovV8mRGKjwglBP4z88wuc2kXU41sgL5juAcUvuc8JsHk/TcB4T1JA8KG8QePZArCuPuUMT75UMC3DH9qAso/d7MHm1N8bXdFhoVGJ1T/AQ "C (clang) – Try It Online")
[Answer]
# [Common Lisp](http://www.clisp.org/), 157 bytes
```
(lambda(l x y)(dolist(i(if(< y 0)(reverse l)l))(dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))(princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))(princ"
"))))
```
[Try it online!](https://tio.run/##bVDNboMwDL73KSx6mHNAggYNDrtMrLwH0FBlDYEBm@jTMzsMWNkun/D3Z4fS6L6dsFfDB1wnNHldXHI0MMJd4KUhdUCNusIXuEMgsFNfqusVGGEEGwZdqx7fMS96SmyMhWQbbk4eSW47bUuuM8210EM7N4/UbNGHGKwQWnhHzwNPiMXvHdwwUaGqPi1Uy300lLkxcIWZEPM7zBMex@AZCDKCTDKceXQQLRDyKNkSM5zZl24Qc4wFmXIiIUicL3QxIQ7zutqtc@43gtd4VaxTAg7yqiRaGh3Mh7iTgjXSrJEsXUAmy53u60fgSEUPDyH89Z8c5Z/2XE220576x0VJf@ezFPXDPSdBPlINmf74Goge1k7f "Common Lisp – Try It Online")
### Explanation
```
(lambda(l x y)                           ; Lambda with parameters `l`, `x`, `y`
    (dolist
        (i                               ; For `i` in the list  
            (if(< y 0)(reverse l)l)      ; The reverse of `l` if `y<0` else `l`
        )
        (dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))
                                         ; Do `y` times, for `n` from 0 to 7, do `x` times
        (princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))
                                         ; If `x<0` and the `n`th bit is 1
                                         ; or `x>0` and the `7-n`th bit is 1
                                         ; print "#", else print " "
        (princ"
")                                       ; After every `y` loop, print a newline
        )
    )
)
```
[Answer]
# [Tcl](http://tcl.tk/), 192 bytes
```
proc f {l x y} {lmap i [if $y<0 {lreverse $l} {lindex $l}] {time {lmap n {0 1 2 3 4 5 6 7} {time {puts -nonewline [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]} [expr abs($x)]};puts {}} [expr abs($y)]}}
```
[Try it online!](https://tio.run/##ZZBRa4MwFIXf@ysOXRjrg2ASo2sn9IcUH7ouBUGjqNuUkN/ubqIbcyPcKOd85ya5w62a57ZrbrjDVhgxOfrW1xYlLuUdbMpjEjr9obteg1XeLs2bHv1/ATuUtV4TBjYGh4BEAoUUmfv22/ehR2Qaoz8prXHRY9uBlY88z5/YmMdnZk5ZxMzhbB/cycIVboWurz0Rh8K9hCbWbYyJDDf3ekAFm4IriERCqAQ8gV8yRirBRQZBxY9qrSNBdMcYz0TKYKbS7XynGpZoRak0W5TlZYkAlyLkfIUj4gVoPCCUCKVSfyTtq@B2NMeKJsN34Qn7/SJEYqvUfnhb4R9BmWjDGApFfKtIyN9CQ8AfpqHb/7SZvwA "Tcl – Try It Online")
```
proc f {l x y}                           Define a function `f` with arguments `l`, `x`, `y`
{lmap i                                  For each `i` in
    [if $y<0 {lreverse $l} {lindex $l}]  The reverse of `l` if `y<0` else `l`
    {
        time {                           Do `abs(y)` times
            lmap n {0 1 2 3 4 5 6 7} {   For `n` from 0 to 7
                time {                   Do `abs(x)` times
                    puts -nonewline      Print without newline
                         [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]
                                         If `x<0` and the `n`th bit is 1 or
                                         `x>0` and the `7-n`th bit is 1
                                         then return "#" else return " "
                } [expr abs($x)]
            };
            puts {}                      Print a newline
        } [expr abs($y)]
    }
}
```
[Answer]
# 8088 machine code, IBM PC DOS, ~~77~~ 71 bytes
**Assembled:**
```
B402 84FF 7906 FD03 F14E F6DF 518A CFAC 5051 B108 8AF3 84F6 7902 F6DE
518A CEB2 2384 DB79 04D0 C8EB 02D0 C072 02B2 2050 CD21 58E2 FA59 E2E4
B20D CD21 B20A CD21 5958 E2CC 59E2 C5
```
**Listing:**
```
    PR_BMP  MACRO BMP, SZBMP, ZX, ZY
            LOCAL LOOP_Y, LOOP_Y2, LOOP_X, LOOP_X2, X_POS, X_NEG
B4 02   MOV  AH, 2          ; DOS display char function 
84 FF   TEST ZY, ZY         ; is Y scale negative?
79 06   JNS  LOOP_Y         ; if positive, start Y LOOP
FD      STD                 ; direction flag start from end
03 F1   ADD  BMP, CX        ; advance input byte array to end
4E      DEC  BMP            ; zero adjust index
F6 DF   NEG  ZY             ; make counter positive
     LOOP_Y:    
51      PUSH CX             ; save outer byte loop counter
8A CF   MOV  CL, ZY         ; set up repeat counter (Y scale factor)
AC      LODSB               ; load byte into AL
     LOOP_Y2:
50      PUSH AX             ; save original AL
51      PUSH CX             ; save outer loop
B1 08   MOV  CL, 8          ; loop 8 bits
8A F3   MOV  DH, ZX         ; DH is positive X scale used as counter
84 F6   TEST ZX, ZX         ; is X scale negative?
79 02   JNS  LOOP_X         ; if so, make counter positive
F6 DE   NEG  DH             ; compliment X counter 
    LOOP_X:
51      PUSH CX             ; save bit counter
8A CE   MOV  CL, DH         ; set repeat counter (X scale factor)
B2 23   MOV  DL, '#'        ; by default, display a #
84 DB   TEST ZX, ZX         ; is X scale negative?
79 04   JNS  X_POS          ; if so, rotate left 1 bit
D0 C8   ROR  AL, 1          ; else rotate right LSB into CF
EB 02   JMP  X_NEG          ; jump to examine CF
    X_POS:
D0 C0   ROL  AL, 1          ; rotate left MSB into CF
    X_NEG:
72 02   JC   LOOP_X2        ; is a 1?   
B2 20   MOV  DL, ' '        ; if not, display a space
    LOOP_X2:    
50      PUSH AX             ; save AL (since silly DOS overwrites it)
CD 21   INT  21H            ; display char
58      POP  AX             ; restore AL
E2 FA   LOOP LOOP_X2        ; loop repeat counter
59      POP  CX             ; restore bit counter
E2 E4   LOOP LOOP_X         ; loop bit counter
B2 0D   MOV  DL, 0DH        ; display CRLF
CD 21   INT  21H
B2 0A   MOV  DL, 0AH
CD 21   INT  21H
59      POP  CX             ; restore outer loop
58      POP  AX             ; restore original AL
E2 CC   LOOP LOOP_Y2        ; loop row display
59      POP  CX             ; restore byte counter
E2 C5   LOOP LOOP_Y         ; loop byte counter
    ENDM
```
This turned out to be more of a doozy in ASM than I originally thought. Multiple concurrent loops and lots of if/else branching can certainly give you headaches.
This is implemented as a MACRO since it allows function-like parameter passing for testing.
**Output**
Here is a test program for DOS that prompts for the X and Y scaling factor and draws to the screen. Note, scaling the dragon too much will scroll past the top since default DOS window is only 24 rows.
[![enter image description here](https://i.stack.imgur.com/GKLKc.png)](https://i.stack.imgur.com/GKLKc.png)
And here's our little dragon (duck):
[![enter image description here](https://i.stack.imgur.com/wrz9q.png)](https://i.stack.imgur.com/wrz9q.png)
**Try it Online!**
You can test in a DOS VM using [DOSBox](https://www.dosbox.com/) or [VirtualConsoles.com](https://virtualconsoles.com/online-emulators/DOS/) with the following steps:
1. Download [VCS.ZIP](https://stage.stonedrop.com/ppcg/VCS.ZIP) (contains all four executables)
2. Go to <https://virtualconsoles.com/online-emulators/DOS/>
3. Upload the ZIP file you just downloaded, click Start
4. Type `PLANE`, `KEY`, `TANK` or `DRAGON`.
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~146~~ 132 bytes
```
param($x,$y,$b)&($t={$b|%({$r+=,$_*$y},{$r=,$_*-$y+$r})[$y-lt0]
$r-ne$e})|%{$b=,$_*8|%{''+' X'[($_-shr$i++%8)%2]}
$y=-$x;-join(&$t)}
```
[Try it online!](https://tio.run/##bVPtasJAEPx/T7GEjblrLhCN1EARLFafIVBEantFW1ttTGmC5tnt3V6@tF3IMLc7OzchZL/7UelhrbbbM77CGI7n/VP69MExl1hIXIkex2x8xNXJ5UdM/bHE5Q0WpdQH4gEWPqaleMQi2GbhgmEafCpUpTi5eo00saae53uQeI8cl8FhneLG991YuINFybAYB5jfBW@7zSfvYSbKc8kYrj72fZ1owiHMw1tpcG5wHhHOqGNx2GKfOhEpR4Qz0k@7OCIHmkZT2o0Nxlbftw4gKMOgyWC3Hgzej6pp1ExDcqDb42Hrb7FKaNOG1e7wcnc@bTGK27ewvJ4KxtiEMyY5UDoJOu4AJPPAVJIk3hVPqOAvh6TV1Fx0nY1541xbXrhWflD3DOvoLtwCeqBNAVZ9kfKqVzt17/2vV@/a@renswg4gQtHZs4mlATM3zUUBlS@V8@ZetEfBZdWkqrD9zbTjZ7@N7TUKGmRxg5yp5I4gfpyGgdH1GKn60Pc81h5/gU "PowerShell – Try It Online")
Unrolled:
```
param($x,$y,$bitmap)
$transform={
    $bitmap|%({$r+=,$_*$y},{$r=,$_*-$y+$r})[$y-lt0]
    $r -ne $empty
}
&$transform|%{                                  # $bitmap is an array of lines
    $bitmap=,$_*8|%{''+' X'[($_-shr$i++%8)%2]}  # $bitmap is an array of line pixels now
    $y=-$x                                      # reuse $y
    -join(&$transform)
}
```
[Answer]
# Perl 5, 105 bytes
```
($_,$h,$v)=@F;say for map{$_=reverse if$h<0;y/0/ /;s/./$&x abs$h/eg;($_)x abs$v}$v<0?reverse/\d+/g:/\d+/g
```
[TIO](https://tio.run/##fYzNCsIwEITvPkUoi1hsu5tCL6ZFT958A6FETJuCtiWRYBFf3dgfz36X3dnZmV6ZW@b9BsoIdAQuLA5HYeXAqs6wu@xfUBZGOWWsYk0FOicxICFDYTFBWD@ZvFjQqGoxdoSLdG9wOe1/OTxft1jvluGn8iDwNME5j/gMjQvx@cJiztLVHz8dPz5d/2i61vpYtj4@ZQnxLw)
If input must be hex
[126 bytes](https://tio.run/##Rc3RCoIwGAXg@55ijBVJ022CGE2pILzrDQKZMJ1QOjYxJXr1lmHU1c934JxfS3ONnFujHCOFUe@lh4xbMYKyNeAm9APlqdWmbroSLum2gFjJgU@hkb00VoK6RCqhfCSUAMItCQhaDUAUFikiKz4NezP7J@oTuv/2yOW@IdVuPu7zEUJHY5yd8DEGDLDFDz4D4V/h5Feru7ptrPNF4/xzFFD2Bg)
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 21 bytes
```
⁴²+BḊ€⁸m€Ṡ}¥xA}ZʋƒYo⁶
```
[Try it online!](https://tio.run/##y0rNyan8//9R45ZDm7SdHu7oetS05lHjjlwg9XDngtpDSysca6NOdR@bFJn/qHHb/8PL9f//j@biitY10lHQNYrVUVBW8ElNK1FILEovzU3NKwFKKRhUGJjrAEk3FxDpaK4QC1QVlJmeUaLgCFcWCwA "Jelly – Try It Online")
Assumes there is at most one command-line argument.
[Answer]
# [APL (Dyalog Extended)](https://github.com/abrudz/dyalog-apl-extended), 23 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
[dzaima's method](https://codegolf.stackexchange.com/a/179229/43319)
Anonymous tacit prefix function. Takes \$(v,h,B)\$ as argument, where \$v\$ is the vertical scaling factor, \$h\$ is the horizontal scaling factor, and \$B\$ is the byte array as an 8-column packed bit-Boolean matrix (this is the normal and most compact way to represent raw bytes in APL). Requires `⎕IO←0` (zero based indexing).
```
' x'⊇⍨∘⊃{⊖⍣(>⍺)⍉⍵/⍨|⍺}/
```
[Try it online!](https://tio.run/##fVBNT8JAEL3zKzYcXIg27EeFnky0QMCDJC2erAdIixcUEjGWiCcS1CYlesB49@KNkxeP/Sn7R@p@1GwhxGz6dufNmzcz7Y2Hhj/tDUdXRhBOghs/8FO2XLU7bPGKCq0g7I5OppPglocY80TdSdaYWPvksDoTN3v@4Oy57YrH4k2Fp27nDKIQAujde33IGQcWPe8OIU7tFWEKQQhZ9MTiL1EQzR9Y9M7iz9IRi3/KLH5h8XeFJ2c8fKykA96cxUs1VjRP1lR0Wq5cx@bYbbXdtH89xoDLgJ4YwAuAQlQ9ENgU2KQSG5JRaGrEkqFSWZPYkHo7jzXpILPUlrWWQEvpsXIAl7DAByK7B1IWdYHHtUxKd0uR9JZzWaburDCbXe2BMiPzH6OmrZFaeln1/ssKI8MwCoMSwPzIH1vWTLImWxxRKpJXkS1GVGWVG2zWgWqO8rPJCJX45Ha5rmaO@QU "APL (Dyalog Extended) – Try It Online")
`{`…`}/` reduce right-to-left using the following anonymous lambda:
 `|⍺` the magnitude of the left argument (the scaling factor)
 `⍵/⍨` use that to replicate the right argument horizontally
 `⍉` transpose
 `⊖⍣(`…`)` flip if:
  `>⍺` the scaling factor is less than zero
`⊃` disclose (since reduction enclosed to reduce tensor rank from 1 to 0)
`' x'⊇⍨` select elements from the string " x" using that matrix
[Answer]
# [Ruby](https://www.ruby-lang.org/), 89 bytes
```
->b,w,h{y=h>0?-1:0;(b*h.abs).map{y+=1;[*1+8*w..0,*0...8*w].map{|x|' X'[b[y/h][x/w]]}*''}}
```
[Try it online!](https://tio.run/##fZDRasMgFIbv8xTeuaVqNcoiK@kYWfMMA/GiXpTcFMK6koQ2z57pcSHrhcPwIec7//GQr6sb51M1070jPWlvY9Xu@RsVr3z35PKWHd3lmZ2P3W3cVGJncrHRec8YJzlnjPm7BXsf7hh9YuPMuG2tGba9tVOO8TTN7twJVCGD@MBfSGAT2EjgASqRaqWAioTOEniA/vovS5gAVtaQ1YE69os4AdnMb1AsG8TMR@B7GZ1cHIc0vKzVOjvyd7u4KY9J9ZBs6pVSr/vH@2JtlnXX7ws6mfBjiD82FjClFD84WiSlN6RIuv9yNHwJK/1UKpLSn4RTPpZOKqL8svMP "Ruby – Try It Online")
[Answer]
# T-SQL, 216 bytes
Before executing this MS-SQL Studio Management, press CRTL-t to show data as text. The height cannot be adjusted to exceed the number of elements in the input.
Because of the horrible implementation of [STRING\_AGG](https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-2017), the height variable will only work in MSSM. MS should have made a third optional parameter to include the order of the elements being concatenated.
The online version can only support adjustment of the width. Height will result in a funky result with multiple stacking shapes.
```
USE master
DECLARE @ table(v int,i int identity)
INSERT @ values
(0x06),(0x0F),(0xF3),(0xFE),(0x0E),(0x04),
(0x04),(0x1E),(0x3F),(0x7F),(0xE3),(0xC3),
(0xC3),(0xC7),(0xFF),(0x3C),(0x08),(0x8F),
(0xE1),(0x3F)
-- @  = width
-- @h = height
DECLARE @s INT=1,@h INT=1
SELECT iif(@s>0,reverse(x),x)FROM(SELECT
string_agg(replicate(iif(v&n=0,' ','X'),abs(@s)),'')x,i,j
FROM(values(1),(2),(4),(8),(16),(32),(64),(128))x(n)
,@,(SELECT top(abs(@h))i j FROM @)g GROUP BY i,j)f
ORDER BY i*@h
```
This script will not show the correct shapes in the online version, so I made some minor adjustments to compensate.
**[Try it online](https://data.stackexchange.com/stackoverflow/query/1025973/classic-vcs-ascii-adventure)**
]