#include "glN64.h"
#include "Types.h"
#include "VI.h"
#include "OpenGL.h"
#include "N64.h"
#include "gSP.h"
#include "gDP.h"
#include "RSP.h"
#include "FrameBuffer.h"
#include "Debug.h"

VIInfo VI;

void VI_UpdateSize()
{
    f32 xScale = _FIXED2FLOAT( _SHIFTR( *REG.VI_X_SCALE, 0, 12 ), 10 );
    //f32 xOffset = _FIXED2FLOAT( _SHIFTR( *REG.VI_X_SCALE, 16, 12 ), 10 );

    f32 yScale = _FIXED2FLOAT( _SHIFTR( *REG.VI_Y_SCALE, 0, 12 ), 10 );
    //f32 yOffset = _FIXED2FLOAT( _SHIFTR( *REG.VI_Y_SCALE, 16, 12 ), 10 );

    u32 hEnd = _SHIFTR( *REG.VI_H_START, 0, 10 );
    u32 hStart = _SHIFTR( *REG.VI_H_START, 16, 10 );

    // These are in half-lines, so shift an extra bit
    u32 vEnd = _SHIFTR( *REG.VI_V_START, 1, 9 );
    u32 vStart = _SHIFTR( *REG.VI_V_START, 17, 9 );

    VI.width = (unsigned int)((hEnd - hStart) * xScale);
    VI.height = (unsigned int)((vEnd - vStart) * yScale * 1.0126582f);

    if (VI.width < 320) VI.width = 320;
    if (VI.height < 240) VI.height = 240;
}

void VI_UpdateScreen()
{
    glFinish();

    if (OGL.frameBufferTextures)
    {
        FrameBuffer *current = FrameBuffer_FindBuffer( *REG.VI_ORIGIN );

        if ((*REG.VI_ORIGIN != VI.lastOrigin) || ((current) && current->changed))
        {
            if (gDP.colorImage.changed)
            {
                FrameBuffer_SaveBuffer( gDP.colorImage.address, gDP.colorImage.size, gDP.colorImage.width, gDP.colorImage.height );
                gDP.colorImage.changed = FALSE;
            }

            FrameBuffer_RenderBuffer( *REG.VI_ORIGIN );

            gDP.colorImage.changed = FALSE;
            VI.lastOrigin = *REG.VI_ORIGIN;
#ifdef DEBUG
            while (Debug.paused && !Debug.step);
            Debug.step = FALSE;
#endif
        }
    }
    else
    {
        if (gSP.changed & CHANGED_COLORBUFFER)
        {
#ifndef __LINUX__
            SwapBuffers( OGL.hDC );
#else
            OGL_SwapBuffers();
#endif
            gSP.changed &= ~CHANGED_COLORBUFFER;
#ifdef DEBUG
            while (Debug.paused && !Debug.step);
            Debug.step = FALSE;
#endif
        }
    }
    glFinish();
}

