// File: daltonbr[P]RayTracing/./src/main.cpp
// Function: main
int main()
{
    // const char* inputFileName = (const char*)"foo.png";//"chapter5b.ppm";
    // const char* outputFileName = (const char*)"foo.out.png";
    // generate_png(inputFileName, outputFileName);

    int nx = 2000;
    int ny = 1000;
    int ns = 1000;
    std::cout << "P3\n" << nx << " " << ny << "\n255\n";

    hitable *list[5];
    list[0] = new sphere(vec3(0, 0, -1), 0.5, new lambertian(vec3(0.5, 0.0, 1.0)));
    list[1] = new sphere(vec3(0.75, -0.25, -1.5), 0.25, new lambertian(vec3(0.1, 0.7, 0.3)));
    // A giant sphere to act as a ground (or a planet)
    
    list[2] = new sphere(vec3(0, -100.5, -1), 100, new lambertian(vec3(0.8, 0.6, 0.2)));
    list[3] = new sphere(vec3(1, 0, -1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 0.3));
    list[4] = new sphere(vec3(-1, 0, -1), 0.5, new metal(vec3(0.8, 0.8, 0.8), 0.8));
    // rose gold sphere
    //list[5] = new sphere(vec3(-0.25, -0.125, -0.25), 0.125, new metal(vec3(0.718, 0.431, 0.475)));
    hitable *world = new hitable_list(list, 5);

    camera cam;

    for (int j = ny - 1; j >= 0; j--)
    {
        for (int i = 0; i < nx; i++)
        {
            vec3 col = vec3(0, 0, 0);
            for (int s = 0; s < ns; s++)
            {
                float u = float(i + drand48()) / float(nx);
                float v = float(j + drand48()) / float(ny);
                ray r = cam.get_ray(u, v);
                vec3 p = r.point_at_parameter(2.0);
                col += color(r, world, 0);
            }
            col /= float(ns);
            col = vec3( sqrt(col[0]), sqrt(col[1]), sqrt(col[2]) );
            int ir = int (255.99 * col[0]);
            int ig = int (255.99 * col[1]);
            int ib = int (255.99 * col[2]);
            
            std::cout << ir << " " << ig << " " << ib << "\n";
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movl $0x0, -0x4(%rbp)
movl $0x7d0, -0x8(%rbp)      # imm = 0x7D0
movl $0x3e8, -0xc(%rbp)      # imm = 0x3E8
movl $0x3e8, -0x10(%rbp)     # imm = 0x3E8
movq 0x2137a(%rip), %rdi     # 0x28fd8
leaq 0x1c11d(%rip), %rsi     # 0x23d82
callq 0x20d0
movq %rax, %rdi
movl -0x8(%rbp), %esi
callq 0x21e0
movq %rax, %rdi
leaq 0x1c9b8(%rip), %rsi     # 0x24637
callq 0x20d0
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x21e0
movq %rax, %rdi
leaq 0x1c0ed(%rip), %rsi     # 0x23d86
callq 0x20d0
movl $0x20, %edi
callq 0x20f0
movq %rax, -0x1e8(%rbp)
leaq -0x4c(%rbp), %rdi
xorps %xmm1, %xmm1
movss 0x1a37e(%rip), %xmm2    # 0x2203c
movaps %xmm1, %xmm0
callq 0x20b10
jmp 0x7cc8
movl $0x18, %edi
callq 0x20f0
movq %rax, -0x1f0(%rbp)
jmp 0x7cdb
leaq -0x68(%rbp), %rdi
movss 0x1a329(%rip), %xmm0    # 0x22010
xorps %xmm1, %xmm1
movss 0x1a316(%rip), %xmm2    # 0x22008
callq 0x20b10
jmp 0x7cf9
movq -0x1f0(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x20ff0
jmp 0x7d0b
movq -0x1f0(%rbp), %rsi
movq -0x1e8(%rbp), %rdi
movl -0x44(%rbp), %eax
movl %eax, -0x70(%rbp)
movq -0x4c(%rbp), %rax
movq %rax, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
movss -0x70(%rbp), %xmm1
movss 0x1a2d7(%rip), %xmm2    # 0x22010
callq 0x21040
jmp 0x7d40
movq -0x1e8(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x20, %edi
callq 0x20f0
movq %rax, -0x1f8(%rbp)
leaq -0x84(%rbp), %rdi
movss 0x1a2d5(%rip), %xmm0    # 0x22040
movss 0x1a2d1(%rip), %xmm1    # 0x22044
movss 0x1a2cd(%rip), %xmm2    # 0x22048
callq 0x20b10
jmp 0x7d82
movl $0x18, %edi
callq 0x20f0
movq %rax, -0x200(%rbp)
jmp 0x7d95
leaq -0x90(%rbp), %rdi
movss 0x1a2a8(%rip), %xmm0    # 0x2204c
movss 0x1a28c(%rip), %xmm1    # 0x22038
movss 0x1a29c(%rip), %xmm2    # 0x22050
callq 0x20b10
jmp 0x7dbb
movq -0x200(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x20ff0
jmp 0x7dd0
movq -0x200(%rbp), %rsi
movq -0x1f8(%rbp), %rdi
movl -0x7c(%rbp), %eax
movl %eax, -0x98(%rbp)
movq -0x84(%rbp), %rax
movq %rax, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
movss -0x98(%rbp), %xmm1
movss 0x1a247(%rip), %xmm2    # 0x22054
callq 0x21040
jmp 0x7e14
movq -0x1f8(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x20, %edi
callq 0x20f0
movq %rax, -0x208(%rbp)
leaq -0xac(%rbp), %rdi
xorps %xmm0, %xmm0
movss 0x1a216(%rip), %xmm1    # 0x22058
movss 0x1a1f2(%rip), %xmm2    # 0x2203c
callq 0x20b10
jmp 0x7e51
movl $0x18, %edi
callq 0x20f0
movq %rax, -0x210(%rbp)
jmp 0x7e64
leaq -0xb8(%rbp), %rdi
movss 0x1a1e9(%rip), %xmm0    # 0x2205c
movss 0x1a1e5(%rip), %xmm1    # 0x22060
movss 0x1a1e1(%rip), %xmm2    # 0x22064
callq 0x20b10
jmp 0x7e8a
movq -0x210(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x20ff0
jmp 0x7e9f
movq -0x210(%rbp), %rsi
movq -0x208(%rbp), %rdi
movl -0xa4(%rbp), %eax
movl %eax, -0xc0(%rbp)
movq -0xac(%rbp), %rax
movq %rax, -0xc8(%rbp)
movsd -0xc8(%rbp), %xmm0
movss -0xc0(%rbp), %xmm1
movss 0x1a189(%rip), %xmm2    # 0x22068
callq 0x21040
jmp 0x7ee6
movq -0x208(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x20, %edi
callq 0x20f0
movq %rax, -0x218(%rbp)
leaq -0xd4(%rbp), %rdi
movss 0x1a0f7(%rip), %xmm0    # 0x22008
xorps %xmm1, %xmm1
movss 0x1a120(%rip), %xmm2    # 0x2203c
callq 0x20b10
jmp 0x7f23
movl $0x18, %edi
callq 0x20f0
movq %rax, -0x220(%rbp)
jmp 0x7f36
leaq -0xe0(%rbp), %rdi
movss 0x1a117(%rip), %xmm0    # 0x2205c
movss 0x1a113(%rip), %xmm1    # 0x22060
movss 0x1a10f(%rip), %xmm2    # 0x22064
callq 0x20b10
jmp 0x7f5c
movq -0x220(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
movss 0x1a0de(%rip), %xmm0    # 0x22050
callq 0x210c0
jmp 0x7f79
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rdi
movl -0xcc(%rbp), %eax
movl %eax, -0xe8(%rbp)
movq -0xd4(%rbp), %rax
movq %rax, -0xf0(%rbp)
movsd -0xf0(%rbp), %xmm0
movss -0xe8(%rbp), %xmm1
movss 0x1a057(%rip), %xmm2    # 0x22010
callq 0x21040
jmp 0x7fc0
movq -0x218(%rbp), %rax
movq %rax, -0x28(%rbp)
movl $0x20, %edi
callq 0x20f0
movq %rax, -0x228(%rbp)
leaq -0xfc(%rbp), %rdi
xorps %xmm1, %xmm1
movss 0x1a04e(%rip), %xmm2    # 0x2203c
movaps %xmm2, %xmm0
callq 0x20b10
jmp 0x7ff8
movl $0x18, %edi
callq 0x20f0
movq %rax, -0x230(%rbp)
jmp 0x800b
leaq -0x108(%rbp), %rdi
movss 0x1a042(%rip), %xmm2    # 0x2205c
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x20b10
jmp 0x8027
movq -0x230(%rbp), %rdi
leaq -0x108(%rbp), %rsi
movss 0x1a01f(%rip), %xmm0    # 0x2205c
callq 0x210c0
jmp 0x8044
movq -0x230(%rbp), %rsi
movq -0x228(%rbp), %rdi
movl -0xf4(%rbp), %eax
movl %eax, -0x110(%rbp)
movq -0xfc(%rbp), %rax
movq %rax, -0x118(%rbp)
movsd -0x118(%rbp), %xmm0
movss -0x110(%rbp), %xmm1
movss 0x19f8c(%rip), %xmm2    # 0x22010
callq 0x21040
jmp 0x808b
movq -0x228(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x18, %edi
callq 0x20f0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x238(%rbp)
leaq -0x40(%rbp), %rsi
movl $0x5, %edx
callq 0x21140
jmp 0x80bd
movq -0x238(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x21190
movl -0xc(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x154(%rbp)
cmpl $0x0, -0x154(%rbp)
jl 0x8592
movl $0x0, -0x158(%rbp)
movl -0x158(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x857c
leaq -0x164(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x20b10
movl $0x0, -0x168(%rbp)
movl -0x168(%rbp), %eax
cmpl -0x10(%rbp), %eax
jge 0x83de
cvtsi2sdl -0x158(%rbp), %xmm0
movsd %xmm0, -0x250(%rbp)
callq 0x20c0
movaps %xmm0, %xmm1
movsd -0x250(%rbp), %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
cvtsi2ssl -0x8(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x16c(%rbp)
cvtsi2sdl -0x154(%rbp), %xmm0
movsd %xmm0, -0x248(%rbp)
callq 0x20c0
movaps %xmm0, %xmm1
movsd -0x248(%rbp), %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
cvtsi2ssl -0xc(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x170(%rbp)
movss -0x16c(%rbp), %xmm0
movss -0x170(%rbp), %xmm1
leaq -0x188(%rbp), %rdi
movq %rdi, -0x240(%rbp)
leaq -0x150(%rbp), %rsi
callq 0x21280
movq -0x240(%rbp), %rdi
movss 0x19e22(%rip), %xmm0    # 0x22004
callq 0x20d90
movq -0x240(%rbp), %rdi
movss %xmm1, -0x1a0(%rbp)
movlpd %xmm0, -0x1a8(%rbp)
movl -0x1a0(%rbp), %eax
movl %eax, -0x190(%rbp)
movq -0x1a8(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x120(%rbp), %rsi
xorl %edx, %edx
callq 0x7900
movss %xmm1, -0x1c0(%rbp)
movlpd %xmm0, -0x1c8(%rbp)
movq -0x1c8(%rbp), %rax
movq %rax, -0x1b4(%rbp)
movl -0x1c0(%rbp), %eax
movl %eax, -0x1ac(%rbp)
leaq -0x164(%rbp), %rdi
leaq -0x1b4(%rbp), %rsi
callq 0x213d0
movl -0x168(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x168(%rbp)
jmp 0x8128
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x82a2
movq -0x1f0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
movq -0x1e8(%rbp), %rdi
movl $0x20, %esi
callq 0x2100
jmp 0x859e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x82e3
movq -0x200(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
movq -0x1f8(%rbp), %rdi
movl $0x20, %esi
callq 0x2100
jmp 0x859e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x8324
movq -0x210(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
movq -0x208(%rbp), %rdi
movl $0x20, %esi
callq 0x2100
jmp 0x859e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x8365
movq -0x220(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
movq -0x218(%rbp), %rdi
movl $0x20, %esi
callq 0x2100
jmp 0x859e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x83a6
movq -0x230(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
movq -0x228(%rbp), %rdi
movl $0x20, %esi
callq 0x2100
jmp 0x859e
movq -0x238(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x2100
jmp 0x859e
cvtsi2ssl -0x10(%rbp), %xmm0
leaq -0x164(%rbp), %rdi
callq 0x21420
leaq -0x164(%rbp), %rdi
xorl %esi, %esi
callq 0x21480
movss (%rax), %xmm0
callq 0x20cf0
movss %xmm0, -0x254(%rbp)
leaq -0x164(%rbp), %rdi
movl $0x1, %esi
callq 0x21480
movss (%rax), %xmm0
callq 0x20cf0
movss %xmm0, -0x258(%rbp)
leaq -0x164(%rbp), %rdi
movl $0x2, %esi
callq 0x21480
movss (%rax), %xmm0
callq 0x20cf0
movss -0x258(%rbp), %xmm1
movaps %xmm0, %xmm2
movss -0x254(%rbp), %xmm0
leaq -0x1d4(%rbp), %rdi
callq 0x20b10
movq -0x1d4(%rbp), %rax
movq %rax, -0x164(%rbp)
movl -0x1cc(%rbp), %eax
movl %eax, -0x15c(%rbp)
leaq -0x164(%rbp), %rdi
xorl %esi, %esi
callq 0x21480
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x19c0f(%rip), %xmm0    # 0x220b0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x1d8(%rbp)
leaq -0x164(%rbp), %rdi
movl $0x1, %esi
callq 0x21480
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x19be0(%rip), %xmm0    # 0x220b0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x1dc(%rbp)
leaq -0x164(%rbp), %rdi
movl $0x2, %esi
callq 0x21480
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x19bb1(%rip), %xmm0    # 0x220b0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x1e0(%rbp)
movl -0x1d8(%rbp), %esi
movq 0x20abe(%rip), %rdi     # 0x28fd8
callq 0x21e0
movq %rax, %rdi
leaq 0x1c10e(%rip), %rsi     # 0x24637
callq 0x20d0
movq %rax, %rdi
movl -0x1dc(%rbp), %esi
callq 0x21e0
movq %rax, %rdi
leaq 0x1c0f1(%rip), %rsi     # 0x24637
callq 0x20d0
movq %rax, %rdi
movl -0x1e0(%rbp), %esi
callq 0x21e0
movq %rax, %rdi
leaq 0x1b821(%rip), %rsi     # 0x23d84
callq 0x20d0
movl -0x158(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x158(%rbp)
jmp 0x80fa
jmp 0x857e
movl -0x154(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x154(%rbp)
jmp 0x80e3
movl -0x4(%rbp), %eax
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x21f0
nopw (%rax,%rax)