// File: /workspace/github_c_makefile_star2_O0/TurkeyMcMac[P]ts3d/src/d3d.c
// Function: d3d_new_camera
d3d_camera *d3d_new_camera(
	d3d_scalar fovx,
	d3d_scalar fovy,
	size_t width,
	size_t height,
	d3d_pixel empty_pixel)
{
	size_t size;
	size_t pixels_size, txtr_offset, tans_offset, dists_offset;
	d3d_texture *empty_txtr;
	d3d_camera *cam;
	size = offsetof(d3d_camera, pixels);
	pixels_size = width * height * sizeof(d3d_pixel);
	if (width != 0 && pixels_size / sizeof(d3d_pixel) / width != height)
		return NULL;
	CHECKED_ADD(size, pixels_size);
	// This type probably has the alignment of a one-pixel texture:
	typedef struct { size_t width, height; d3d_pixel pixels[1]; } one_pix;
	ALIGN_SIZE(size, one_pix);
	txtr_offset = size;
	CHECKED_ADD(size, texture_size(1, 1));
	ALIGN_SIZE(size, d3d_scalar);
	tans_offset = size;
	if (height * sizeof(d3d_scalar) / sizeof(d3d_scalar) != height)
		return NULL;
	CHECKED_ADD(size, height * sizeof(d3d_scalar));
	dists_offset = size;
	if (width * sizeof(d3d_scalar) / sizeof(d3d_scalar) != width)
		return NULL;
	CHECKED_ADD(size, width * sizeof(d3d_scalar));
	cam = d3d_malloc(size);
	if (!cam) return NULL;
	// The members 'tans' and 'dists' are actually pointers to parts of the
	// same allocation. 'empty_txtr' is glued on before them, but is not a
	// member.
	empty_txtr = (void *)((char *)cam + txtr_offset);
	cam->tans = (void *)((char *)cam + tans_offset);
	cam->dists = (void *)((char *)cam + dists_offset);
	// Just do basic protection against non-positive FOVs as they might
	// cause issues. I could do something better than silently clamping, but
	// what do you expect a non-positive FOV to do anyway?
	cam->fov.x = fovx > (d3d_scalar)0.0 ? fovx : 0.001;
	cam->fov.y = fovy > (d3d_scalar)0.0 ? fovy : 0.001;
	cam->width = width;
	cam->height = height;
	empty_txtr->width = 1;
	empty_txtr->height = 1;
	empty_txtr->pixels[0] = empty_pixel;
	cam->blank_block.faces[D3D_DPOSX] =
	cam->blank_block.faces[D3D_DPOSY] =
	cam->blank_block.faces[D3D_DNEGX] =
	cam->blank_block.faces[D3D_DNEGY] =
	cam->blank_block.faces[D3D_DUP] =
	cam->blank_block.faces[D3D_DDOWN] = empty_txtr;
	cam->order = NULL;
	cam->order_buf_cap = 0;
	cam->last_sprites = NULL;
	cam->last_n_sprites = 0;
	empty_camera_pixels(cam);
	for (size_t y = 0; y < height; ++y) {
		d3d_scalar angle =
			cam->fov.y * ((d3d_scalar)0.5 - (d3d_scalar)y / height);
		cam->tans[y] = tan(angle);
	}
	return cam;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movb %dl, %al
movsd %xmm0, -0x18(%rbp)
movsd %xmm1, -0x20(%rbp)
movq %rdi, -0x28(%rbp)
movq %rsi, -0x30(%rbp)
movb %al, -0x31(%rbp)
movq $0x80, -0x40(%rbp)
movq -0x28(%rbp), %rax
imulq -0x30(%rbp), %rax
shlq $0x0, %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x2825
movq -0x48(%rbp), %rax
shrq $0x0, %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x28(%rbp)
cmpq -0x30(%rbp), %rax
je 0x2825
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
jmp 0x2827
movq -0x40(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x284a
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x78(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x2854
movq -0x40(%rbp), %rax
addq $0x8, %rax
subq $0x1, %rax
shrq $0x3, %rax
shlq $0x3, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x2883
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x80(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl $0x1, %esi
movq %rsi, %rdi
callq 0x2c40
movq %rax, %rcx
movq -0xb8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x28d9
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x88(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x28e6
movq -0x40(%rbp), %rax
addq $0x8, %rax
subq $0x1, %rax
shrq $0x3, %rax
shlq $0x3, %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x291b
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x90(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rax
shlq $0x3, %rax
shrq $0x3, %rax
cmpq -0x30(%rbp), %rax
je 0x294d
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
jmp 0x294f
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x297f
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x98(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
shlq $0x3, %rax
shrq $0x3, %rax
cmpq -0x28(%rbp), %rax
je 0x29b1
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
jmp 0x29b3
movq -0x40(%rbp), %rax
movq -0x28(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x29e3
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0xa0(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x2750
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jne 0x2a0f
movq $0x0, -0x10(%rbp)
jmp 0x2c2d
movq -0x70(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x70(%rbp), %rcx
addq -0x58(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x70(%rbp), %rcx
addq -0x60(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x78(%rax)
movsd -0x18(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2a58
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0xc0(%rbp)
jmp 0x2a6a
movsd 0xe5c0(%rip), %xmm0     # 0x11020
movsd %xmm0, -0xc0(%rbp)
jmp 0x2a6a
movsd -0xc0(%rbp), %xmm0
movq -0x70(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x20(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2a97
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0xc8(%rbp)
jmp 0x2aa9
movsd 0xe581(%rip), %xmm0     # 0x11020
movsd %xmm0, -0xc8(%rbp)
jmp 0x2aa9
movsd -0xc8(%rbp), %xmm0
movq -0x70(%rbp), %rax
movsd %xmm0, 0x8(%rax)
movq -0x28(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x68(%rbp), %rax
movq $0x1, (%rax)
movq -0x68(%rbp), %rax
movq $0x1, 0x8(%rax)
movb -0x31(%rbp), %cl
movq -0x68(%rbp), %rax
movb %cl, 0x10(%rax)
movq -0x68(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x70(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x70(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x70(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x70(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x70(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x70(%rbp), %rax
movq $0x0, 0x50(%rax)
movq -0x70(%rbp), %rax
movq $0x0, 0x58(%rax)
movq -0x70(%rbp), %rax
movq $0x0, 0x60(%rax)
movq -0x70(%rbp), %rax
movq $0x0, 0x68(%rax)
movq -0x70(%rbp), %rdi
callq 0x2cc0
movq $0x0, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x2c25
movq -0x70(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0xa8(%rbp), %xmm2
movaps 0xe4dc(%rip), %xmm4     # 0x11070
punpckldq %xmm4, %xmm2    # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
movapd 0xe4e0(%rip), %xmm3     # 0x11080
subpd %xmm3, %xmm2
movaps %xmm2, %xmm1
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
addsd %xmm1, %xmm2
movq -0x30(%rbp), %xmm1
punpckldq %xmm4, %xmm1    # xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1]
subpd %xmm3, %xmm1
movaps %xmm1, %xmm3
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm3, %xmm1
divsd %xmm1, %xmm2
movsd 0xe455(%rip), %xmm1     # 0x11028
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0xb0(%rbp)
movsd -0xb0(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
callq 0x20f0
movq -0x70(%rbp), %rax
movq 0x70(%rax), %rax
movq -0xa8(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x2b6b
movq -0x70(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0xd0, %rsp
popq %rbp
retq
nopw (%rax,%rax)