https://github.com/akkartik/mu/blob/main/linux/apps/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/linux
 6 #   $ ./translate apps/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 }