// File: /workspace/github_cpp_makefile_star2_O1/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
movl %esi, -0x20(%rsp)
movq 0x8(%rdi), %rax
movb 0x3c019(%rax), %cl
movb %cl, -0x56(%rsp)
testb $0x10, %cl
je 0x5065
movq 0x8(%rax), %rcx
movq %rcx, -0x10(%rsp)
xorl %edx, %edx
movq -0x10(%rsp), %rcx
movq %rdx, -0x8(%rsp)
movzbl (%rcx,%rdx,4), %ecx
movq %rcx, -0x48(%rsp)
cmpl -0x20(%rsp), %ecx
jne 0x5053
movq -0x8(%rsp), %rdx
leaq (,%rdx,4), %rcx
movq -0x10(%rsp), %rsi
movb 0x3(%rsi,%rdx,4), %dl
movq %rdx, -0x50(%rsp)
movzbl 0x1(%rsi,%rcx), %edx
movzbl 0x2(%rsi,%rcx), %ebx
movl %ebx, %ecx
andl $0x3, %ecx
movq %rcx, -0x18(%rsp)
movb 0x3c010(%rax), %sil
movl %edx, %ecx
andb $-0x2, %cl
movb %sil, -0x55(%rsp)
testb $0x20, %sil
movzbl %cl, %ecx
cmovel %edx, %ecx
movl %ecx, -0x3c(%rsp)
testb $0x4, -0x56(%rsp)
jne 0x4df7
cmpb $0x9, -0x50(%rsp)
jb 0x4f22
movzbl -0x3c(%rsp), %ecx
shll $0x4, %ecx
movq %rcx, -0x38(%rsp)
movq (%rax), %r13
movq -0x18(%rsp), %rcx
leal (,%rcx,4), %ecx
movl %ecx, -0x28(%rsp)
movq -0x48(%rsp), %rcx
addl $0x7, %ecx
movl %ecx, -0x54(%rsp)
movq -0x50(%rsp), %rcx
addl $0x7, %ecx
movl %ecx, -0x1c(%rsp)
xorl %r9d, %r9d
movq -0x38(%rsp), %r8
leaq (%r9,%r8), %r14
movl -0x54(%rsp), %ecx
subb %r9b, %cl
movq -0x48(%rsp), %rdx
leal (%rdx,%r9), %esi
testb %bl, %bl
movq %r9, -0x30(%rsp)
leaq 0x8(%r9,%r8), %rbp
movzbl %sil, %esi
movzbl %cl, %r9d
cmovnsl %esi, %r9d
movzbl %r9b, %r11d
shll $0x8, %r11d
movl $0x7, %ecx
movq -0x50(%rsp), %rdx
movl %edx, %esi
movl -0x1c(%rsp), %edx
movl %edx, %r8d
movzbl (%r13,%r14), %r10d
xorl %r12d, %r12d
btl %ecx, %r10d
setb %r12b
movzbl (%r13,%rbp), %r10d
shrl %cl, %r10d
andl $0x1, %r10d
leal (%r12,%r10,2), %r10d
testb $0x40, %bl
movzbl %sil, %r15d
movzbl %r8b, %r12d
cmovel %r15d, %r12d
testl %r10d, %r10d
je 0x4f01
cmpb $-0x11, %r9b
ja 0x4f01
orl -0x28(%rsp), %r10d
movzbl 0x3f10(%r13,%r10), %r10d
movzbl %r12b, %r15d
orl %r11d, %r15d
movl %r15d, %r12d
testb $0x20, %bl
jne 0x4ee3
movl 0x38(%rdi,%r10,4), %r10d
movl %r10d, 0x10(%rax,%r12,4)
jmp 0x4f01
movl 0x10(%rax,%r12,4), %r15d
movzbl 0x3f00(%r13), %edx
cmpl 0x38(%rdi,%rdx,4), %r15d
jne 0x4f01
movl 0x38(%rdi,%r10,4), %edx
movl %edx, 0x10(%rax,%r12,4)
decb %r8b
incb %sil
addl $-0x1, %ecx
jb 0x4e7e
movq -0x30(%rsp), %r9
incq %r9
cmpq $0x8, %r9
jne 0x4e32
cmpb $0x9, -0x50(%rsp)
setb %cl
testb $0x4, -0x56(%rsp)
sete %dl
testb $0x20, -0x55(%rsp)
je 0x5053
andb %cl, %dl
jne 0x5053
movq -0x48(%rsp), %rcx
leal 0x10(%rcx), %edx
movq %rdx, -0x30(%rsp)
movl -0x3c(%rsp), %edx
incb %dl
movzbl %dl, %edx
shll $0x4, %edx
movq %rdx, -0x38(%rsp)
movq (%rax), %r8
movq -0x18(%rsp), %rdx
leaq 0x3f04(,%rdx,4), %r14
addl $0x17, %ecx
movq %rcx, -0x48(%rsp)
movq -0x50(%rsp), %rcx
addl $0x7, %ecx
movl %ecx, -0x54(%rsp)
xorl %r9d, %r9d
movq -0x38(%rsp), %rsi
leaq (%r9,%rsi), %r12
movq -0x48(%rsp), %rcx
subl %r9d, %ecx
movq -0x30(%rsp), %rdx
addl %r9d, %edx
testb %bl, %bl
movq %r9, -0x28(%rsp)
leaq 0x8(%r9,%rsi), %r9
cmovsl %ecx, %edx
shll $0x8, %edx
movzwl %dx, %r11d
movl $0x7, %ecx
movq -0x50(%rsp), %rdx
movl %edx, %r13d
movl -0x54(%rsp), %edx
movzbl (%r8,%r12), %r10d
xorl %ebp, %ebp
btl %ecx, %r10d
setb %bpl
movzbl (%r8,%r9), %r10d
shrl %cl, %r10d
andl $0x1, %r10d
leal (%rbp,%r10,2), %r10d
testb $0x40, %bl
movzbl %r13b, %esi
movzbl %dl, %ebp
cmovel %esi, %ebp
testl %r10d, %r10d
je 0x5037
cmpl $0xefff, %r11d          # imm = 0xEFFF
ja 0x5037
orq %r14, %r10
movzbl (%r8,%r10), %r10d
movzbl %bpl, %esi
orl %r11d, %esi
movl %esi, %ebp
testb $0x20, %bl
je 0x502e
movl 0x10(%rax,%rbp,4), %esi
movzbl 0x3f00(%r8), %r15d
cmpl 0x38(%rdi,%r15,4), %esi
jne 0x5037
movl 0x38(%rdi,%r10,4), %esi
movl %esi, 0x10(%rax,%rbp,4)
decb %dl
incb %r13b
addl $-0x1, %ecx
jb 0x4fca
movq -0x28(%rsp), %r9
incq %r9
cmpq $0x8, %r9
jne 0x4f8a
movq -0x8(%rsp), %rdx
incq %rdx
cmpq $0x40, %rdx
jne 0x4d7a
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq