https://github.com/akkartik/mu/blob/main/linux/raytracing/2.mu

     1 # Listing 7 of https://raytracing.github.io/books/RayTracingInOneWeekend.html
     2 #
     3 # To run (on Linux):
     4 #   $ git clone https://github.com/akkartik/mu
     5 #   $ cd mu
     6 #   $ ./translate raytracing/2.mu
     7 #   $ ./a.elf > 2.ppm
     8
     9 fn main -> _/ebx: int {
    10   print-string 0, "P3\n256 256\n255\n"
    11   var _four/edx: int <- copy 4
    12   var four/xmm1: float <- convert _four
    13   var one-fourth/xmm1: float <- reciprocal four
    14   var max/edx: int <- copy 0xff
    15   var image-size/xmm2: float <- convert max
    16   var j/ecx: int <- copy 0xff
    17   {
    18     compare j, 0
    19     break-if-<
    20     var i/eax: int <- copy 0
    21     {
    22       compare i, 0xff
    23       break-if->
    24       var c: rgb
    25       # compute r
    26       var tmp/xmm0: float <- convert i
    27       tmp <- divide image-size
    28       var r-addr/edx: (addr float) <- get c, r
    29       copy-to *r-addr, tmp
    30 #?       var tmp2/ebx: int <- reinterpret *r-addr
    31 #?       print-int32-hex 0, tmp2
    32 #?       print-string 0, "\n"
    33       # compute g
    34       tmp <- convert j
    35       tmp <- divide image-size
    36       var g-addr/edx: (addr float) <- get c, g
    37       copy-to *g-addr, tmp
    38       # compute b
    39       var b-addr/edx: (addr float) <- get c, b
    40       copy-to *b-addr, one-fourth
    41       # emit
    42       var c-addr/edx: (addr rgb) <- address c
    43       print-rgb 0, c-addr
    44       i <- increment
    45       loop
    46     }
    47     j <- decrement
    48     loop
    49   }
    50   return 0
    51 }
    52
    53 type rgb {
    54   # components normalized to within [0.0, 1.0]
    55   r: float
    56   g: float
    57   b: float
    58 }
    59
    60 # print translating to [0, 256)
    61 fn print-rgb screen: (addr screen), _c: (addr rgb) {
    62   var c/esi: (addr rgb) <- copy _c
    63   var n/ecx: int <- copy 0xff  # turns out 255 works just as well as 255.999, which is lucky because we don't have floating-point literals
    64   var xn/xmm1: float <- convert n
    65   # print 255 * c->r
    66   var result/xmm0: float <- copy xn
    67   var src-addr/eax: (addr float) <- get c, r
    68   result <- multiply *src-addr
    69   var result-int/edx: int <- convert result
    70   print-int32-decimal screen, result-int
    71   print-string screen, " "
    72   # print 255 * c->g
    73   src-addr <- get c, g
    74   result <- copy xn
    75   result <- multiply *src-addr
    76   result-int <- convert result
    77   print-int32-decimal screen, result-int
    78   print-string screen, " "
    79   # print 255 * c->b
    80   src-addr <- get c, b
    81   result <- copy xn
    82   result <- multiply *src-addr
    83   result-int <- convert result
    84   print-int32-decimal screen, result-int
    85   print-string screen, "\n"
    86 }