// File: khedoros[P]khednes/compositor.cpp
// Function: compositor::flip()
void compositor::flip() {
    if(!render) return;

    SDL_Rect spr_render;
    spr_render.x = spr_render.y = 0; spr_render.w = 256; spr_render.h = 240;
    SDL_Rect spr_tv;
    spr_tv.x = 512; spr_tv.y = 0; spr_tv.w = 256; spr_tv.h = 240;

    SDL_Rect nt_render;
    nt_render.x = nt_render.y = 0; nt_render.w = 256; nt_render.h = 240;
    SDL_Rect nt_tv;
    nt_tv.x = nt_tv.y = 0; nt_tv.w = 512; nt_tv.h = 480;

    SDL_Rect all;
    all.x = all.y = 0; all.w = cur_x_res; all.h = cur_y_res;

    if(!buffer) {
        cout<<"Buffer is null; not flipping nuttin'!"<<endl;
        return;
    }
    else if(!(buffer->format->palette)) {
        cout<<"Palette is null; not flipping"<<endl;
    }

    //Draw low priority sprites, then all necessary sections of the background, then high priority sprites, then the overlay
    if(!tv) {

        SDL_BlitSurface(lps,NULL,buffer,&spr_render); //Draw low-priority sprites

        int ys = 0;
        while(nt_regions.size() != 0) { //Draw each section of the background that needs drawn
            SDL_Rect * v = nt_regions.front();
            nt_regions.pop_front();
            nt_render.y = ys;
            ys += v->h;
            SDL_BlitSurface(nt,v,buffer,&nt_render);
            delete v;
        }

        SDL_BlitSurface(hps,NULL,buffer,&spr_render); //Draw the high-priority sprites

    }
    else {
        SDL_BlitSurface(lps,NULL,buffer,&spr_tv); //Draw low-priority sprites
        SDL_BlitSurface(nt,NULL,buffer,&all); //Draw entire real-address name table
        { //Draw the extra name table crap
            SDL_Rect special;
            //Top-right mirror of table 1 + 3
            special.x = 512;
            special.y = 0;
            special.w = 256;
            special.h = 480;
            SDL_BlitSurface(nt,&special,buffer,&all);

            //Bottom-right mirror of table 1
            special.y = 480;
            special.h = 240;
            SDL_BlitSurface(nt,&special,buffer,&all);

            //Bottom-left mirror of table 1 +2
            special.x = 0;
            special.w = 512;
            SDL_BlitSurface(nt,&special,buffer,&all);
        }
        
        SDL_BlitSurface(hps,NULL,buffer,&spr_tv); //Draw the high-priority sprites
        //wait(20);
    }

    SDL_BlitSurface(overlay,NULL,buffer,&all); //Put the pset'ed overlay on top

    SDL_DestroyTexture(texture);

    texture = SDL_CreateTextureFromSurface(render, buffer);

    SDL_RenderClear(render);
    SDL_RenderCopy(render,texture,NULL,NULL);
    SDL_RenderPresent(render);

    //Clear all buffers
    fill(NES_TRANSPARENT, overlay);
    fill(NES_TRANSPARENT, lps);
    fill(NES_TRANSPARENT, nt);
    fill(NES_TRANSPARENT, hps);

    //if(!delay)
        //wait(10);
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x8(%rax)
jne 0x25678
jmp 0x25a16
movq 0x8(%rsp), %rax
movl $0x0, 0x74(%rsp)
movl $0x0, 0x70(%rsp)
movl $0x100, 0x78(%rsp)      # imm = 0x100
movl $0xf0, 0x7c(%rsp)
movl $0x200, 0x60(%rsp)      # imm = 0x200
movl $0x0, 0x64(%rsp)
movl $0x100, 0x68(%rsp)      # imm = 0x100
movl $0xf0, 0x6c(%rsp)
movl $0x0, 0x54(%rsp)
movl $0x0, 0x50(%rsp)
movl $0x100, 0x58(%rsp)      # imm = 0x100
movl $0xf0, 0x5c(%rsp)
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
movl $0x200, 0x48(%rsp)      # imm = 0x200
movl $0x1e0, 0x4c(%rsp)      # imm = 0x1E0
movl $0x0, 0x34(%rsp)
movl $0x0, 0x30(%rsp)
movl 0x178(%rax), %ecx
movl %ecx, 0x38(%rsp)
movl 0x17c(%rax), %ecx
movl %ecx, 0x3c(%rsp)
cmpq $0x0, 0x10(%rax)
jne 0x2574f
movq 0x11881(%rip), %rdi     # 0x36fb0
leaq 0x7a38(%rip), %rsi      # 0x2d16e
callq 0x43c0
movq %rax, %rdi
movq 0x1184b(%rip), %rsi     # 0x36f90
callq 0x4400
jmp 0x25a16
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
cmpq $0x0, 0x8(%rax)
jne 0x25785
movq 0x11846(%rip), %rdi     # 0x36fb0
leaq 0x7a23(%rip), %rsi      # 0x2d194
callq 0x43c0
movq %rax, %rdi
movq 0x11810(%rip), %rsi     # 0x36f90
callq 0x4400
jmp 0x25787
movq 0x8(%rsp), %rax
testb $0x1, 0x188(%rax)
jne 0x2586e
movq 0x8(%rsp), %rax
movq 0x28(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x70(%rsp), %rcx
callq 0x4320
movl $0x0, 0x2c(%rsp)
movq 0x8(%rsp), %rdi
addq $0x190, %rdi            # imm = 0x190
callq 0x262d0
cmpq $0x0, %rax
je 0x2584e
movq 0x8(%rsp), %rdi
addq $0x190, %rdi            # imm = 0x190
callq 0x26300
movq 0x8(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x20(%rsp)
addq $0x190, %rdi            # imm = 0x190
callq 0x26330
movq 0x8(%rsp), %rax
movl 0x2c(%rsp), %ecx
movl %ecx, 0x54(%rsp)
movq 0x20(%rsp), %rcx
movl 0xc(%rcx), %ecx
addl 0x2c(%rsp), %ecx
movl %ecx, 0x2c(%rsp)
movq 0x30(%rax), %rdi
movq 0x20(%rsp), %rsi
movq 0x10(%rax), %rdx
leaq 0x50(%rsp), %rcx
callq 0x4320
movq 0x20(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x25849
movq (%rsp), %rdi
callq 0x4390
jmp 0x257bc
movq 0x8(%rsp), %rax
movq 0x38(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x70(%rsp), %rcx
callq 0x4320
jmp 0x25953
movq 0x8(%rsp), %rax
movq 0x28(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x60(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movq 0x30(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x30(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movl $0x200, 0x10(%rsp)      # imm = 0x200
movl $0x0, 0x14(%rsp)
movl $0x100, 0x18(%rsp)      # imm = 0x100
movl $0x1e0, 0x1c(%rsp)      # imm = 0x1E0
movq 0x30(%rax), %rdi
movq 0x10(%rax), %rdx
leaq 0x10(%rsp), %rsi
leaq 0x30(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movl $0x1e0, 0x14(%rsp)      # imm = 0x1E0
movl $0xf0, 0x1c(%rsp)
movq 0x30(%rax), %rdi
movq 0x10(%rax), %rdx
leaq 0x10(%rsp), %rsi
leaq 0x30(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movl $0x0, 0x10(%rsp)
movl $0x200, 0x18(%rsp)      # imm = 0x200
movq 0x30(%rax), %rdi
movq 0x10(%rax), %rdx
leaq 0x10(%rsp), %rsi
leaq 0x30(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movq 0x38(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x60(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0x30(%rsp), %rcx
callq 0x4320
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0x42c0
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
movq 0x10(%rax), %rsi
callq 0x4510
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x8(%rax), %rdi
callq 0x4380
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
movq 0x18(%rax), %rsi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x4420
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x40b0
movq 0x8(%rsp), %rdi
movq 0x20(%rdi), %rdx
movl $0x4a, %esi
callq 0x25a20
movq 0x8(%rsp), %rdi
movq 0x28(%rdi), %rdx
movl $0x4a, %esi
callq 0x25a20
movq 0x8(%rsp), %rdi
movq 0x30(%rdi), %rdx
movl $0x4a, %esi
callq 0x25a20
movq 0x8(%rsp), %rdi
movq 0x38(%rdi), %rdx
movl $0x4a, %esi
callq 0x25a20
addq $0x88, %rsp
retq
nop