// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/ppu.cpp
// Function: Ppu::drawSprites(int)
void Ppu::drawSprites(int n_scanline) {
    //Select what events the window will listen to
    uint8_t index, attribute, palette;
    int pos_x, pos_y;
    unsigned int patterntable, line_addr, h_offset, large_sprite;
    bool flip_h, flip_v, priority;

    //Show sprites ppumask bit
    if ((mem_ppu->PPUMASK >> 4)&1) {
	for (int i = 0; i<64; ++i) {
	    pos_y     = mem_ppu->oam[(i*4) + 0];
	    index     = mem_ppu->oam[(i*4) + 1];
	    attribute = mem_ppu->oam[(i*4) + 2];
	    pos_x     = mem_ppu->oam[(i*4) + 3];

	    if (n_scanline == pos_y) {

	    	palette = attribute & 3;
	    	priority = (attribute >> 5) & 1;
	    	flip_h = (attribute >> 6) & 1;
	    	flip_v = (attribute >> 7) & 1;

	    	large_sprite = (mem_ppu->PPUCTRL >> 5) & 1;
	    	if (large_sprite) {
	    	    patterntable = index & 1;
	    	    index = index & 0xfe;
	    	}
	    	else {
	    	    patterntable = (mem_ppu->PPUCTRL >> 3) & 1;
	    	}

	    	if (patterntable)
	    	    index += 256;

	    	if (pos_x > 8 || ((mem_ppu->PPUMASK >> 2)&1)) {
	    	    for (int i2 = 0; i2<8; ++i2) {
	    	        for (int j2 = 0; j2<8; ++j2) {
			    line_addr = (index * 16) + i2;
	    	            h_offset = (7-j2);
	    	            unsigned char bitplane =
	    	                (((mem_ppu->ram[line_addr])>>h_offset)&1) +
	    	               ((((mem_ppu->ram[line_addr+8])>>h_offset)&1)<<1);
            	            
	    	            unsigned char color = mem_ppu->ram[0x3f10 + (palette << 2) + bitplane];
	    	    	    uint8_t tmp_pos_x;
	    	    	    uint8_t tmp_pos_y;
	    	    	    if (flip_h)
	    	    	        tmp_pos_x = pos_x + 7 - j2;
	    	    	    else
	    	    	        tmp_pos_x = pos_x + j2;
	    	    	    if (flip_v)
	    	    	        tmp_pos_y = pos_y + 7 - i2;
	    	    	    else
	    	    	        tmp_pos_y = pos_y + i2;

			    int position = (tmp_pos_y*256) + tmp_pos_x;
			    if (bitplane != 0 && position < 61440) {
				if (priority == 0) {
				    mem_ppu->vram[position] = colors[color];
				}
				else if (mem_ppu->vram[position] == colors[mem_ppu->ram[0x3f00]]) {
				    mem_ppu->vram[position] = colors[color];
				}
			    }
	    	        }
	    	    }
	    	}

	    	if (large_sprite) {
	    	    index += 1;
	    	    pos_y += 16;
	    	    if (pos_x > 8 || ((mem_ppu->PPUMASK >> 2)&1)) {
	    	        for (int i2 = 0; i2<8; ++i2) {
	    		    for (int j2 = 0; j2<8; ++j2) {
				line_addr = (index * 16) + i2;
	    		        h_offset = (7-j2);
	    		        unsigned char bitplane =
	    		            (((mem_ppu->ram[line_addr])>>h_offset)&1) +
	    		           ((((mem_ppu->ram[line_addr+8])>>h_offset)&1)<<1);
            		            
	    		        unsigned char color = mem_ppu->ram[0x3f00 + (palette << 2) + 0x04 + bitplane];
			        uint8_t tmp_pos_x;
			        uint8_t tmp_pos_y;
	    	    	        if (flip_h)
				    tmp_pos_x = pos_x + 7 - j2;
	    	    	        else
				    tmp_pos_x = pos_x + j2;
	    	    	        if (flip_v)
				    tmp_pos_y = pos_y + 7 - i2;
	    	    	        else
				    tmp_pos_y = pos_y + i2;

				int position = (tmp_pos_y*256) + tmp_pos_x;

			    	if (bitplane != 0 && position < 61440) {
			    	    if (priority == 0) {
					mem_ppu->vram[position] = colors[color];
			    	    }
			    	    else if (mem_ppu->vram[position] == colors[mem_ppu->ram[0x3f00]]) {
					mem_ppu->vram[position] = colors[color];
			    	    }
			    	}
	    		    }
	    		}
	    	    }
	    	}
	    }
	}
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, -0x48(%rsp)
movq %rdi, -0x68(%rsp)
movq 0x8(%rdi), %rax
movq %rax, -0x70(%rsp)
movb 0x3c019(%rax), %al
movb %al, -0x72(%rsp)
testb $0x10, %al
jne 0x3678
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x70(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rsp)
movq -0x48(%rsp), %rax
leal 0x7(%rax), %ecx
movl %ecx, -0x4c(%rsp)
leal 0x10(%rax), %ecx
movq %rcx, -0x28(%rsp)
addl $0x17, %eax
movl %eax, -0x50(%rsp)
xorl %ecx, %ecx
cmpq $0x40, %rcx
je 0x366d
movq -0x40(%rsp), %rax
movq %rcx, -0x38(%rsp)
movzbl (%rax,%rcx,4), %eax
movq %rax, -0x18(%rsp)
cmpl -0x48(%rsp), %eax
jne 0x3884
movq -0x38(%rsp), %rdx
leaq (,%rdx,4), %rcx
movq -0x40(%rsp), %rax
movb 0x3(%rax,%rdx,4), %dl
movq %rdx, -0x60(%rsp)
movzbl 0x2(%rax,%rcx), %r15d
movzbl 0x1(%rax,%rcx), %eax
movq %rax, -0x58(%rsp)
movq -0x70(%rsp), %rax
movb 0x3c010(%rax), %r8b
testb $0x4, -0x72(%rsp)
jne 0x370f
cmpb $0x9, -0x60(%rsp)
jb 0x3884
movq -0x60(%rsp), %rax
movzbl %al, %esi
movl %r15d, %edi
andl $0x3, %edi
movq -0x58(%rsp), %rdx
movl %edx, %ecx
andb $-0x2, %cl
movb %r8b, -0x71(%rsp)
testb $0x20, %r8b
movzbl %cl, %ecx
cmovel %edx, %ecx
movzbl %cl, %ecx
shll $0x4, %ecx
movq %rcx, -0x20(%rsp)
movq -0x70(%rsp), %rcx
movq (%rcx), %rdx
movq %rdi, -0x30(%rsp)
movl %edi, %r8d
shll $0x2, %r8d
addl $0x7, %esi
movq %rsi, -0x8(%rsp)
leal 0x7(%rax), %ecx
movzbl %cl, %r11d
xorl %r9d, %r9d
cmpq $0x8, %r9
je 0x387d
movq %r9, %rbx
movq -0x20(%rsp), %rdi
orq %rdi, %rbx
movl -0x4c(%rsp), %ecx
subl %r9d, %ecx
movq -0x18(%rsp), %rax
leal (%rax,%r9), %esi
testb %r15b, %r15b
movq %r9, -0x10(%rsp)
leaq 0x8(%r9,%rdi), %r12
movzbl %sil, %r9d
cmovsl %ecx, %r9d
movzbl %r9b, %r14d
shll $0x8, %r14d
movq -0x60(%rsp), %rax
movl %eax, %esi
movl $0x7, %eax
movl %eax, %ecx
cmpl $-0x1, %ecx
je 0x3870
movzbl (%rdx,%rbx), %r10d
xorl %r13d, %r13d
btl %ecx, %r10d
setb %r13b
movzbl (%rdx,%r12), %r10d
shrl %cl, %r10d
andl $0x1, %r10d
leal (%r13,%r10,2), %r10d
leal (%r11,%rcx), %r13d
addb $-0x7, %r13b
testb $0x40, %r15b
movzbl %r13b, %ebp
movzbl %sil, %r13d
cmovnel %ebp, %r13d
testl %r10d, %r10d
je 0x3866
cmpb $-0x11, %r9b
ja 0x3866
orl %r8d, %r10d
movzbl 0x3f10(%rdx,%r10), %r10d
movzbl %r13b, %ebp
orl %r14d, %ebp
movl %ebp, %r13d
testb $0x20, %r15b
jne 0x3836
movq -0x68(%rsp), %rax
movl 0x38(%rax,%r10,4), %r10d
movq -0x70(%rsp), %rax
movl %r10d, 0x10(%rax,%r13,4)
jmp 0x3866
movq -0x70(%rsp), %rax
movl 0x10(%rax,%r13,4), %ebp
movzbl 0x3f00(%rdx), %eax
movq -0x68(%rsp), %rdi
cmpl 0x38(%rdi,%rax,4), %ebp
jne 0x3866
movq -0x68(%rsp), %rax
movl 0x38(%rax,%r10,4), %eax
movq -0x70(%rsp), %rdi
movl %eax, 0x10(%rdi,%r13,4)
decl %ecx
incb %sil
jmp 0x37b7
movq -0x10(%rsp), %r9
incq %r9
jmp 0x3767
testb $0x20, -0x71(%rsp)
jne 0x3891
movq -0x38(%rsp), %rcx
incq %rcx
jmp 0x36a3
cmpb $0x8, -0x60(%rsp)
ja 0x38b7
testb $0x4, -0x72(%rsp)
je 0x3884
movq -0x70(%rsp), %rax
movq (%rax), %rdx
movq -0x30(%rsp), %rax
leal (,%rax,4), %eax
movzbl %al, %r8d
movq -0x58(%rsp), %rax
orq $0x1, %rax
shll $0x4, %eax
movq %rax, -0x58(%rsp)
addl $0x3f04, %r8d           # imm = 0x3F04
xorl %esi, %esi
cmpq $0x8, %rsi
je 0x3884
movq %rsi, %r10
movq -0x58(%rsp), %rdi
orq %rdi, %r10
movl -0x50(%rsp), %eax
subl %esi, %eax
movq -0x28(%rsp), %rcx
addl %esi, %ecx
testb %r15b, %r15b
leaq 0x8(%rsi,%rdi), %r11
cmovsl %eax, %ecx
shll $0x8, %ecx
movzwl %cx, %r9d
movq -0x60(%rsp), %rax
movl %eax, %ebx
movl $0x7, %eax
movl %eax, %ecx
cmpl $-0x1, %ecx
je 0x39ac
movzbl (%rdx,%r10), %eax
xorl %r14d, %r14d
btl %ecx, %eax
setb %r14b
movzbl (%rdx,%r11), %eax
shrl %cl, %eax
andl $0x1, %eax
leal (%r14,%rax,2), %r14d
movq -0x8(%rsp), %rax
addl %ecx, %eax
addb $-0x7, %al
testb $0x40, %r15b
movzbl %al, %eax
movzbl %bl, %ebp
cmovnel %eax, %ebp
testl %r14d, %r14d
je 0x39a3
cmpl $0xefff, %r9d           # imm = 0xEFFF
ja 0x39a3
orl %r8d, %r14d
movzbl (%rdx,%r14), %r14d
movzbl %bpl, %eax
orl %r9d, %eax
movl %eax, %r12d
testb $0x20, %r15b
je 0x398f
movq -0x70(%rsp), %rax
movl 0x10(%rax,%r12,4), %eax
movzbl 0x3f00(%rdx), %r13d
movq -0x68(%rsp), %rdi
cmpl 0x38(%rdi,%r13,4), %eax
jne 0x39a3
movq -0x68(%rsp), %rax
movl 0x38(%rax,%r14,4), %eax
movq -0x70(%rsp), %rdi
movl %eax, 0x10(%rdi,%r12,4)
decl %ecx
incb %bl
jmp 0x390f
incq %rsi
jmp 0x38d1