/***************************************************************************
    Windows CE GDI Video Routine
 ***************************************************************************/
#include <windows.h>

#include "CE.h"
#include "CEvideo.h"
#include "system.h"
#include "ppp_stdio.h"

/** Various variables ****************************************/
HBITMAP g_hbitmap;

/*************************************************************/
/* GDI : video initialize */
/*************************************************************/
int CEVideo_Init_GDI( int width, int height )
{
    HANDLE  hDIB;
    BITMAPINFOHEADER bi;
    BITMAPINFOHEADER * lpbi;
    DWORD * lpQuad;

    DEBUGLOG( "CEVideo_Init\n" );

	g_width  = width;
	g_height = height;
	if( scanline < 3 ){
	    g_screen_width  = g_width ;
	    g_screen_height = g_height;
	}else{ /* x2 */
	    g_screen_width  = g_width  * 2;
	    g_screen_height = g_height * 2;
	}
    if(videomode==1){
        g_vbuf = (char*)malloc( g_width * g_height * 2 );
        if( g_vbuf == NULL ){
            LOG( "GDI video initialize : Failed\n" );
            return 0;
        }          
    }

    bi.biSize           = sizeof( BITMAPINFOHEADER );
    bi.biWidth          = g_screen_width;
    bi.biHeight         = -g_screen_height;
    bi.biPlanes         = 1;
    bi.biBitCount       = 16;
    bi.biCompression    = BI_BITFIELDS;
    bi.biSizeImage      = 0;
    bi.biXPelsPerMeter  = 0;
    bi.biXPelsPerMeter  = 0;
    bi.biClrUsed        = 0;
    bi.biClrImportant   = 0;

#if _WIN32_WCE >= 300
    hDIB = GlobalAlloc( GHND, sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) ); 
    lpbi = (BITMAPINFOHEADER *)GlobalLock( hDIB );
#else
    hDIB = LocalAlloc( LHND, sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) ); 
    lpbi = (BITMAPINFOHEADER *)LocalLock( hDIB );
#endif
    *lpbi = bi;

    lpQuad = (DWORD*)&((LPBITMAPINFO)lpbi)->bmiColors[0];
    lpQuad[0]=0xF800;
    lpQuad[1]=0x07E0;
    lpQuad[2]=0x001F;

    g_hbitmap = CreateDIBSection( NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS, (void**)&g_vram, NULL, 0 );

#if _WIN32_WCE >= 300
    GlobalUnlock( hDIB );
    GlobalFree( hDIB );
#else
    LocalUnlock( hDIB );
    LocalFree( hDIB );
#endif

    if (g_vram == NULL){
        LOG( "GDI video initialize : Failed\n" );
        return 0;
    }else{
        LOG( "GDI video initialize : OK\n" );
        return 1;
    }
}

/*************************************************************/
/*************************************************************/
void CEVideo_Draw( void )
{
    HDC hDC;
    HDC hbDC;
    DEBUGLOG( "CEVideo_Draw\n" );

    hDC = GetDC(g_hWnd);
    hbDC = CreateCompatibleDC(hDC);
    SelectObject( hbDC, g_hbitmap );
    BitBlt( hDC, systemScrPosX,systemScrPosY, g_screen_width, g_screen_height,hbDC, 0, 0,SRCCOPY ); 
    ReleaseDC( g_hWnd, hDC );
    DeleteDC( hbDC );

    if( scanlineflip ) scanlineflip = 0;
    else scanlineflip = 1;
}

void systemDrawScreen_GDI_NOBUF()
{
    DEBUGLOG( "systemDrawScreen\n" );
    CEVideo_Draw();
}

void systemDrawScreen_GDI_USEBUF()
{
    u8 * delta = 0;

    DEBUGLOG( "systemDrawScreen\n" );

    if(filterFunction) {
        filterFunction((u8*)g_vbuf,				// src buf
                          g_width*2,			// src pitch
                          (u8*)delta,			// no use
                          (u8*)g_vram,			// dst buf
                          g_screen_width*2,		// dst pitch
                          g_width,				// src width
                          g_height );			// src height
    }
    CEVideo_Draw();
}

/*************************************************************/
/*************************************************************/
void CEVideo_Trash_GDI()
{
    DeleteObject( g_hbitmap );
    LOG( "GDI video trash OK\n" );
}

/*************************************************************/
/*************************************************************/
char * CEVideo_GetBufferPtrLine_FULL_GDI_NOBUF(int line)
{
    return (char *)g_vram + g_screen_width * (line) * 2;
}

char * CEVideo_GetBufferPtrLine_FULL_GDI_USEBUF(int line)
{
    return (char *)g_vbuf + g_width * (line) * 2;
}

/*************************************************************/
/*************************************************************/
char * CEVideo_GetBufferPtrLine_HALF_GDI_NOBUF(int line)
{
    if( (line&1)==1 ) return NULL;
    return (char *)g_vram + g_screen_width * (line) * 2;
}

char * CEVideo_GetBufferPtrLine_HALF_GDI_USEBUF(int line)
{
    if( (line&1)==1 ) return NULL;
    return (char *)g_vbuf + g_width * (line) * 2;
}

/*************************************************************/
/*************************************************************/
char * CEVideo_GetBufferPtrLine_INTERLESS_GDI_NOBUF(int line)
{
    if( scanlineflip == 0 ){
        if( (line&1)==1 ) return NULL;
    }else{
        if( (line&1)==0 ) return NULL;
    }
    return (char *)g_vram + g_screen_width * (line) * 2;
}

char * CEVideo_GetBufferPtrLine_INTERLESS_GDI_USEBUF(int line)
{
    if( scanlineflip == 0 ){
        if( (line&1)==1 ) return NULL;
    }else{
        if( (line&1)==0 ) return NULL;
    }
    return (char *)g_vbuf + g_width * (line) * 2;
}

/*************************************************************/
/*************************************************************/
char * CEVideo_GetBufferPtr_GDI_NOBUF(void)
{
    return g_vram;
}

char * CEVideo_GetBufferPtr_GDI_USEBUF(void)
{
    return g_vbuf;
}

/*************************************************************/
/*************************************************************/
void CEVideo_CleanBuffer_GDI_NOBUF(void)
{
    memset( g_vram,0, g_screen_width * g_screen_height * 2 );
}

void CEVideo_CleanBuffer_GDI_USEBUF(void)
{
    memset( g_vbuf,0, g_width * g_height * 2 );
    memset( g_vram,0, g_screen_width * g_screen_height * 2 );
}

/*************************************************************/
/*************************************************************/
void CEVideo_FreeBufferPtr_GDI_NOBUF(void)
{
}

void CEVideo_FreeBufferPtr_GDI_USEBUF(void)
{
    free(g_vbuf);
}
