// File: khedoros[P]khednes/ppu3.cpp
// Function: ppu::s0_hit_cycle(unsigned int)
unsigned int ppu::s0_hit_cycle(unsigned int cycle) {
    //TODO: This is an inexact estimate. It needs fixed, sometime.
    //      (Better than the last version of the estimate, though ;-)
    if(recalc_s0) {
        if(sprites[0].y + 1 > 239) spr_hit0_cycle = -1;
        else {
            int spry = sprites[0].y + 1;
            int sprx = sprites[0].x;
            bool hf = sprites[0].hflip;
            bool vf = sprites[0].vflip;
            int palnum = sprites[0].pal | 4;
            int tile = sprites[0].tile;
            int table = control0.sprite_table;
            SDL_Surface * s = get_Surface(table, tile, palnum, hf, vf);
            int px = -1;
            int py = -1;
            for(int x = 0; x < 8; ++x)
                for(int y = 0; y < 8; ++y) {
                    unsigned char t =((unsigned char *)s->pixels)[y*(s->pitch)+x];
                    if(t != NES_TRANSPARENT) {
                        px = x; py = y; /*cout<<"x: "<<x<<" y: "<<y<<" val: "<<int(t)<<endl;*/ goto loop_exit;
                    }
                }
            loop_exit:
            if(px == -1) spr_hit0_cycle = -1;
            else spr_hit0_cycle = ((spry + 1 + py) * CLK_PER_LINE + sprx + px);
            recalc_s0 = false;
        }
    }
    return spr_hit0_cycle;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movl %esi, 0x4c(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
testb $0x1, 0x6d5(%rax)
je 0x1df4f
movq 0x8(%rsp), %rax
movl 0x208(%rax), %eax
andl $0xff, %eax
addl $0x1, %eax
cmpl $0xef, %eax
jle 0x1ddc2
movq 0x8(%rsp), %rax
movl $0xffffffff, 0x6d0(%rax) # imm = 0xFFFFFFFF
jmp 0x1df4d
movq 0x8(%rsp), %rdi
movl 0x208(%rdi), %eax
andl $0xff, %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
movl 0x208(%rdi), %eax
shrl $0x18, %eax
movl %eax, 0x44(%rsp)
movl 0x208(%rdi), %eax
shrl $0x16, %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x43(%rsp)
movl 0x208(%rdi), %eax
shrl $0x17, %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x42(%rsp)
movl 0x208(%rdi), %eax
shrl $0x10, %eax
andl $0x3, %eax
orl $0x4, %eax
movl %eax, 0x3c(%rsp)
movl 0x208(%rdi), %eax
shrl $0x8, %eax
andl $0xff, %eax
movl %eax, 0x38(%rsp)
movb 0x21850(%rdi), %al
shrb $0x3, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x34(%rsp)
movl 0x34(%rsp), %esi
movl 0x38(%rsp), %edx
movl 0x3c(%rsp), %ecx
movb 0x43(%rsp), %al
andb $0x1, %al
movzbl %al, %r8d
movb 0x42(%rsp), %al
andb $0x1, %al
movzbl %al, %r9d
callq 0x1df60
movq %rax, 0x28(%rsp)
movl $0xffffffff, 0x24(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x20(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x1c(%rsp)
cmpl $0x8, 0x1c(%rsp)
jge 0x1df03
movl $0x0, 0x18(%rsp)
cmpl $0x8, 0x18(%rsp)
jge 0x1def4
movq 0x28(%rsp), %rax
movq 0x20(%rax), %rax
movl 0x18(%rsp), %ecx
movq 0x28(%rsp), %rdx
imull 0x18(%rdx), %ecx
addl 0x1c(%rsp), %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, 0x17(%rsp)
movzbl 0x17(%rsp), %eax
cmpl $0x4a, %eax
je 0x1dee5
movl 0x1c(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x18(%rsp), %eax
movl %eax, 0x20(%rsp)
jmp 0x1df05
jmp 0x1dee7
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x1de9e
jmp 0x1def6
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x1de8f
jmp 0x1df05
cmpl $-0x1, 0x24(%rsp)
jne 0x1df1d
movq 0x8(%rsp), %rax
movl $0xffffffff, 0x6d0(%rax) # imm = 0xFFFFFFFF
jmp 0x1df41
movq 0x8(%rsp), %rax
movl 0x48(%rsp), %ecx
addl $0x1, %ecx
addl 0x20(%rsp), %ecx
imull $0x155, %ecx, %ecx      # imm = 0x155
addl 0x44(%rsp), %ecx
addl 0x24(%rsp), %ecx
movl %ecx, 0x6d0(%rax)
movq 0x8(%rsp), %rax
movb $0x0, 0x6d5(%rax)
jmp 0x1df4f
movq 0x8(%rsp), %rax
movl 0x6d0(%rax), %eax
addq $0x58, %rsp
retq
nop