// File: /workspace/github_cpp_makefile_star2_O1/khedoros[P]khednes/main.cpp
// Function: main
int main(int argc, char ** argv) {
    opterr = 0;
    char option;
    int res=1;
    int mapper=0;
    //cout<<"Argc: "<<argc<<endl;
    if(argc==1) {
        cout<<"Usage:\n\n./"<<argv[0]<<" [-d #] [-m #] <filename>\n\n\tOptions:\n\t-d Enables debug output. Options for # are:\n\t\t1\tCPU\n\t\t2\tMAIN\n\t\t3\tMEM\n\t\t4\tPPU\n\t\t5\tROM\n\t\t6\tUTIL\n\t\t7\tWAV\n\t\t7\tAPU\n";
        cout<<"\n\t-m manually specifies an iNES mapper number to use.\n";
    }

    while(argc>3&&(option=getopt(argc,argv,"d:x:m:"))!=-1) {
        switch(option) {
        case 'd':
            util::toggle_log(atoi(optarg));
            break;
        case 'x':
            res=atoi(optarg);
            break;
        case 'm':
            mapper=atoi(optarg);
            break;
        default:
            cerr<<"Unkown option '"<<optopt<<".\n";
            return 1;
        }
    }
    if(res==0)
        res=1; 
    std::string filename;
    if(optind<argc||argc==2) {
        filename=std::string(argv[optind]);
        cout<<"Loading "<<filename<<"..."<<endl;
    }
    else {
        cout<<"Give a single filename, like this: \n\n\t"<<argv[0]<<" rom.nes"<<endl;        
        return 1;
    }
        
//        if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 ) {
    bool headless = false;
    if( SDL_Init(SDL_INIT_EVERYTHING|SDL_INIT_JOYSTICK|SDL_INIT_GAMECONTROLLER|SDL_INIT_NOPARACHUTE) < 0 ) {
        if( SDL_Init(SDL_INIT_NOPARACHUTE|SDL_INIT_AUDIO) < 0) {
            fprintf(stderr,"Couldn't initialize SDL: %s\n", SDL_GetError());
            exit(1);
        }
        headless = true;
        cout<<"Running in headless mode due to difficulty initializing some SDL subsystems."<<endl;
    }

    //cout<<"Trying to open the joystick (if any)"<<endl;

    SDL_Joystick * js = NULL;
    int jscount = SDL_NumJoysticks();
    if(jscount > 0) {
        for(int i=0;i<jscount;++i) {
            const char * name = SDL_JoystickNameForIndex(i);
            cout<<"Found joystick: "<<name<<endl;
        }
        cout<<"Just opening joystick 0 though"<<endl;
        js = SDL_JoystickOpen(0);
    }

    //cout<<"Done with joystick stuff"<<endl;

    //cout<<"Going to load cartridge"<<endl;
    rom cart(filename, mapper);
    //cout<<"Cart loaded. Going to start ppu"<<endl;
    ppu ppui(cart,res);
    //cout<<"PPU started. Going to start apu."<<endl;
    if(ppui.dummy) {
        headless = true;
        cout<<"PPU started in dummy mode, so audio will too."<<endl;
    }
    apu apui(headless);
    SDL_PauseAudioDevice(apui.get_id(), true);
    //cout<<"APU started. Going to bring up memory map"<<endl;
    mem memi(cart,ppui,apui);
    apui.setmem(&memi);
    //cout<<"Memory started. Going to start CPU"<<endl;
    cpu cpui(&memi,&apui,memi.get_rst_addr(), cart.isNSF());
    //cout<<"CPU started."<<endl;

    if(cart.isNSF()) {
        cout<<"Starting NSF player instead of main emulator"<<endl;
        return run_nsf(cart, apui, memi, cpui);
    }

    bool paused=false;
    //int time_stop;
    //long total_time;
    int pstart = SDL_GetTicks();
    //int delay = 0;
    //long delay_count = 0;
    //long delay_total = 0;
    SDL_PauseAudioDevice(apui.get_id(), false);
    while (1==1) {
        //cout<<"Start of event loop."<<endl;
        //int frame_start = SDL_GetTicks();
        SDL_Event event;
        //int curx,cury;
        int newx,newy;
        //bool changed;
        //cout<<"Polling and handling events"<<endl;
        while(SDL_PollEvent(&event)){  /* Loop until there are no events left on the queue */
            switch(event.type){  /* Process the appropiate event type */
            case SDL_JOYBUTTONDOWN:
            case SDL_JOYBUTTONUP:
                {
                SDL_Scancode sc;
                int button = int(event.jbutton.button);
                int state = int(event.jbutton.state);
                //cout<<"Button: "<<state<<" state: "<<state<<endl;
                cout<<"Saw button: "<<button<<endl;
                switch(button) {
                case 0: sc = SDL_SCANCODE_L; break;
                case 1: sc = SDL_SCANCODE_K; break;
                case 4: sc = SDL_SCANCODE_G; break;
                case 5: sc = SDL_SCANCODE_H; break;
                case 8: sc = SDL_SCANCODE_W; break;
                case 9: sc = SDL_SCANCODE_S; break;
                case 10: sc = SDL_SCANCODE_A; break;
                case 11: sc = SDL_SCANCODE_D; break;
                default: sc = SDL_SCANCODE_UNKNOWN;
                }
                if(state == 1)
                    memi.sendkeydown(sc);
                else
                    memi.sendkeyup(sc);
                }
                break;
            case SDL_JOYDEVICEADDED:
            case SDL_CONTROLLERDEVICEADDED:
                cout<<"Added joystick "<<event.jdevice.which<<": "<<SDL_JoystickNameForIndex(event.jdevice.which)<<endl;
                if(js) {
                    SDL_JoystickClose(js);
                    js = NULL;
                }
                if(!js) {
                    cout<<"No joystick previously connected, so I'm using that one."<<endl;
                    js = SDL_JoystickOpen(event.jdevice.which);
                }
                break;
            case SDL_JOYDEVICEREMOVED:
            case SDL_CONTROLLERDEVICEREMOVED:
                cout<<"Removed joystick: "<<SDL_JoystickNameForIndex(event.jdevice.which)<<endl;
                if(js) {
                    SDL_JoystickClose(js);
                    js = NULL;
                }
                break;
            case SDL_KEYDOWN:  /* Handle a KEYDOWN event */         
                if(event.key.keysym.scancode==SDL_SCANCODE_Q||
                  (event.key.keysym.scancode==SDL_SCANCODE_C&&(event.key.keysym.mod==KMOD_RCTRL))||
                  (event.key.keysym.scancode==SDL_SCANCODE_C&&(event.key.keysym.mod==KMOD_LCTRL))) {
                    printf("You pressed q or ctrl-c. Exiting.\n");
                    cpui.print_details(filename);
                    printf("%d frames rendered in %f seconds. (%f FPS)\n",ppui.get_frame(),float(clock())/float(CLOCKS_PER_SEC),float(ppui.get_frame())/(float(clock())/float(CLOCKS_PER_SEC)));
                    //SDL_PauseAudio(true);
                    cout<<"Calling SDL_Quit()"<<endl;
                    SDL_Quit();
                    cout<<"Called SDL_Quit()"<<endl;
                    return 0;
                }
                else if(event.key.keysym.scancode==SDL_SCANCODE_R) {
                    cpui.reset(memi.get_rst_addr());
                }
                else if(event.key.keysym.scancode==SDL_SCANCODE_P) {
                    paused=!paused;
                    if(paused) {
                        SDL_PauseAudioDevice(apui.get_id(), true);
                        printf("Paused emulation.\n");
                    }
                    else {
                        SDL_PauseAudioDevice(apui.get_id(), false);
                        printf("Unpaused emulation.\n");
                    }
                }
                else if(event.key.keysym.scancode >= SDL_SCANCODE_1 &&
                        event.key.keysym.scancode <= SDL_SCANCODE_0) {

                    std::cout<<"Saw scancode "<<event.key.keysym.scancode<<endl;
                    printf(" debug output #%d",int(event.key.keysym.scancode- (SDL_SCANCODE_1 - 1)));
                    //util::toggle_log(event.key.keysym.scancode-48);
                    printf("\n");
                }
                else if(event.key.keysym.scancode==SDL_SCANCODE_TAB) {
                    ppui.toggle_table_view();
                }
                else {
                    //printf("Keydown\n");
                    //printf("Time: %d\n",SDL_GetTicks());
                    memi.sendkeydown(event.key.keysym.scancode);
                }
                break;
            case SDL_KEYUP: /* Handle a KEYUP event*/
                //printf("Keyup\n");
                memi.sendkeyup(event.key.keysym.scancode);
                break;
            case SDL_MOUSEMOTION:
                memi.sendmousepos(event.motion.x, event.motion.y);
                break;
            case SDL_MOUSEBUTTONDOWN:
                memi.sendmousedown(event.button.x,event.button.y);
                break;
            case SDL_MOUSEBUTTONUP:
                memi.sendmouseup(event.button.x,event.button.y);
                break;
            //case SDL_VIDEORESIZE:
            case SDL_WINDOWEVENT:
                switch(event.window.event) {
                case SDL_WINDOWEVENT_SIZE_CHANGED:
                    newx=event.window.data1;
                    newy=event.window.data2;
                    if(newx > 0 && newy > 0) {
                        //changed=true;
                    }
                    //ppui.resize(newx,newy);
                    break;
                case SDL_WINDOWEVENT_EXPOSED:
                    //ppui.resize(1,1);
                    break;
                }
                break;
            case SDL_QUIT:
                //SDL_PauseAudio(true);
                SDL_Quit();
                cpui.print_details(filename);
                printf("%d frames rendered in %f seconds. (%f FPS)\n",ppui.get_frame(),float(clock())/float(CLOCKS_PER_SEC),float(ppui.get_frame())/(float(clock())/float(CLOCKS_PER_SEC)));
                return 0;
                break;
            default: /* Report an unhandled event */
                //printf("I don't know what this event is! Flushing it.\n");
                SDL_FlushEvent(event.type);
                break;
            }
        }
        if(!paused) {
            //cout<<"Running the CPU"<<endl;
            int cpu_ret=cpui.run_ops();
            //cout<<"Ran the CPU"<<endl;
            if(cpu_ret < 0) {
                return 1;
            }
            else {
                //cout<<"Frame "<<ppui.get_frame()<<endl;

                int apu_id = apui.get_id();
                if(apu_id > 0) {
                    //cout<<"Locking audio...";
                    SDL_LockAudioDevice(apu_id);
                    //cout<<"done."<<endl;
                    apui.set_frame(ppui.get_frame());
                    apui.gen_audio();
                    //apui.dat.buffered += 735; Dude, do this in gen_audio, not here =/
                    //cout<<"Unlocking audio...";
                    SDL_UnlockAudioDevice(apu_id);
                    //cout<<"done."<<endl;
                }
                //cout<<SDL_GetTicks()<<": Frame: "<<ppui.get_frame()<<" Write pos: "<<apui.write_pos<<endl;
                //cout<<"Running the PPU"<<endl;
                int ppu_ret=ppui.calc();
                //cout<<"Ran the PPU"<<endl;
                if(ppu_ret>0) {
                    if(ppu_ret==1) {
                        //cout<<"Triggering NMI in CPU"<<endl;
                        cpui.trigger_nmi();
                    }
                }
            }
        }

        //Calculates the time that the frame should end at, and delays until that time
        //cout<<"Timing two"<<endl;
        int frames = ppui.get_frame();
        int now = SDL_GetTicks();
        int delay = pstart + int(double(frames) * double(1000) / double(60)) - now;
        //cout<<"Frame: "<<frames<<" now: "<<now<<" delay: "<<delay<<endl;       
        if(delay > 0) {
            SDL_Delay(delay);
        }
    }
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x221f8, %rsp          # imm = 0x221F8
movq %rsi, %rbx
movl %edi, %r14d
movq 0x14a3e(%rip), %rax     # 0x1bfc8
movl $0x0, (%rax)
cmpl $0x1, %edi
jne 0x761f
movq 0x14a10(%rip), %r15     # 0x1bfb0
leaq 0xca71(%rip), %rsi      # 0x14018
movl $0xa, %edx
movq %r15, %rdi
callq 0x4410
movq (%rbx), %r12
testq %r12, %r12
je 0x75d8
movq %r12, %rdi
callq 0x41c0
movq 0x149e5(%rip), %rdi     # 0x1bfb0
movq %r12, %rsi
movq %rax, %rdx
callq 0x4410
jmp 0x75f0
movq (%r15), %rax
movq -0x18(%rax), %rax
leaq (%r15,%rax), %rdi
movl 0x20(%r15,%rax), %esi
orl $0x1, %esi
callq 0x45d0
movq 0x149b9(%rip), %r15     # 0x1bfb0
leaq 0xca25(%rip), %rsi      # 0x14023
movl $0x94, %edx
movq %r15, %rdi
callq 0x4410
leaq 0xcaa6(%rip), %rsi      # 0x140b8
movl $0x36, %edx
movq %r15, %rdi
callq 0x4410
cmpl $0x4, %r14d
jl 0x769f
movl $0x0, 0x18(%rsp)
movl $0x1, %ebp
leaq 0xcab6(%rip), %r12      # 0x140ef
movq 0x14958(%rip), %r15     # 0x1bf98
movl %r14d, %edi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x40d0
shll $0x18, %eax
cmpl $0xff000000, %eax       # imm = 0xFF000000
je 0x76ac
sarl $0x18, %eax
cmpl $0x78, %eax
je 0x768d
cmpl $0x6d, %eax
je 0x767f
cmpl $0x64, %eax
jne 0x83fd
movq (%r15), %rdi
callq 0x4550
movl %eax, %edi
callq 0xfdb4
jmp 0x7697
movq (%r15), %rdi
callq 0x4550
movl %eax, 0x18(%rsp)
jmp 0x7697
movq (%r15), %rdi
callq 0x4550
movl %eax, %ebp
cmpl $0x3, %r14d
jg 0x7640
jmp 0x76ac
movl $0x1, %ebp
movl $0x0, 0x18(%rsp)
cmpl $0x1, %ebp
adcl $0x0, %ebp
leaq 0x38(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x148f3(%rip), %rax     # 0x1bfc0
movslq (%rax), %rax
cmpl %r14d, %eax
setge %cl
cmpl $0x2, %r14d
setne %dl
testb %cl, %dl
jne 0x79ad
movq (%rbx,%rax,8), %rsi
leaq 0x990(%rsp), %rdi
leaq 0x468(%rsp), %rdx
callq 0x4170
leaq 0x28(%rsp), %rdi
leaq 0x990(%rsp), %rbx
movq %rbx, %rsi
callq 0x4440
movq (%rbx), %rdi
leaq 0x9a0(%rsp), %rax
cmpq %rax, %rdi
je 0x7728
callq 0x4380
movq 0x14881(%rip), %rdi     # 0x1bfb0
leaq 0xc9d0(%rip), %rsi      # 0x14106
movl $0x8, %edx
callq 0x4410
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq 0x1485f(%rip), %rbx     # 0x1bfb0
movq %rbx, %rdi
callq 0x4410
movq %rax, %r14
leaq 0xc9ac(%rip), %rsi      # 0x1410f
movl $0x3, %edx
movq %rax, %rdi
callq 0x4410
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r14, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movl $0x10f231, %edi         # imm = 0x10F231
callq 0x4350
movl %eax, 0x14(%rsp)
cmpl $0x0, 0x14(%rsp)
jns 0x7804
movl $0x100010, %edi         # imm = 0x100010
callq 0x4350
testl %eax, %eax
js 0x8444
movq 0x147eb(%rip), %r14     # 0x1bfb0
leaq 0xc994(%rip), %rsi      # 0x14160
movl $0x4c, %edx
movq %r14, %rdi
callq 0x4410
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq 0x147b9(%rip), %rdi     # 0x1bfb0
callq 0x4030
movq %rax, %rdi
callq 0x4290
callq 0x4250
movl %eax, %r13d
xorl %r14d, %r14d
testl %eax, %eax
jle 0x78ec
leaq 0xc98f(%rip), %r12      # 0x141ad
movl %r14d, %edi
callq 0x4490
movq %rax, %r15
movl $0x10, %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4410
testq %r15, %r15
je 0x7856
movq %r15, %rdi
callq 0x41c0
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x4410
jmp 0x786d
movq (%rbx), %rax
movq -0x18(%rax), %rax
leaq (%rbx,%rax), %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x45d0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
incl %r14d
cmpl %r14d, %r13d
jne 0x781e
movq 0x1470d(%rip), %r14     # 0x1bfb0
leaq 0xc914(%rip), %rsi      # 0x141be
movl $0x1e, %edx
movq %r14, %rdi
callq 0x4410
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq 0x146db(%rip), %rdi     # 0x1bfb0
callq 0x4030
movq %rax, %rdi
callq 0x4290
xorl %edi, %edi
callq 0x41b0
movq %rax, %r14
leaq 0x90(%rsp), %r15
movq %r15, -0x10(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
leaq 0x80(%rsp), %rdi
callq 0x8d1c
leaq 0x150(%rsp), %rdi
leaq 0x80(%rsp), %rsi
movl 0x18(%rsp), %edx
callq 0x8e3c
movq 0x80(%rsp), %rdi
cmpq %r15, %rdi
je 0x793d
callq 0x4380
leaq 0x990(%rsp), %rdi
leaq 0x150(%rsp), %rsi
movl %ebp, %edx
callq 0xdbc0
cmpb $0x1, 0x221f1(%rsp)
jne 0x79f3
movq 0x14647(%rip), %r15     # 0x1bfb0
leaq 0xc86d(%rip), %rsi      # 0x141dd
movl $0x2d, %edx
movq %r15, %rdi
callq 0x4410
movq (%r15), %rax
addq -0x18(%rax), %r15
movq %r15, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq 0x14615(%rip), %rdi     # 0x1bfb0
callq 0x4030
movb $0x1, %bpl
movq %rax, %rdi
callq 0x4290
jmp 0x79fa
movq 0x145fc(%rip), %r14     # 0x1bfb0
leaq 0xc758(%rip), %rsi      # 0x14113
movl $0x26, %edx
movq %r14, %rdi
callq 0x4410
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x8372
movq %rbx, %rdi
callq 0x41c0
movq 0x145cd(%rip), %rdi     # 0x1bfb0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x4410
jmp 0x838a
movl 0x14(%rsp), %ebp
shrl $0x1f, %ebp
movzbl %bpl, %esi
leaq 0x220(%rsp), %rdi
callq 0x10e1e
leaq 0x220(%rsp), %rdi
callq 0x10866
movl %eax, %edi
movl $0x1, %esi
callq 0x4470
leaq 0xa0(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x990(%rsp), %rdx
leaq 0x220(%rsp), %rcx
callq 0xa65c
leaq 0x220(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x10fa0
leaq 0xa0(%rsp), %rdi
callq 0xae46
movl %eax, %ebp
leaq 0x150(%rsp), %rdi
callq 0xa084
movzbl %al, %r8d
leaq 0x468(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0x220(%rsp), %rdx
movl %ebp, %ecx
callq 0xb484
leaq 0x150(%rsp), %rdi
callq 0xa084
testb %al, %al
je 0x7b22
movq 0x144fb(%rip), %rbx     # 0x1bfb0
leaq 0xc74f(%rip), %rsi      # 0x1420b
movl $0x2c, %edx
movq %rbx, %rdi
callq 0x4410
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq 0x144c9(%rip), %rdi     # 0x1bfb0
callq 0x4030
movq %rax, %rdi
callq 0x4290
leaq 0x150(%rsp), %rdi
leaq 0x220(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
leaq 0x468(%rsp), %rcx
callq 0x8528
movl %eax, 0x8(%rsp)
jmp 0x832b
callq 0x43d0
movl %eax, 0x14(%rsp)
leaq 0x220(%rsp), %rdi
callq 0x10866
movl %eax, %edi
xorl %esi, %esi
callq 0x4470
leaq 0x48(%rsp), %r15
movq $0x0, 0x18(%rsp)
movl $0x0, 0x8(%rsp)
movq %r14, %rax
movq %rax, %r14
movq %r15, %rdi
callq 0x4230
testl %eax, %eax
je 0x7f7b
movl 0x48(%rsp), %edi
cmpl $0x602, %edi            # imm = 0x602
jg 0x7bbf
cmpl $0x3ff, %edi            # imm = 0x3FF
jg 0x7c62
cmpl $0x2ff, %edi            # imm = 0x2FF
jle 0x7d76
cmpl $0x300, %edi            # imm = 0x300
je 0x7dd8
cmpl $0x301, %edi            # imm = 0x301
jne 0x7d91
movl 0x58(%rsp), %esi
leaq 0xa0(%rsp), %rdi
callq 0xa906
movq %r14, %rax
jmp 0x7b5a
cmpl $0x605, %edi            # imm = 0x605
jg 0x7ca3
leal -0x603(%rdi), %eax
cmpl $0x2, %eax
jae 0x7d03
movzbl 0x54(%rsp), %r12d
movb 0x55(%rsp), %bpl
movl $0xc, %edx
movq %rbx, %rdi
leaq 0xc644(%rip), %rsi      # 0x14238
callq 0x4410
movq %rbx, %rdi
movl %r12d, %esi
callq 0x45e0
movq %rax, %r13
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
xorl %esi, %esi
cmpb $0xc, %r12b
jae 0x7c43
movl %r12d, %eax
leaq 0xc7bc(%rip), %rcx      # 0x143fc
movl (%rcx,%rax,4), %esi
cmpb $0x1, %bpl
jne 0x7e37
leaq 0xa0(%rsp), %rdi
callq 0xa81c
movq %r14, %rax
jmp 0x7b5a
cmpl $0x400, %edi            # imm = 0x400
je 0x7d9e
cmpl $0x401, %edi            # imm = 0x401
je 0x7dbb
cmpl $0x402, %edi            # imm = 0x402
jne 0x7d91
movl 0x5c(%rsp), %esi
movl 0x60(%rsp), %edx
leaq 0xa0(%rsp), %rdi
callq 0xa986
movq %r14, %rax
jmp 0x7b5a
cmpl $0x606, %edi            # imm = 0x606
je 0x7cbf
cmpl $0x653, %edi            # imm = 0x653
je 0x7d0f
cmpl $0x654, %edi            # imm = 0x654
jne 0x7d91
movl $0x12, %edx
movq %rbx, %rdi
leaq 0xc5c0(%rip), %rsi      # 0x1428e
callq 0x4410
movl 0x50(%rsp), %edi
callq 0x4490
movq %rax, %r12
testq %rax, %rax
je 0x7e4c
movq %r12, %rdi
callq 0x41c0
movq %rbx, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x4410
jmp 0x7e63
cmpl $0x605, %edi            # imm = 0x605
jne 0x7d91
movl $0xf, %edx
movq %rbx, %rdi
leaq 0xc527(%rip), %rsi      # 0x14245
callq 0x4410
movl 0x50(%rsp), %esi
movq %rbx, %rdi
callq 0x45e0
movq %rax, %r12
movl $0x2, %edx
movq %rax, %rdi
leaq 0xde94(%rip), %rsi      # 0x15bd5
callq 0x4410
movl 0x50(%rsp), %edi
callq 0x4490
movq %rax, %r13
testq %rax, %rax
je 0x7ea7
movq %r13, %rdi
callq 0x41c0
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x4410
jmp 0x7ec2
movq %r14, %rax
cmpl $0x200, %edi            # imm = 0x200
je 0x7b5a
cmpl $0x100, %edi            # imm = 0x100
je 0x8277
callq 0x4670
movq %r14, %rax
jmp 0x7b5a
movl 0x5c(%rsp), %esi
movl 0x60(%rsp), %edx
leaq 0xa0(%rsp), %rdi
callq 0xa97e
movq %r14, %rax
jmp 0x7b5a
movl 0x5c(%rsp), %esi
movl 0x60(%rsp), %edx
leaq 0xa0(%rsp), %rdi
callq 0xa98e
movq %r14, %rax
jmp 0x7b5a
movl 0x58(%rsp), %esi
cmpl $0x14, %esi
je 0x8145
movl 0x60(%rsp), %eax
addl $-0x40, %eax
testl $0xffbf, %eax           # imm = 0xFFBF
sete %al
cmpl $0x6, %esi
jne 0x7e01
testb %al, %al
jne 0x8145
cmpl $0x13, %esi
je 0x8018
cmpl $0x15, %esi
jne 0x7f40
leaq 0xa0(%rsp), %rdi
callq 0xae46
leaq 0x468(%rsp), %rdi
movl %eax, %esi
callq 0xceba
movq %r14, %rax
jmp 0x7b5a
leaq 0xa0(%rsp), %rdi
callq 0xa906
movq %r14, %rax
jmp 0x7b5a
movq (%rbx), %rax
movq -0x18(%rax), %rax
leaq (%rbx,%rax), %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x45d0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movl $0x0, %eax
testq %r14, %r14
je 0x7b5a
movq %r14, %rdi
callq 0x41a0
xorl %eax, %eax
jmp 0x7b5a
movq (%r12), %rax
movq -0x18(%rax), %rax
movq %r12, %rdi
addq %rax, %rdi
movl 0x20(%r12,%rax), %esi
orl $0x1, %esi
callq 0x45d0
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r12, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
testq %r14, %r14
je 0x7ef7
movq %r14, %rdi
callq 0x41a0
movl $0x38, %edx
movq %rbx, %rdi
leaq 0xc34f(%rip), %rsi      # 0x14255
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movl 0x50(%rsp), %edi
callq 0x41b0
jmp 0x7b5a
leal -0x1e(%rsi), %eax
cmpl $0x9, %eax
jbe 0x8077
cmpl $0x2b, %esi
jne 0x7f66
leaq 0x990(%rsp), %rdi
callq 0xfbac
movq %r14, %rax
jmp 0x7b5a
leaq 0xa0(%rsp), %rdi
callq 0xa81c
movq %r14, %rax
jmp 0x7b5a
testb $0x1, 0x18(%rsp)
jne 0x80f2
leaq 0x468(%rsp), %rdi
callq 0xcb82
movl %eax, %r12d
testl %eax, %eax
js 0x80e5
leaq 0x220(%rsp), %rdi
callq 0x10866
movl %eax, %r13d
testl %eax, %eax
jle 0x7ff0
movl %r13d, %edi
callq 0x43a0
leaq 0x990(%rsp), %rdi
callq 0xfb98
leaq 0x220(%rsp), %rdi
movl %eax, %esi
callq 0x1086a
leaq 0x220(%rsp), %rdi
movl $0x2df, %esi            # imm = 0x2DF
callq 0x11294
movl %r13d, %edi
callq 0x45c0
leaq 0x990(%rsp), %rdi
callq 0xef52
cmpl $0x1, %eax
jne 0x80ed
leaq 0x468(%rsp), %rdi
callq 0xcda2
jmp 0x80ed
movq 0x18(%rsp), %rax
movl %eax, %ebp
xorb $0x1, %bpl
testb $0x1, %al
je 0x8046
leaq 0x220(%rsp), %rdi
callq 0x10866
movl %eax, %edi
xorl %esi, %esi
callq 0x4470
leaq 0xc36f(%rip), %rdi      # 0x143b3
jmp 0x8066
leaq 0x220(%rsp), %rdi
callq 0x10866
movl %eax, %edi
movl $0x1, %esi
callq 0x4470
leaq 0xc361(%rip), %rdi      # 0x143c7
callq 0x4540
movl %ebp, %eax
movq %rax, 0x18(%rsp)
jmp 0x7b57
movl $0xd, %edx
movq %rbx, %rdi
leaq 0xc26c(%rip), %rsi      # 0x142f2
callq 0x4410
movl 0x58(%rsp), %esi
movq %rbx, %rdi
callq 0x45e0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r12, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movl 0x58(%rsp), %esi
addl $-0x1d, %esi
leaq 0xc231(%rip), %rdi      # 0x14300
xorl %eax, %eax
callq 0x4050
movl $0xa, %edi
callq 0x44c0
jmp 0x7b57
movl $0x1, 0x8(%rsp)
testl %r12d, %r12d
js 0x813e
leaq 0x990(%rsp), %rdi
callq 0xfb98
movl %eax, %r12d
callq 0x43d0
xorps %xmm0, %xmm0
cvtsi2sd %r12d, %xmm0
mulsd 0xbef1(%rip), %xmm0     # 0x14008
divsd 0xbef1(%rip), %xmm0     # 0x14010
cvttsd2si %xmm0, %edi
addl 0x14(%rsp), %edi
subl %eax, %edi
movb $0x1, %bpl
testl %edi, %edi
jle 0x8322
callq 0x42d0
jmp 0x8322
xorl %ebp, %ebp
jmp 0x8322
leaq 0xc28d(%rip), %rdi      # 0x143d9
callq 0x4540
leaq 0x468(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0xb596
leaq 0x990(%rsp), %rdi
callq 0xfb98
movl %eax, %r12d
callq 0x4270
movq %rax, %r13
leaq 0x990(%rsp), %rdi
callq 0xfb98
xorps %xmm0, %xmm0
cvtsi2ss %r13, %xmm0
movss 0xbe6c(%rip), %xmm1     # 0x14004
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
movss %xmm0, 0x24(%rsp)
callq 0x4270
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0xbe3c(%rip), %xmm0     # 0x14004
movss 0x24(%rsp), %xmm1
divss %xmm0, %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0xc0c4(%rip), %rdi      # 0x142a1
movl %r12d, %esi
movsd 0x8(%rsp), %xmm0
movb $0x2, %al
callq 0x4050
movl $0x12, %edx
movq %rbx, %rdi
leaq 0xc0d1(%rip), %rsi      # 0x142cd
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
callq 0x4090
movl $0x11, %edx
movq %rbx, %rdi
leaq 0xc0a4(%rip), %rsi      # 0x142e0
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
xorl %ebp, %ebp
movq %rax, %rdi
callq 0x4290
movl $0x0, 0x8(%rsp)
jmp 0x8322
callq 0x4090
leaq 0x468(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0xb596
leaq 0x990(%rsp), %rdi
callq 0xfb98
movl %eax, %r12d
callq 0x4270
movq %rax, %r13
leaq 0x990(%rsp), %rdi
callq 0xfb98
xorps %xmm0, %xmm0
cvtsi2ss %r13, %xmm0
movss 0xbd41(%rip), %xmm1     # 0x14004
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
movss %xmm0, 0x24(%rsp)
callq 0x4270
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0xbd11(%rip), %xmm0     # 0x14004
movss 0x24(%rsp), %xmm1
divss %xmm0, %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0xbf99(%rip), %rdi      # 0x142a1
movl %r12d, %esi
movsd 0x8(%rsp), %xmm0
movb $0x2, %al
callq 0x4050
xorl %ebp, %ebp
movl $0x0, 0x8(%rsp)
testb %bpl, %bpl
jne 0x7b57
leaq 0x468(%rsp), %rdi
callq 0xbade
leaq 0xa0(%rsp), %rdi
callq 0xa7d6
leaq 0x220(%rsp), %rdi
callq 0x11db8
leaq 0x990(%rsp), %rdi
callq 0xdf8c
leaq 0x150(%rsp), %rdi
callq 0xa0d8
movl 0x8(%rsp), %ebx
jmp 0x83d5
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x45d0
movq 0x13c1f(%rip), %rbx     # 0x1bfb0
leaq 0xbda2(%rip), %rsi      # 0x1413a
movl $0x8, %edx
movq %rbx, %rdi
callq 0x4410
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq 0x13bed(%rip), %rdi     # 0x1bfb0
callq 0x4030
movl $0x1, %ebx
movq %rax, %rdi
callq 0x4290
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x83e9
callq 0x4380
movl %ebx, %eax
addq $0x221f8, %rsp          # imm = 0x221F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x13bec(%rip), %rbx     # 0x1bff0
leaq 0xbceb(%rip), %rsi      # 0x140f6
movl $0xf, %edx
movq %rbx, %rdi
callq 0x4410
movq 0x13b89(%rip), %rax     # 0x1bfa8
movl (%rax), %esi
movq %rbx, %rdi
callq 0x45e0
leaq 0xc14f(%rip), %rsi      # 0x1457f
movl $0x2, %edx
movq %rax, %rdi
callq 0x4410
movl $0x1, %ebx
jmp 0x83e9
movq 0x13b6d(%rip), %rax     # 0x1bfb8
movq (%rax), %rbx
callq 0x42f0
leaq 0xbce9(%rip), %rsi      # 0x14143
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x4510
movl $0x1, %edi
callq 0x4420
jmp 0x84a6
jmp 0x849c
jmp 0x84a1
movq %rax, %rbx
jmp 0x84ff
movq %rax, %rbx
movq 0x80(%rsp), %rdi
cmpq %r15, %rdi
je 0x850c
callq 0x4380
jmp 0x850c
jmp 0x84c1
jmp 0x84c1
jmp 0x84c8
movq %rax, %rbx
jmp 0x84e5
movq %rax, %rbx
jmp 0x84f2
movq %rax, %rbx
jmp 0x84d8
jmp 0x84c1
jmp 0x84c8
jmp 0x84c1
jmp 0x84c8
jmp 0x84c8
jmp 0x84c8
jmp 0x84c8
jmp 0x84c8
jmp 0x84c1
jmp 0x84c8
jmp 0x84c8
movq %rax, %rbx
jmp 0x850c
jmp 0x84c8
movq %rax, %rbx
leaq 0x468(%rsp), %rdi
callq 0xbade
leaq 0xa0(%rsp), %rdi
callq 0xa7d6
leaq 0x220(%rsp), %rdi
callq 0x11db8
leaq 0x990(%rsp), %rdi
callq 0xdf8c
leaq 0x150(%rsp), %rdi
callq 0xa0d8
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x8520
callq 0x4380
movq %rbx, %rdi
callq 0x4610