#define RELAXCASE
#define CHEAT5000
//#define LIGHTGUN 1
//#define USE_DEBUGCLIENT
//#define NO_CONFIGURATION

#include <XBApp.h>
#include <XBFont.h>
#include <XBHelp.h>
#include <XBSound.h>
#include <xgraphics.h>
#include <assert.h>
#include <d3d8perf.h>
#include "SndXBOX.hxx"
//#include "CDDAXbox.h"
#include <stdio.h>
#include <vector>
//#include "unzip.h"
#include "undocumented.h"
#include "iosupport.h"
#include "panel.h"
#include "custom_launch_params.h"
#include "keyboard_api.h"
#include "gamescreen.h"
//#include "SDL.h"
//#include "disksys.h"


#ifdef LIGHTGUN
#include "lightgun.h"
#endif

DWORD g_dwSoundThreadId ;
HANDLE g_hSoundThread ;

#ifdef __cplusplus
extern "C" {
#endif

void debug_printf(char *, ...);
void bormain(int argc, char **argv);

#define uint8 unsigned char
#define uint32 unsigned int

void _2xSaI(uint8 *srcPtr, uint32 srcPitch,
		 uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void _2xSaIScanline(uint8 *srcPtr, uint32 srcPitch,
		 uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void SuperEagle(uint8 *srcPtr, uint32 srcPitch,
		uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void SuperEagleScanline(uint8 *srcPtr, uint32 srcPitch,
		uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void Super2xSaI(uint8 *srcPtr, uint32 srcPitch,
		 uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void Super2xSaIScanline(uint8 *srcPtr, uint32 srcPitch,
		 uint8 *deltaPtr,
		 uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void Scale2x(uint8 *srcPtr, uint32 srcPitch,
	     uint8 *deltaPtr,
	     uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void SuperScale(uint8 *srcPtr, uint32 srcPitch,
	     uint8 *deltaPtr,
	     uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void SuperScaleScanline(uint8 *srcPtr, uint32 srcPitch,
	     uint8 *deltaPtr,
	     uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void Eagle(uint8 *srcPtr, uint32 srcPitch,
	     uint8 *deltaPtr,
	     uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);
void EagleScanline(uint8 *srcPtr, uint32 srcPitch,
	     uint8 *deltaPtr,
	     uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode);

void Simple2x(unsigned char *srcPtr, uint32 srcPitch, unsigned char * /* deltaPtr */,
              unsigned char *dstPtr, uint32 dstPitch, int width, int height, int scanlines) ;
void AdMame2x(unsigned char *srcPtr, uint32 srcPitch, unsigned char * /* deltaPtr */,
              unsigned char *dstPtr, uint32 dstPitch, int width, int height, int scanline) ;


unsigned int xbox_get_pitch();
unsigned char * xbox_get_screen_buffer() ;
int xbox_read_sector_type( unsigned int sector, unsigned int sector_type ) ;
void sprintfx( const char *fmt, ... );
//extern int iFastFwd ;
//int LoadState(char *file) ;
//int SaveState(char *file) ;
//extern int Running;
//int psx_WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) ;

//_CRTIMP extern int * __cdecl errno(void);
char gxmsg[2050] ;

//int errno ;

#ifdef __cplusplus
}
#endif

//_CRTIMP int * __cdecl _errno(void);
//_CRTIMP int errno;

typedef struct tagBITMAPINFOHEADER{
      DWORD  biSize;
      DWORD  biWidth;
      DWORD  biHeight;
      WORD   biPlanes;
      WORD   biBitCount ;
      DWORD  biCompression;
      DWORD  biSizeImage;
      DWORD  biXPelsPerMeter;
      DWORD  biYPelsPerMeter;
      DWORD  biClrUsed;
      DWORD  biClrImportant;

   } BITMAPINFOHEADER;

typedef struct tagRGBQUAD {
  BYTE    rgbBlue; 
  BYTE    rgbGreen; 
  BYTE    rgbRed; 
  BYTE    rgbReserved; 
} RGBQUAD; 

typedef struct BMP
{
	BITMAPINFOHEADER						BitmapInfoHeader;
	RGBQUAD									Palette[256];
} BMP;


#pragma warning(disable:4244)
#pragma warning(disable:4018)
#pragma warning(disable:4101)

#define PLATFORM_NAME "OPENBORX"
#define PLATFORM_SAV L"OPENBORXSAV"
#define READING_ROMS_STRING L"Reading a26roms directory...please wait."
#define PLATFORM_INI "openborx.ini"
#define PLAYTHING_INI "plaything.cfg"
//#define PLATFORM_MEMORY_POINTER internalRAM
#define PLATFORM_MEMORY_POINTER NULL
#define THEMEMUSIC "D:\\OPENBORX.MP3"
#define PLATFORM_FILE_DIR m_defaultRomDir
#define DEFAULT_PARENT_DIR "D:\\openborx\\*"
#define CD_BUF_SECTORS 1
#define CD_DATA_BUFFER_SIZE CD_BUF_SECTORS*2352
#define PROJECTILE_DEF 4 
#define DEFAULT_SKIN "default_openborx"
#define DEFAULT_SKIN_DIR "D:\\EMUSKINS"
#define MAIN_MENU_STRING L"OpenBORX Main Menu"
#define MLINE 
#define DEFAULT_SAVE_PATH "E:\\SAVES\\OPENBORX"
//#define GAME_GENIE 1
#define EMU_RECORDING_SIZE ( sizeof(DWORD)*4*60*60*10 )

#define GAMESHARK_GBA_TYPE 0x01
#define GAMESHARK_GBC_TYPE 0x02
#define CODEBREAKER_TYPE   0x03

int CODE_LENGTHS[] = { 12, 16, 8, 12 } ;



#define CONSOLE_MEMORY_SIZE 128
unsigned char *m_memory_locations[] = { NULL } ;
unsigned int  m_memory_sizes[] = { 128 } ;

#define NUM_MEMORY_LOCATIONS 1

byte keyboard_keystate[256] ;



#define XBOX_DPAD_UP          0x00000001
#define XBOX_DPAD_DOWN        0x00000002
#define XBOX_DPAD_LEFT        0x00000004
#define XBOX_DPAD_RIGHT       0x00000008
#define XBOX_START            0x00000010
#define XBOX_BACK             0x00000020
#define XBOX_LEFT_THUMB       0x00000040
#define XBOX_RIGHT_THUMB      0x00000080

#define XBOX_A                0x00000100
#define XBOX_B                0x00000200
#define XBOX_X                0x00000400
#define XBOX_Y                0x00000800
#define XBOX_BLACK            0x00001000
#define XBOX_WHITE            0x00002000
#define XBOX_LEFT_TRIGGER     0x00004000
#define XBOX_RIGHT_TRIGGER    0x00008000

#define XBOX_LTHUMB_UP        0x00010000
#define XBOX_LTHUMB_DOWN      0x00020000
#define XBOX_LTHUMB_LEFT      0x00040000
#define XBOX_LTHUMB_RIGHT     0x00080000

#define XBOX_RTHUMB_UP        0x00100000
#define XBOX_RTHUMB_DOWN      0x00200000
#define XBOX_RTHUMB_LEFT      0x00400000
#define XBOX_RTHUMB_RIGHT     0x00800000



#define INPUT_FIRE     0x01
#define INPUT_UP       0x02
#define INPUT_DOWN     0x04
#define INPUT_LEFT     0x08
#define INPUT_RIGHT    0x10
#define INPUT_BG_T     0x20
#define INPUT_BG_B     0x40
#define INPUT_RESET    0x80
#define INPUT_SELECT   0x100
#define INPUT_DIFF1    0x200
#define INPUT_DIFF2    0x400
#define INPUT_PAD0     0x800
#define INPUT_PAD1     0x1000
#define INPUT_PAD2     0x2000
#define INPUT_PAD3     0x4000
#define INPUT_PAD4     0x8000
#define INPUT_PAD5     0x10000
#define INPUT_PAD6     0x20000
#define INPUT_PAD7     0x40000
#define INPUT_PAD8     0x80000
#define INPUT_PAD9     0x100000
#define INPUT_PADPOUND 0x200000
#define INPUT_PADSTAR  0x400000



#define DEFAULT_BUTTON1  XBOX_A
#define DEFAULT_BUTTON2  XBOX_DPAD_UP
#define DEFAULT_BUTTON3  XBOX_DPAD_DOWN
#define DEFAULT_BUTTON4  XBOX_DPAD_LEFT
#define DEFAULT_BUTTON5  XBOX_DPAD_RIGHT
#define DEFAULT_BUTTON6  XBOX_B
#define DEFAULT_BUTTON7  XBOX_X
#define DEFAULT_BUTTON8  XBOX_START
#define DEFAULT_BUTTON9  XBOX_BACK
#define DEFAULT_BUTTON10 XBOX_WHITE
#define DEFAULT_BUTTON11 XBOX_BLACK
#define DEFAULT_BUTTON12 0
#define DEFAULT_BUTTON13 0
#define DEFAULT_BUTTON14 0
#define DEFAULT_BUTTON15 0
#define DEFAULT_BUTTON16 0
#define DEFAULT_BUTTON17 0
#define DEFAULT_BUTTON18 0
#define DEFAULT_BUTTON19 0
#define DEFAULT_BUTTON20 0
#define DEFAULT_BUTTON21 0
#define DEFAULT_BUTTON22 0
#define DEFAULT_BUTTON23 0
#define DEFAULT_BUTTON24 0
#define DEFAULT_BUTTON25 0
#define DEFAULT_BUTTON26 0
#define DEFAULT_BUTTON27 0
#define DEFAULT_BUTTON28 0
#define DEFAULT_BUTTON29 0
#define DEFAULT_BUTTON30 0
#define DEFAULT_BUTTON31 0
#define DEFAULT_BUTTON32 0


typedef struct _cheat_code { 
	char code[20] ;
	byte type ;
	UINT32 adr ;
	UINT32 val ;
	byte   enabled ;
	char desc[100] ;
} CHEAT_CODE;

typedef struct _NETPLAY_SERVER {
	char ip[16] ; 
} NETPLAY_SERVER;

typedef struct _favoritestruct {
	char filename[MAX_PATH] ;
} FAVORITE ;



//-----------------------------------------------------------------------------
// Name: class CXBoxSample
// Desc: Main class to run this application. Most functionality is inherited
//       from the CXBApplication base class.
//-----------------------------------------------------------------------------
class CXBoxSample : public CXBApplication
{
public:
    CXBoxSample();

    virtual HRESULT Initialize();
    virtual HRESULT InitializeWithScreen();
    virtual void    InitializeEmuSpecific();
    virtual HRESULT Render();
    virtual HRESULT FrameMove();
	virtual void    initConsole( UINT32 idx, int isFavorite, int forceConfig ) ;
	virtual void    cleanupConsole( ) ;
	virtual unsigned int     handleEvents() ;
	virtual int     init_texture() ;
	virtual void    doScreenSize();
	virtual BOOL    SetRefreshRate(INT iRefreshRate);
	virtual int		init_white_texture();
	virtual int		render_to_texture( unsigned char *buf) ;
	virtual void    saveSettings( char *filename );
	virtual int     loadSettings( char *filename );
	void            doChangeVideoMode( );
	virtual void    emuLaunch( unsigned int gameSelected, unsigned int isFavorite, int forceConfig ) ;
	void            setPalette( unsigned char *palette) ;
	virtual int     pollXBoxControllers( );

	virtual void	UpdatePalette(void);
	
	virtual void    xboxChangeFilter() ;
	void            ClearScreen() ;
	virtual void    processEmu( BOOL render ) ;
	virtual void    fillPresentationParams() ;
	void			MenuBar( int xpos, int ypos, int xlen, int ylen ) ;
	virtual void    GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b);
	virtual void    SetPalette(uint8 index, uint8 r, uint8 g, uint8 b);

	

	D3DCOLOR m_color_palette[256];
	int m_country ;
	int m_refreshRate ;
	int					m_smsFPS ;
	int m_skipNext ;
	float m_fGamma ;
	int m_useFM ;


	DWORD m_startTime ;
	int m_changedGenie ;
	DWORD m_joypad ;
	DWORD m_zapperDat[3] ;
	D3DCOLOR			color_palette[256];
	int                 PaletteChanged ;	
	DWORD m_xboxControllers[4] ;
	DWORD m_prevEmuControllers[4] ;
	DWORD m_emuControllers[4] ;
	DWORD m_networkEmuControllers[4] ;
	DWORD m_networkStatus ;
	char m_screenshotDir[MAX_PATH] ;
	int m_defaultScreenshots ;

	D3DXVECTOR2 m_gameVecScale ; 
	D3DXVECTOR2 m_gameVecTranslate ; 
	RECT m_gameRectSource ;
	int m_throttle ;

	int m_stateNumber ;
	int  m_smbCdFile ;
	int  m_bUsingSamba ;
	int m_xboxHFilter ;
	int m_xboxSFilter ;
	char m_smbShare[500] ;
	float m_fFrameTime ;
	UINT32 m_numFrames ;
	int  m_scrollSpeed ; 
	int   keyTime ;
	unsigned int m_pitch ;
	DWORD  m_bRealCD ;
	DWORD  m_currentStartSector ;
	unsigned char *m_ptrCdBuf ;
	char m_cdromID[11]; 
	DWORD m_bitDepth ;
	DWORD m_lineHeight ;
	unsigned int m_zapperNum ;
	unsigned int m_vandalFix ;
	unsigned int m_psxfix_Xa ;
	unsigned int m_psxfix_Sio ;
	unsigned int m_psxfix_Mdec ;
	unsigned int m_psxfix_Cdda ;
	unsigned int m_psxfix_Cpu ;
	unsigned int m_psxfix_SpuIrq ;
	unsigned int m_psxfix_VSyncWA ;
	int       m_bNetplay ;
	unsigned int m_bNetworkCD ;
	char m_szSkin[100] ;
	char m_szSkinDir[MAX_PATH] ;


	unsigned int m_changedSettings ;
	WCHAR *m_menuText[200] ;



	UINT32 topIdx  ;
	UINT32 curr  ;
	D3DPalette			*m_pd3dPalette ;
	BOOL m_bIsDDrive ;
	//CDDAXbox m_cdda ;

    CXBHelp     m_Help;             // Help object
    BOOL        m_bDrawHelp;        // TRUE to draw help screen
	D3DPRESENT_PARAMETERS	m_origPP ;


    LPDIRECTSOUND8      m_pDSound;      // DirectSound object
    DWORD               m_dwCurrent;    // Current surface
	DWORD               m_graphicsFixes ;
	DWORD               m_frameskip, m_framelimit ;
	DWORD				m_numtracks ;
	int m_bMappingCircle ;
	int m_bMappingSquare ;
	int m_bMappingTriangle ;
	int m_bMappingCross ;
	int m_bMappingR1 ;
	int m_bMappingL1 ;
	int m_bMappingR2 ;
	int m_bMappingL2 ;
	int m_bMappingStart ;
	int m_bMappingSelect ;
	int m_bMappingThrottle ;
	CPanel m_pnlBackgroundMain ;
	CPanel m_pnlBackgroundSelect ;
	CPanel m_pnlBackgroundOther ;
	CPanel m_pnlSplashEmu ;
	CPanel m_pnlSplashGame ;
	CPanel m_pnlPopup ;
	CPanel m_pnlGameScreen ;
	CPanel m_pnlGameScreen2 ;


	byte *m_memBuf1, *m_memBuf2, *m_consoleMemory, *m_memMatches ;
	UINT32 m_currentMemMatches ;
	unsigned char *m_cdDataBuffer ;

	typedef struct _filenamestruct {
		WCHAR name[200] ;
		unsigned char filename[200] ;
		char isDir ;
	} FILENAME ;


	FILENAME *files ;
	unsigned long m_numFavorites ;
	unsigned long numfiles ;
	UINT32   m_iMaxWindowList;
	UINT32   m_iWindowMiddle ;
	UINT32   m_steps ;
	DWORD    m_dwStartPause ;
	int		m_nbytes ;
	int		m_nXOffset, m_nYOffset, m_nFontHeight ;
	int		m_namesPerPage ;
	char    m_szCurrentDir[MAX_PATH];
	CIoSupport m_io ;
	HANDLE m_hCdrom ;
	unsigned char m_cdbuffer[2352*4] ;
	unsigned char m_memcard1[MAX_PATH] ;
	unsigned char m_memcard2[MAX_PATH] ;
	int m_memcardnum1, m_memcardnum2 ;
	unsigned char m_biosfile[100] ;


	LPDIRECT3DTEXTURE8	m_pd3dBackgroundTexture;
	LPDIRECT3DTEXTURE8	Texture;
	LPDIRECT3DTEXTURE8	Texture2;
	LPDIRECT3DTEXTURE8	WhiteTexture;
	LPD3DXSPRITE			Sprite;
	LPD3DXSPRITE			MenuSprite;
	byte*				g_pBlitBuff ;
	byte*				g_pUnpaletteBuff ;
	byte*				g_pAlignBuff ;
	byte*				g_pDeltaBuff ;
	int					m_droppedFrames ;	
	
	UINT32				m_state ;
    WCHAR      m_strMessage[80];
	UINT32              m_msgDelay ;


	SoundXBOX			m_sound;
	CXBSound			m_sfxMenuMove;
	CXBSound			m_sfxMenuSelect;
	CXBSound			m_sfxMenuCancel;
	char				g_savePath[500] ;
	char				g_saveprefix[500] ;
	char				g_sramfile[500] ;
	char				g_bramfile[500] ;
	char				g_cuefile[500] ;
	char				g_rtcfile[500] ;
	char				g_chtfile[500] ;
	char				g_statefile[500] ;
	char				g_keysfile[500] ;
	char				g_settingsfile[500] ;
	FILE                *m_logfile ;

// Indicates the width and height of the screen
	UINT32 theWidth;
	UINT32 theHeight;
    RECT SrcRect;
    RECT DestRect;

	int					m_nScreenX, m_nScreenY, m_nScreenMaxX, m_nScreenMaxY ;


	CHEAT_CODE *m_cheatCodes;

	typedef struct _cheatdbentry 
	{
		char gamename[100] ;
		char slus[11] ;
		unsigned int numcodes ;
		char *filepos ;
	} CHEATDBENTRY ;


	char *m_cheatfile ;
	unsigned int m_numDBCheats ;

	UINT32 m_numCheats ;


};

#ifdef __cplusplus
extern "C" {
#endif


void hq2x_16(unsigned char*, unsigned char*, DWORD, DWORD, DWORD, DWORD, DWORD);
unsigned int   LUT16to32[65536];
unsigned int   RGBtoYUV[65536];

#ifdef __cplusplus
}
#endif

void hq2x_16_stub(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode ) 
{
    hq2x_16( srcPtr, dstPtr, width, height, dstPitch, srcPitch - (width<<1), dstPitch - (width<<2));

}

void dummy_blitter(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode ) 
{
}

struct blitters
{
	void (*blitfunc)(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height, int scanmode ) ;
	char name[100] ;
	float  multiplier ;
} SOFTWARE_FILTERS[] = 
{
	{ dummy_blitter, "None", 1 },
	{ _2xSaI, "2xSai", 2},
	{ Super2xSaI, "Super 2xSai", 2},
	{ hq2x_16_stub, "HQ2X", 2},
	{ Eagle, "Eagle2x", 2},
	{ SuperEagle, "Super Eagle 2x", 2},
	{ SuperScale, "SuperScale 2x", 2},
	{ AdMame2x, "AdvanceMame 2x", 2},
	{ Simple2x, "Simple 2x", 2},
	{ _2xSaIScanline, "2xSai Scanline", 2},
	{ Super2xSaIScanline, "Super 2xSai Scanline", 2},
	{ EagleScanline, "Eagle2x Scanline", 2},
	{ SuperEagleScanline, "Super Eagle2x Scanline", 2},
	{ SuperScaleScanline, "SuperScale 2x Scanline", 2},
} ;

#define HQFILTERNUM 1

#define NUM_SOFTWARE_FILTERS 14

//#include "..\common\commonfuncs.cpp"

void InitLUTs(void)
{
  int i, j, k, r, g, b, Y, u, v;

  for (i=0; i<65536; i++)
    LUT16to32[i] = ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3);

  for (i=0; i<32; i++)
  for (j=0; j<64; j++)
  for (k=0; k<32; k++)
  {
    r = i << 3;
    g = j << 2;
    b = k << 3;
    Y = (r + g + b) >> 2;
    u = 128 + ((r - b) >> 2);
    v = 128 + ((-r + 2*g -b)>>3);
    RGBtoYUV[ (i << 11) + (j << 5) + k ] = (Y<<16) + (u<<8) + v;
  }

}

int  m_bRecreated ;

void xbox_print_memory()
{
					MEMORYSTATUS stat;

					GlobalMemoryStatus( &stat );
					sprintfx( "memory=%u\r\n", stat.dwAvailPhys ) ; 
}

CXBoxSample *g_app ;
char global_error_message[1024] ;
unsigned int m_performanceFreq[2] ;
unsigned int m_performanceCurr[2] ;
unsigned int m_performancePrev[2] ;


int recreate( D3DPRESENT_PARAMETERS *pparams )
{
	char tmpfilename[500] ;

	SAFE_RELEASE( g_app->Sprite ) ;
	SAFE_RELEASE( g_app->MenuSprite ) ;

				g_app->m_pd3dDevice->Release();

				//g_app->fillPresentationParams() ;

				if( FAILED( g_app->m_pD3D->CreateDevice( 0, D3DDEVTYPE_HAL, NULL, 
													   D3DCREATE_HARDWARE_VERTEXPROCESSING, 
													   pparams, &g_app->m_pd3dDevice ) ) )
				{
					return 0 ;
				}
				else
				{
					g_pd3dDevice = g_app->m_pd3dDevice ;

					g_app->m_pnlBackgroundMain.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlBackgroundSelect.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlBackgroundOther.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlSplashEmu.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlSplashGame.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlPopup.Recreate( g_app->m_pd3dDevice );
					g_app->m_pnlGameScreen.Recreate( g_app->m_pd3dDevice );

					m_bRecreated = 1 ;
					return 1 ;

				}
}

void xbox_set_refreshrate( int rate )
{
	int nativeRate ;
	D3DPRESENT_PARAMETERS holdpp ;


	sprintfx( "set refresh %u\r\n", rate ) ;

	if(XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I)
	{
		//get supported video flags
		DWORD videoFlags = XGetVideoFlags();
		
		//set pal60 if available.
		if(videoFlags & XC_VIDEO_FLAGS_PAL_60Hz)
			nativeRate = 60 ;
		else
			nativeRate = 50 ;
	}
	else
		nativeRate = 60 ;

	if ( rate != g_app->m_d3dpp.FullScreen_RefreshRateInHz )
	{
		sprintfx( "rate is diff\r\n" ) ;
		g_app->m_d3dpp.FullScreen_RefreshRateInHz = rate ;

		if ( nativeRate != rate )
		{
			sprintfx( "set emu\r\n" ) ;
			g_app->m_d3dpp.Flags |= D3DPRESENTFLAG_EMULATE_REFRESH_RATE ;
		}
		else
		{
			sprintfx( "unset emu\r\n" ) ;
			g_app->m_d3dpp.Flags &= ~D3DPRESENTFLAG_EMULATE_REFRESH_RATE ;
		}
/*
		if ( g_app->m_d3dpp.BackBufferWidth == 1920 )
		{
			g_app->m_d3dpp.Flags &= ~D3DPRESENTFLAG_EMULATE_REFRESH_RATE ;
			g_app->m_d3dpp.FullScreen_RefreshRateInHz = nativeRate ;

		}
*/
		memcpy( &holdpp, &g_app->m_d3dpp, sizeof(D3DPRESENT_PARAMETERS) ) ;

		recreate( &g_app->m_d3dpp ) ;

		memcpy( &g_app->m_d3dpp, &holdpp, sizeof(D3DPRESENT_PARAMETERS) ) ;

		g_app->m_pd3dDevice->Reset(&g_app->m_d3dpp);

		memcpy( &g_app->m_d3dpp, &holdpp, sizeof(D3DPRESENT_PARAMETERS) ) ;
	}
}


struct { char *keyname ; int keynum ; } validKeys[11] = 
{
	{ "XBOX A", 0 },
	{ "XBOX B", 1 },
	{ "XBOX X", 2 },
	{ "XBOX Y", 3 },
	{ "XBOX BLACK", 4 },
	{ "XBOX WHITE", 5 },
	{ "XBOX START", 6 },
	{ "XBOX BACK", 7 },
	{ "XBOX LTRIGGER", 8 },
	{ "XBOX RTRIGGER", 9 },
	{ "UNMAPPED", 10 },
};







int CXBoxSample::init_texture()
{
//	return 1  ;


	D3DCOLOR *palette ;

	sprintfx( "begin inittext\r\n") ;
	xbox_print_memory() ;

	// Release any previous texture
	if (Texture) 
	{ 
		return 1 ;
		Texture->BlockUntilNotBusy() ;
		Texture->Release();
		Texture = NULL;
	}
	
	theWidth = 320*4 ;
	theHeight = 240*4 ;



	// Create the texture
	if (D3DXCreateTextureFromFileInMemoryEx(m_pd3dDevice, GAMESCREEN_FILE, sizeof(GAMESCREEN_FILE),
		 theWidth, theHeight, 1, 0, D3DFMT_LIN_R5G6B5, D3DPOOL_MANAGED,
		 //D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED,
		 D3DX_FILTER_NONE , D3DX_FILTER_NONE, 0, NULL, NULL, &Texture)==D3D_OK)
	{
		m_pnlGameScreen.m_pTexture = NULL ;
		if ( FAILED(m_pnlGameScreen.Create(m_pd3dDevice, Texture, FALSE, theWidth, theHeight)) )
		{
			//popupMsg( "no create panel", &m_pnlBackgroundOther ) ;
		}
	}
	else
	{
		//popupMsg( "no load texture", &m_pnlBackgroundOther ) ;
	}
	
/*
	// Create the texture
	if (D3DXCreateTextureFromFileEx(m_pd3dDevice, "D:\\gamescreen.png",
		 theWidth, theHeight, 1, 0, D3DFMT_LIN_R5G6B5, D3DPOOL_MANAGED,
		 //D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED,
		 D3DX_FILTER_NONE , D3DX_FILTER_NONE, 0, NULL, NULL, &Texture)==D3D_OK)
	{
		if ( FAILED(m_pnlGameScreen.Create(m_pd3dDevice, Texture, FALSE, theWidth, theHeight)) )
		{
			popupMsg( "no create panel", &m_pnlBackgroundOther ) ;
		}
	}
	else
	{
		popupMsg( "no load texture", &m_pnlBackgroundOther ) ;
	}

	xbox_print_memory() ;
*/	
/*
	D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_LIN_R5G6B5, D3DPOOL_DEFAULT, &Texture);
		if ( FAILED(m_pnlGameScreen.Create(m_pd3dDevice, Texture, FALSE, theWidth, theHeight)) )
		{
			popupMsg( "no create panel", &m_pnlBackgroundOther ) ;
		}

*/
//	D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_P8, D3DPOOL_DEFAULT, &Texture);
//	D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &Texture);
//	D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_DEFAULT, &Texture);
	
	D3DSURFACE_DESC desc;
    Texture->GetLevelDesc(0, &desc);

	sprintfx( "before inittex\r\n") ;

	xbox_print_memory() ;
	
	if (g_pBlitBuff != NULL)
	{
		delete [] g_pBlitBuff;
		g_pBlitBuff = NULL;
	}
	
	// Allocate a buffer to blit our frames to
	g_pBlitBuff = new byte[ desc.Size ];

	xbox_print_memory() ;
/*
	if (g_pAlignBuff != NULL)
	{
		delete [] g_pAlignBuff;
		g_pAlignBuff = NULL;
	}
	
	// Allocate a buffer to blit our frames to
	g_pAlignBuff = new byte[desc.Size];

	xbox_print_memory() ;

	if (g_pUnpaletteBuff != NULL)
	{
		delete [] g_pUnpaletteBuff ;
		g_pUnpaletteBuff = NULL;
	}
	
	// Allocate a buffer to blit our frames to
	g_pUnpaletteBuff = new byte[desc.Size];
*/
	xbox_print_memory() ;

	if (g_pDeltaBuff != NULL)
	{
		delete [] g_pDeltaBuff;
		g_pDeltaBuff = NULL;
	}
	
	// Allocate a buffer to blit our frames to
	g_pDeltaBuff = new byte[desc.Size];

	xbox_print_memory() ;

	if ( g_pDeltaBuff == NULL )
		return 1 ;

	memset( g_pDeltaBuff, 0xFF, desc.Size ) ;

	sprintfx( "aft inittex\r\n") ;
	

	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	rectSource.bottom = theHeight-1 ;
	rectSource.right  = theWidth-1 ;

	D3DLOCKED_RECT d3dlr;
	Texture->LockRect(0, &d3dlr, &rectSource, 0);

	m_pitch = d3dlr.Pitch ;

	// Unlock our texture
	Texture->UnlockRect(0);

	xbox_print_memory() ;

	//m_pd3dDevice->CreatePalette( D3DPALETTE_256 , &m_pd3dPalette ) ;
	//m_pd3dPalette->Lock( &palette, 0 ) ;
	//memset( palette, 44, 256* sizeof( D3DCOLOR ) ) ;
	//m_pd3dPalette->Unlock() ;

	//m_pd3dDevice->SetPalette( 0, m_pd3dPalette ) ;

	sprintfx( "end inittex\r\n") ;

	return 0;
}




void CXBoxSample::UpdatePalette(void)
{
	/*
    unsigned char	r, g, b;
    int				index;

    if (bitmap.pal.update == 0) return;

    for (index = 0; index < 32; index++)
    {
        if(bitmap.pal.color[index])
        {
			
			//if (UseDirectDraw && RegistryInfo.EnableDirectDraw)
			//{
	            r = bitmap.pal.color[index][0];
				g = bitmap.pal.color[index][1];
				b = bitmap.pal.color[index][2];

				r = r >> 3 ;
				g = g >> 2 ;
				b = b >> 3 ;

				pixel[index] = (r<<11) | ( g <<5 ) | b ;

			//}
			//else
			//{
	            //r = bitmap.pal.color[index][0];
				//g = bitmap.pal.color[index][1];
				//b = bitmap.pal.color[index][2];
			//}

			//r = (unsigned char)(255.0f * pow((float)r / 255.0f, 1.0f / m_fGamma) + 0.5f);
			//g = (unsigned char)(255.0f * pow((float)g / 255.0f, 1.0f / m_fGamma) + 0.5f);
			//b = (unsigned char)(255.0f * pow((float)b / 255.0f, 1.0f / m_fGamma) + 0.5f);

			//pixel[index] = MAKE_PIXEL(r, g, b);

			Bmp.Palette[0x00 | index].rgbRed	  = r;
			Bmp.Palette[0x00 | index].rgbGreen	  = g;
			Bmp.Palette[0x00 | index].rgbBlue	  = b;
			Bmp.Palette[0x20 | index].rgbRed	  = r;
			Bmp.Palette[0x20 | index].rgbGreen	  = g;
			Bmp.Palette[0x20 | index].rgbBlue	  = b;
			Bmp.Palette[0x40 | index].rgbRed	  = r;
			Bmp.Palette[0x40 | index].rgbGreen	  = g;
			Bmp.Palette[0x40 | index].rgbBlue	  = b;
        }
    }

    bitmap.pal.update = 0;
    memset(bitmap.pal.dirty, 0, 32);
	*/
}








void CXBoxSample::emuLaunch( unsigned int gameSelected, unsigned int isFavorite, int forceConfig )
{
	//m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	//m_pd3dDevice->Reset( &m_d3dpp ) ;


	initConsole(gameSelected, isFavorite, forceConfig) ;

	//while ( m_state == IN_GAME )
	//{
		//processEmu( TRUE ) ;
	//}

	cleanupConsole() ;

	char tmpfilename[1024] ;

	//sprintf( tmpfilename, "%s\\%s\\SPRITES\\*", m_szSkinDir, m_szSkin) ;
	//m_plaything.LoadSprites( tmpfilename ) ;

	m_sound.cleanup() ;




	//m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	//m_pd3dDevice->Reset( &m_d3dpp ) ;

}





void CXBoxSample::GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)
{
	*r=( color_palette[i] >> 16 ) & 0xFF ;
	*g=( color_palette[i] >> 8 ) & 0xFF ;
	*b=( color_palette[i]  ) & 0xFF ;
}

void CXBoxSample::SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
{

	color_palette[index] = ( 0xFF << 24 ) | ( r << 16 ) | ( g << 8 ) | (b)  ;
	PaletteChanged=1;
}



void CXBoxSample::saveSettings( char *filename )
{

	FILE *setfile ;

	m_changedSettings = 0 ;

	setfile = fopen( filename, "wb" ) ;

	if ( !setfile )
		return ;

	fwrite( &m_xboxSFilter, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_nScreenX, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_nScreenY, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_nScreenMaxX, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_nScreenMaxY, sizeof(unsigned int), 1, setfile ) ;

	fclose( setfile ) ;

}


void CXBoxSample::setPalette( unsigned char *palette)
{

	//m_pd3dPalette->Lock( &color_palette, 0 ) ;

	memset( color_palette, 0, 256*sizeof(D3DCOLOR) ) ;
	DWORD r, g, b;



	for (int i = 0; i < 256; i++)
	{
		r = palette[i*3] ;
		g = palette[(i*3)+1] ;
		b = palette[(i*3)+2] ;

		//color_palette[i] = 0xFF000000 | ( palette[i*3] << 16 ) | ( palette[(i*3)+1] << 8 ) | ( palette[(i*3)+2] )  ;
		color_palette[i] =  ( ( r >> 3 ) << 11 ) | ( ( g >> 2 ) << 5 ) | ( b >> 3 )  ;
	}

	//m_pd3dPalette->Unlock() ;

	//m_pd3dDevice->SetPalette( 0, m_pd3dPalette ) ;
}

int CXBoxSample::loadSettings( char *filename )
{

	FILE *setfile ;

	m_changedSettings = 0 ;

	setfile = fopen( filename, "rb" ) ;

	if ( !setfile )
	{
		saveSettings( filename ) ;
		return 1;
	}

	fread( &m_xboxSFilter, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_nScreenX, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_nScreenY, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_nScreenMaxX, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_nScreenMaxY, sizeof(unsigned int), 1, setfile ) ;


	fclose( setfile ) ;
	
	if ( ( m_xboxSFilter < 0 ) || ( m_xboxSFilter >= NUM_SOFTWARE_FILTERS ))
	{
		m_xboxSFilter = 0 ;

	}

	return 0 ;
}






struct genietable
{
	byte nibble ;
	char code ;
} GENIETABLE[] = 
{
	{ 0x0, 'A' },
	{ 0x1, 'E' },
	{ 0x2, 'P' },
	{ 0x3, 'O' },
	{ 0x4, 'Z' },
	{ 0x5, 'X' },
	{ 0x6, 'L' },
	{ 0x7, 'U' },
	{ 0x8, 'G' },
	{ 0x9, 'K' },
	{ 0xA, 'I' },
	{ 0xB, 'S' },
	{ 0xC, 'T' },
	{ 0xD, 'V' },
	{ 0xE, 'Y' },
	{ 0xF, 'N' }
} ;










int charToHex( char c )
{
	if ( ( c >= '0' ) && ( c <= '9' ) )
		return c-'0' ;
	else
		return c-'A'+10 ;
}

int strToHex( char *str, int len )
{
	int base ;
	int val ;

	base = 1 ;

	val = 0 ;

	for ( int i = len-1 ; i >= 0 ; i-- )
	{
		val += charToHex(str[i])*base ;
		base *= 16 ;
	}

	return val ;
}




HRESULT CXBoxSample::InitializeWithScreen()
{
	FILE *debugfile ;
	char initext[100] ;
	char szDevice[2000] ;
	char *fpos, *epos ;
	int numread ;
	char tmpfilename[MAX_PATH] ;



	XBInput_GetInput();
	XBInput_GetInput();
	

	
	m_bRecreated = 0 ;

	sprintfx( "before loadtext - showmemory \r\n" ) ;

	xbox_print_memory() ;

	XMountUtilityDrive( TRUE )  ;

	m_io.Unmount("C:") ;
	m_io.Unmount("E:") ;
	m_io.Unmount("F:") ;
	m_io.Unmount("G:") ;
	m_io.Unmount("X:") ;
	m_io.Unmount("Y:") ;
	m_io.Unmount("Z:") ;
	m_io.Unmount("R:") ;
	m_io.Mount("C:", "Harddisk0\\Partition2");
	m_io.Mount("E:", "Harddisk0\\Partition1");
	m_io.Mount("F:", "Harddisk0\\Partition6");
	m_io.Mount("G:", "Harddisk0\\Partition7");
	m_io.Mount("X:", "Harddisk0\\Partition3");
	m_io.Mount("Y:", "Harddisk0\\Partition4");
	m_io.Mount("Z:", "Harddisk0\\Partition5");
	//m_io.Mount("Y:", "Harddisk0\\Partition4");
	//m_io.Mount("Z:", "Harddisk0\\Partition5");
	m_io.Mount("R:","Cdrom0");

	XFormatUtilityDrive() ;

	CreateDirectory( "E:\\SAVES", NULL ) ;

	//debugfile = fopen( "E:\\SAVES\\xportdebug.txt", "wb" ) ;

	//fprintf( debugfile, "Starting initialization\r\n") ;
	//fflush( debugfile ) ;


	//m_io.Remount("D:", "Harddisk0\\Partition1\\games");

	//m_io.GetDeviceFromSymlink( "D:", szDevice ) ;


	//m_io.Remount("S:",szDevice+8);  //S drive will always be the original D mapping


	xbox_print_memory() ;


	char szNewDir[MAX_PATH] ;
	char *s, *p ;

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;


	strcpy( szNewDir, DEFAULT_SAVE_PATH ) ;

	s = szNewDir+3 ;
	

	while ( p = strchr( s, '\\' ) )
	{
		*p = 0 ;
		CreateDirectory( szNewDir, NULL ) ;

		*p = '\\' ;

		p++ ;
		s = p ;
	}

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;

	CreateDirectory( DEFAULT_SAVE_PATH, NULL ) ;

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;

	xbox_print_memory() ;

	sprintfx( "inscre\r\n") ;




	m_xboxSFilter = 0 ;
	m_nScreenMaxX = 640 ;
	m_nScreenMaxY = 480 ;
	m_nScreenX = 0 ;
	m_nScreenY = 0 ;






	DWORD tdiff = GetTickCount() ;

	tdiff = GetTickCount() - tdiff ;

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	xbox_print_memory() ;
	sprintfx( "inscre\r\n") ;



	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	sprintfx( "inscre\r\n") ;
	xbox_print_memory() ;


	m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL|D3DCLEAR_TARGET,
						 0x00000000, 0.0f, 0L );
	//RenderGradientBackground( 0xFF000000, 0xFF000000 );



	m_pd3dDevice->Present( NULL, NULL, NULL, NULL );


	QueryPerformanceFrequency((union _LARGE_INTEGER *) m_performanceFreq);

	InitLUTs() ;

	XGetCustomLaunchData() ;
	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	sprintfx( "inscre\r\n") ;

	xbox_print_memory() ;



	xbox_print_memory() ;
	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;


	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	xbox_print_memory() ;

	sprintfx( "inscre\r\n") ;

	curr = 0 ;
	topIdx = 0 ;
	numfiles = 0 ;

	m_stateNumber = 0 ;




	//m_namesPerPage =  m_skin.gameSelectMenu.linesPerPage ; // (25*14 ) / ( m_Font.GetFontHeight()-2) ;


	m_msgDelay = 0 ;
	wcscpy( m_strMessage, L" " ) ;
	
	g_pBlitBuff = NULL ;
	g_pDeltaBuff = NULL ;
	g_pAlignBuff = NULL ;
	WhiteTexture = NULL ;
	Texture = NULL ;
	Sprite = NULL ;


	MenuSprite = NULL ;


	m_cheatCodes = NULL ;
	m_numCheats = 0 ;

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	xbox_print_memory() ;
	init_white_texture();
	xbox_print_memory() ;

	g_saveprefix[0] = 0 ;


	sprintfx( "inscre\r\n") ;
	xbox_print_memory() ;
	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	//copyOldSaves() ;

	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	xbox_print_memory() ;
	sprintfx( "inscre\r\n") ;


	curr = 0 ;
	topIdx = 0 ;

	sprintfx( "inscre\r\n") ;
	xbox_print_memory() ;



	
	xbox_print_memory() ;
	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;
	
	InitializeEmuSpecific() ;
	//fprintf( debugfile, "Init\r\n") ;
	//fflush( debugfile ) ;

	//fclose(debugfile) ;
	xbox_print_memory() ;

	initConsole(0,0,0) ;

    return S_OK;
}


//-----------------------------------------------------------------------------
// Name: FrameMove
// Desc: Performs per-frame updates
//-----------------------------------------------------------------------------
HRESULT CXBoxSample::FrameMove()
{

	InitializeWithScreen() ;
    return S_OK;
}


int CXBoxSample::render_to_texture( unsigned char *buf)
{
    int vp_vstart ;
    int vp_vend   ;
    int vp_hstart ;
    int vp_hend   ;
	int w,h ;
	RECT src, dst;
	WORD *curr1 ; 
	byte *curr2 ;
	DWORD pitchDiff1 ; 
	DWORD pitchDiff2 ; 
	D3DCOLOR *palette ;
	char palstr[200] ;
	DWORD pixel ;
	byte r,g,b ;

	w = 320 ;
	h = 240 ;

	m_numFrames++ ;

/*	if ( PaletteChanged != 0 )
	{
		m_pd3dDevice->GetPalette( 0, &m_pd3dPalette ) ;
		m_pd3dPalette->Lock( &palette, 0 ) ;
		memcpy( palette, color_palette, 256* sizeof( D3DCOLOR ) ) ;
		m_pd3dPalette->Unlock() ;
		PaletteChanged = 0 ;
	}
*/
	//sprintfx("rendertext\r\n") ;

	// Get a description of our level 0 texture so we can figure
	// out the pitch of the texture

	D3DSURFACE_DESC desc;
    Texture->GetLevelDesc(0, &desc);
	
	
	// Allocate a buffer to blit our frames to


	unsigned char *bsrc = buf;
	unsigned short  *bdst = (unsigned short*)g_pBlitBuff;

	for ( int y = 0 ; y < 240 ; y++ )
	{
		for ( int x = 0 ; x < 320 ; x++ )
		{
			*(bdst+x) = color_palette[ *bsrc++ ] ;
		}
		bdst += m_pitch/2 ;
	}
	

	// Figure out how big of a rect to lock in our texture
	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	rectSource.bottom = theHeight-1 ;
	rectSource.right  = theWidth-1 ;

	// Lock the rect in our texture
	D3DLOCKED_RECT d3dlr;
	Texture->LockRect(0, &d3dlr, &rectSource, 0);

/*
	if ( m_xboxSFilter )
		curr1 = (WORD*)g_pUnpaletteBuff ;
	else
		curr1 = (WORD*)d3dlr.pBits  ;

	curr2 = g_pBlitBuff ;
	pitchDiff1 = (m_pitch - 640 )/2;
	pitchDiff2 = m_pitch - 320 ;


	for ( int y = 0 ; y < MaxLines ; y++ )
	{
		for ( int x = 0 ; x < 320 ; x++ )
		{
			*curr1++ = (color_palette[*curr2&0x7f] & 0xFFFF);
			curr2++ ;
			//*curr1++ = (palette[*curr2++] & 0xFFFF);
		}

		curr2 += pitchDiff2 ;
		curr1 += pitchDiff1 ;
	}
*/






	float mx, my ;

	if ( m_xboxSFilter )
	{
		SOFTWARE_FILTERS[m_xboxSFilter].blitfunc(g_pBlitBuff + m_pitch,m_pitch, g_pDeltaBuff+m_pitch, ((unsigned char*)d3dlr.pBits)+m_pitch, m_pitch, 320, 240, 0 ) ;
		//XGSwizzleRect(g_pBlitBuff, 0, NULL, d3dlr.pBits, desc.Width, desc.Height, NULL, 2);
		//memcpy( d3dlr.pBits, g_pBlitBuff, desc.Size ) ;
		Texture->UnlockRect(0);
		//m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,0x00000000, 1.0f, 0L );
		//RenderGradientBackground( 0xFF000000, 0xFF000000 );
		g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);
		g_pd3dDevice->BeginScene();

		//memcpy( g_pDeltaBuff, g_pUnpaletteBuff, 240*512 ) ;
		mx = (float)m_nScreenMaxX / ((float)320*SOFTWARE_FILTERS[m_xboxSFilter].multiplier) ;
		my = (float)m_nScreenMaxY / ((float)240*SOFTWARE_FILTERS[m_xboxSFilter].multiplier);

		//m_gameRectSource.top = vp_vstart*2;
		//m_gameRectSource.left = vp_hstart*2;
		//m_gameRectSource.bottom = vp_vstart*2 + ( vp_vend-vp_vstart)*2;
		//m_gameRectSource.right  = vp_hend*2 + ( vp_hend-vp_hstart)*2;

		m_gameRectSource.top = 0 ;
		m_gameRectSource.left = 0 ; 
		m_gameRectSource.bottom = (240-1)*SOFTWARE_FILTERS[m_xboxSFilter].multiplier ; 
		m_gameRectSource.right  = (320-1)*SOFTWARE_FILTERS[m_xboxSFilter].multiplier ; 

	}
	else
	{
		//memcptsystemDrawScreenNoFilter( (unsigned char*)d3dlr.pBits) ;
		//XGSwizzleRect(g_pBlitBuff, 0, NULL, d3dlr.pBits, desc.Width, desc.Height, NULL, 2);


		unsigned char *src = g_pBlitBuff;
		unsigned char *dst = (unsigned char*)d3dlr.pBits;

		for ( int y = 0 ; y < 240 ; y++ )
		{
			memcpy( dst, src, 320*2 ) ;
			dst += m_pitch ;
			src += m_pitch ;
		}


		//memcpy( d3dlr.pBits, g_pBlitBuff, desc.Size ) ;
		Texture->UnlockRect(0);
		//m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,0x00000000, 1.0f, 0L );
		//RenderGradientBackground( 0xFF000000, 0xFF000000 );
		g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);
		g_pd3dDevice->BeginScene();

		mx = (float)m_nScreenMaxX / ((float)320) ;
		my = (float)m_nScreenMaxY / ((float)240);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = 240-1;
		m_gameRectSource.right  = 320-1;
	}



	m_gameVecScale.x = mx ; m_gameVecScale.y = my;
	m_gameVecTranslate.x = m_nScreenX ; m_gameVecTranslate.y = m_nScreenY ;
	D3DXCOLOR d3color(1.0, 1.0, 1.0, 1.0);




	m_pnlGameScreen.Render( m_gameRectSource.left, m_gameRectSource.top,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY) ;
	//m_pnlGameScreen.Render(m_nScreenX ,m_nScreenY,m_nScreenMaxX*mx,m_nScreenMaxY*my) ;

//	Sprite->Draw(Texture, &m_gameRectSource, &m_gameVecScale, NULL, 0, &m_gameVecTranslate, d3color);
/*
	if ( global_error_message[0] )
	{
		if ( m_msgDelay > 0 )
		{
			WCHAR msg[500] ;
			m_msgDelay-- ;
			swprintf( msg, L"%S", global_error_message ) ;

			m_Font.DrawText( 48, 48, 0xFFFFFFFF, msg, 0x00000000, 1, 0, 640, 480, pmenuParams->size   ) ;
		}
	}
	*/
	if ( global_error_message[0] )
	{
		WCHAR msg[500] ;
		m_msgDelay-- ;
		swprintf( msg, L"%S", global_error_message ) ;


		if ( m_msgDelay <= 0 )
		{
			global_error_message[0] = 0 ;
		}
	}
	/*
	else
	{
		if ( GetTickCount() - m_startTime > 0 )
		{
			sprintf( global_error_message, "%2.2f FPS - %u frames in %3.2f sec", ((float)m_numFrames*1000.0f)/((float)( GetTickCount() - m_startTime )), m_numFrames, ((float)( GetTickCount() - m_startTime ))/1000.0f ) ;
			m_msgDelay = 1 ;
			WCHAR msg[500] ;
			swprintf( msg, L"%S", global_error_message ) ;

			m_Font.DrawText( 48, 48, 0xFFFFFFFF, msg, 0x00000000, 1, 0, 640, 480, pmenuParams->size   ) ;
		}
		else
		{
			sprintf( global_error_message, "<inf> FPS" ) ;
			m_msgDelay = 1 ;
			WCHAR msg[500] ;
			swprintf( msg, L"%S", global_error_message ) ;

			m_Font.DrawText( 48, 48, 0xFFFFFFFF, msg, 0x00000000, 1, 0, 640, 480, pmenuParams->size   ) ;
		}
	}
*/

#ifdef LIGHTGUN
	if ( m_zapperNum )
	{
		if ( m_lightgun.wButtons & XINPUT_LIGHTGUN_ONSCREEN  )
		{
			FLOAT fWidth = 640.0f ;
			FLOAT fHeight = 480.0f ;
			FLOAT fThumbLX = (fWidth/2) + (fWidth/2)*(m_lightgun.sThumbLX+0.5f)/32767.5f;
			FLOAT fThumbLY = (fHeight/2) - (fHeight/2)*(m_lightgun.sThumbLY+0.5f)/32767.5f;
		    ColorBar( fThumbLX-10, fThumbLY-10, 20,20, 0xFF00FF00 );
		}
	}
#endif
	// End the scene.
	g_pd3dDevice->EndScene();

	//if ( !m_throttle )
		//g_pd3dDevice->BlockUntilVerticalBlank() ;

	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

	/*
	float FPS, desiredFPS ;

	desiredFPS = m_refreshRate ;

	if ( m_throttle )
		desiredFPS = desiredFPS * 3.0f ;


	do
	{
		QueryPerformanceCounter((union _LARGE_INTEGER *) m_performanceCurr);

		if (m_performanceCurr[0] != m_performancePrev[0])
		{					
			FPS = (float) (m_performanceFreq[0])  / (float) (m_performanceCurr[0] - m_performancePrev[0]);
			//sprintf( global_error_message, "fps=%.1f %.1f\r\n", FPS, desiredFPS);
		}
		else
		{
			FPS = 100.0f ;
			//sprintf( global_error_message, "fps=too much...\r\n");
		}

		//view_fps = 0;
	} while ( FPS > desiredFPS ) ;

	m_performancePrev[0] = m_performanceCurr[0];
*/
	return 1;
	
	// Swizzle the blittled surface back to the texture
	//XGSwizzleRect(g_pAlignBuff, 0, NULL, d3dlr.pBits, desc.Width, desc.Height, NULL, 1);


	// Swizzle the blittled surface back to the texture
//	XGSwizzleRect(XBuf+8, 0, NULL, d3dlr.pBits, desc.Width, desc.Height, NULL, 1);
	//XGSwizzleRect(g_pBlitBuff, 0, NULL, d3dlr.pBits, desc.Width, desc.Height, NULL, 4);
/*
	// Unlock our texture
	Texture->UnlockRect(0);

	//delete [] g_pBlitBuff;
	//g_pBlitBuff = NULL;


	src.left   = 0;
	src.top    = 0;
	src.right  = theWidth  + 0;
	src.bottom = theHeight + 1;

	UINT iWidth  = theWidth;
	UINT iHeight = theHeight;
	
	// win_start_maximized the rect, constraining to the aspect ratio
	dst.left   = dst.top = 0;
	dst.right  = iWidth;
	dst.bottom = iHeight;
	
	// center
	//dst.left   += ((iWidth - (dst.right - dst.left)) / 2)  + ((640-iWidth)/2);
	//dst.top    += ((iHeight - (dst.bottom - dst.top)) / 2) + ((480-iHeight)/2);
	//dst.right  += dst.left;
	//dst.bottom += dst.top;
	
    // Clear the viewport
//	if ( ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_A ] ) || ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_X ] ) )  
	    g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);
	
	// Begin the Scene
	g_pd3dDevice->BeginScene();

	// Compute the source and dest image sizes
	const float dw = dst.right-dst.left;
	const float dh = dst.bottom-dst.top;
	const float sw = src.right-src.left;
	const float sh = src.bottom-src.top;


	float mx, my ;

	mx = (float)m_nScreenMaxX / (float)theWidth ;
	my = (float)m_nScreenMaxY / (float)theHeight ;

	// Compute the scale and transform vectors
	//D3DXVECTOR2 vecScale(dw/sw, dh/sh);
	D3DXVECTOR2 vecScale(mx, my);
	D3DXVECTOR2 vecTranslate(m_nScreenX, m_nScreenY );


	// Compute the scale and transform vectors
	//D3DXVECTOR2 vecScale(dw/sw, dh/sh);
	//D3DXVECTOR2 vecScale(2, 2);
	//D3DXVECTOR2 vecTranslate(56, 0 );
	//D3DXVECTOR2 vecTranslate(dst.left, dst.top);
	
	D3DXCOLOR d3color(1.0, 1.0, 1.0, 1.0);
	
	// Draw the sprite
	//if ( ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_A ] ) || ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_Y ] ) )  
		Sprite->Draw(Texture, &rectSource, &vecScale, NULL, 0, &vecTranslate, d3color);
	
	if ( global_error_message[0] )
	{
		if ( m_msgDelay > 0 )
		{
			WCHAR msg[500] ;
			m_msgDelay-- ;
			swprintf( msg, L"%S", global_error_message ) ;

			m_Font.DrawText( 48, 48, 0xFFFFFFFF, msg, 0x00000000, 1, 0, 640, 480, pmenuParams->size   ) ;
		}
	}

	// End the scene.
	g_pd3dDevice->EndScene();
	
	// Present the scene
	//if ( ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_A ] ) || ( m_DefaultGamepad.bAnalogButtons[ XINPUT_GAMEPAD_BLACK ] ) )  
		g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

	return 1;
	*/
}

void CXBoxSample::InitializeEmuSpecific()
{


	g_pUnpaletteBuff = NULL ;


	//m_cdda.dsound = m_sound.dsound ;
	//m_cdda.dsound_init() ;
	//m_cdda.m_fps = m_d3dpp.FullScreen_RefreshRateInHz ;

//	LoadCheatDB() ;



}

struct vidmodes
{
	char name[100] ;
	unsigned int width ;
	unsigned int height ;
	char progressive ;
	float multx ;
	float multy ;
} VIDEOMODES[] = 
{
	{ "Standard 480i", 640, 480, 0, 1.0f, 1.0f },
	{ "480p", 640, 480, 1, 1.0f, 1.0f },
	{ "720p", 1280, 720, 1, 2.0f, 1.5f },
	{ "1080i", 1920, 1080, 0, 3.0f, 2.25f },
	{ "720x480", 720, 480, 0, 1.125f, 1.0f },
	{ "720x576", 720, 576, 0, 1.125f, 1.2f },
} ;

void CXBoxSample::fillPresentationParams()
{
	IDirect3D8 *pD3D ;

    ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );

    m_d3dpp.BackBufferWidth        = 640;
    m_d3dpp.BackBufferHeight       = 480;
	m_d3dpp.BackBufferFormat        = D3DFMT_LIN_R5G6B5 ;
	m_d3dpp.Flags = 0 ;
	m_d3dpp.BackBufferCount									= 1;
	m_d3dpp.EnableAutoDepthStencil					= TRUE;
    m_d3dpp.AutoDepthStencilFormat	=	D3DFMT_D16;
	m_d3dpp.SwapEffect                      = D3DSWAPEFFECT_DISCARD;
	m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    m_d3dpp.MultiSampleType			=	D3DMULTISAMPLE_NONE;

	if(XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I)
	{
		//get supported video flags
		DWORD videoFlags = XGetVideoFlags();
		
		//set pal60 if available.
		if(videoFlags & XC_VIDEO_FLAGS_PAL_60Hz)
			m_d3dpp.FullScreen_RefreshRateInHz = 60 ;
		else
			m_d3dpp.FullScreen_RefreshRateInHz = 50 ;
	}
	else
		m_d3dpp.FullScreen_RefreshRateInHz = 60 ;



	DWORD videoFlags = XGetVideoFlags();

	if ( XGetAVPack() == XC_AV_PACK_HDTV)
	{
		if ( videoFlags & XC_VIDEO_FLAGS_HDTV_480p )
		{
			m_d3dpp.Flags = D3DPRESENTFLAG_PROGRESSIVE ;
			m_d3dpp.BackBufferWidth        = 640 ;
			m_d3dpp.BackBufferHeight       = 480 ;
		}
		else if ( videoFlags & XC_VIDEO_FLAGS_HDTV_720p )
		{
			m_d3dpp.Flags = D3DPRESENTFLAG_PROGRESSIVE | D3DPRESENTFLAG_WIDESCREEN ;
			m_d3dpp.BackBufferFormat       = D3DFMT_A8R8G8B8 ;
			m_d3dpp.BackBufferWidth        = 1280 ;
			m_d3dpp.BackBufferHeight       = 720 ;
		}
		else if ( videoFlags & XC_VIDEO_FLAGS_HDTV_1080i )
		{
			m_d3dpp.Flags = D3DPRESENTFLAG_WIDESCREEN | D3DPRESENTFLAG_INTERLACED ;
			m_d3dpp.BackBufferWidth        = 1920 ;
			m_d3dpp.BackBufferHeight       = 1080 ;
		}
	}




}

VOID __cdecl main()
{


	CXBoxSample xbApp;

	g_app = &xbApp ;



	xbApp.fillPresentationParams() ;


	memcpy( &xbApp.m_origPP, &xbApp.m_d3dpp, sizeof(xbApp.m_origPP) ) ;


    if( FAILED( xbApp.Create() ) )
	{
        return;
	}



/*
	//check for pal60 mode
	if(XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I)
	{
		//get supported video flags
		DWORD videoFlags = XGetVideoFlags();
		
		//set pal60 if available.
		if(videoFlags && XC_VIDEO_FLAGS_PAL_60Hz)
			xbApp.SetRefreshRate(60) ;
		else
			xbApp.SetRefreshRate(50) ;
	}
	else
		xbApp.SetRefreshRate(60) ;
*/

			//xbApp.SetRefreshRate(60) ;

/*	//check for pal60 mode
	if(XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I)
	{
		//get supported video flags
		DWORD videoFlags = XGetVideoFlags();
		
		//set pal60 if available.
		if(videoFlags && XC_VIDEO_FLAGS_PAL_60Hz)
			xbApp.m_d3dpp.FullScreen_RefreshRateInHz = 60 ;
		else
			xbApp.m_d3dpp.FullScreen_RefreshRateInHz = 50 ;
	}
	else
		xbApp.m_d3dpp.FullScreen_RefreshRateInHz = 60 ;
*/

    xbApp.Run();
}

//-----------------------------------------------------------------------------
// Name: CXBoxSample (constructor)
// Desc: Constructor for CXBoxSample class
//-----------------------------------------------------------------------------
CXBoxSample::CXBoxSample() 
            :CXBApplication()
{
    m_bDrawHelp = FALSE;
	files = NULL ;
	global_error_message[0] = 0 ;

	m_steps = 0 ;

}

int CXBoxSample::init_white_texture()
{
	// Release any previous texture
	if (WhiteTexture) 
	{ 
		WhiteTexture->Release();
		WhiteTexture = NULL;
	}
	
	// Create the texture
	D3DXCreateTexture(m_pd3dDevice, 1, 1, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &WhiteTexture);
	
	D3DSURFACE_DESC desc;
    WhiteTexture->GetLevelDesc(0, &desc);


	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	rectSource.bottom = 0;
	rectSource.right  = 0 ;

	D3DLOCKED_RECT d3dlr;
	WhiteTexture->LockRect(0, &d3dlr, &rectSource, 0);

	DWORD color ;

	color = 0xFFFFFFFF ;

	memcpy( d3dlr.pBits, &color, sizeof(color) ) ;

	// Unlock our texture
	WhiteTexture->UnlockRect(0);

	if ( MenuSprite == NULL )
		D3DXCreateSprite(m_pd3dDevice, &MenuSprite);

	return 0;
}

void CXBoxSample::ClearScreen() 
{
	m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL|D3DCLEAR_TARGET,
						 0x00000000, 1.0f, 0L );
	//RenderGradientBackground( 0xFF000000, 0xFF000000 );
	m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Name: Render
// Desc: Renders the scene
//-----------------------------------------------------------------------------
HRESULT CXBoxSample::Render()
{


    return S_OK;
}





#ifdef LIGHTGUN

void CXBoxSample::doZapper()
{
	BOOL bShotFired;
	BOOL bShotHitScreen;
	BOOL bShotMissedScreen;
	int foundgun = 0 ;

	// Check all ports for a lightgun
	for( DWORD i=0; i<4; i++ )
	{
		if( g_Gamepads[i].hDevice && g_Gamepads[i].caps.SubType == XINPUT_DEVSUBTYPE_GC_LIGHTGUN )
		{
			// Copy the gamepad input to the lightgun structure.
			// Note: This is just for convenience so we can refer to a 
			// "lightgun" instead of a "gamepad".
			m_lightgun.CopyInput( &g_Gamepads[i], i );
			foundgun = 1 ;
			break ;

		}
	}

	if ( foundgun == 0 )
	{
		return ;
	}

	//m_lightgun.DisplayWhiteField() ;

	// Make sure the gun is properly calibrated. Note that this is called every
	// frame in case the state of the display changes
	m_lightgun.VerifyCalibrationState( FALSE );

	// Set the vibration motors
	//m_Lightgun.SetVibrationMotors( m_wLeftMotorSpeed, m_wRightMotorSpeed );


	m_lightgun.Update( &bShotFired, &bShotHitScreen, &bShotMissedScreen );

	m_zapperDat[2] = 0 ;

	if ( bShotFired )
	{
		m_zapperDat[2] |= 1 ;
		if ( bShotMissedScreen )
		{
			m_zapperDat[2] |= 2 ;
		}
	}

	FLOAT fWidth = 640.0f ;
	FLOAT fHeight = 480.0f ;
    FLOAT fThumbLX = (fWidth/2) + (fWidth/2)*(m_lightgun.sThumbLX+0.5f)/32767.5f;
    FLOAT fThumbLY = (fHeight/2) - (fHeight/2)*(m_lightgun.sThumbLY+0.5f)/32767.5f;


	if ( ( fThumbLX > m_nScreenX ) && ( fThumbLX < m_nScreenX + m_nScreenMaxX ) &&
		 ( fThumbLY > m_nScreenY ) && ( fThumbLY < m_nScreenY + m_nScreenMaxY ) )
	{
		m_zapperDat[0] = ((fThumbLX - m_nScreenX)*256)/m_nScreenMaxX ;
		m_zapperDat[1] = ((fThumbLY - m_nScreenY)*240)/m_nScreenMaxY ;
	}
	else
	{
		m_zapperDat[0] = 0 ;
		m_zapperDat[1] = 0 ;
	}

	/*
   *x=*x*VNSWID/(t.right?t.right:1);
   *y=*y*totallines/(t.bottom?t.bottom:1);
  }
  else
  {
   *x/=winsizemul;
   *y/=winsizemul;
  }
  *x+=VNSCLIP;
 }

 *y+=srendline;
*/
}

#endif

//extern int emulating ;

int CXBoxSample::pollXBoxControllers( )
{
	DWORD retval ;
	DWORD emuval ;
	DWORD keystroke_iter ;

	XBInput_GetInput();

	for ( int i = 0 ; i < 4 ; i++ )
	{
		retval = 0 ;


		if ( g_Gamepads[i].hDevice )
		{
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_A] > 25 )
			{
				retval |= XBOX_A ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_B] > 25 )
			{
				retval |= XBOX_B ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_X] > 25 )
			{
				retval |= XBOX_X ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_Y] > 25 )
			{
				retval |= XBOX_Y ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_BLACK] > 25 )
			{
				retval |= XBOX_BLACK ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_WHITE] > 25 )
			{
				retval |= XBOX_WHITE ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_DPAD_UP ) 
			{
				retval |= XBOX_DPAD_UP ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_DPAD_DOWN ) 
			{
				retval |= XBOX_DPAD_DOWN ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_DPAD_LEFT ) 
			{
				retval |= XBOX_DPAD_LEFT ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ) 
			{
				retval |= XBOX_DPAD_RIGHT ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_START )  
			{
				retval |= XBOX_START ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_BACK )  
			{
				retval |= XBOX_BACK ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_LEFT_THUMB )  
			{
				retval |= XBOX_LEFT_THUMB ;
			}
			if ( g_Gamepads[i].wButtons & XINPUT_GAMEPAD_RIGHT_THUMB )  
			{
				retval |= XBOX_RIGHT_THUMB ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] > 25 )
			{
				retval |= XBOX_LEFT_TRIGGER ;
			}
			if ( g_Gamepads[i].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] > 25 )
			{
				retval |= XBOX_RIGHT_TRIGGER ;
			}
			if ( g_Gamepads[i].fX1 > 0.30f )
			{
				retval |= XBOX_LTHUMB_RIGHT ;
			}
			if ( g_Gamepads[i].fX1 < -0.30f )
			{
				retval |= XBOX_LTHUMB_LEFT ;
			}
			if ( g_Gamepads[i].fY1 > 0.30f )
			{
				retval |= XBOX_LTHUMB_UP ;
			}
			if ( g_Gamepads[i].fY1 < -0.30f )
			{
				retval |= XBOX_LTHUMB_DOWN ;
			}
			if ( g_Gamepads[i].fX2 > 0.30f )
			{
				retval |= XBOX_RTHUMB_RIGHT ;
			}
			if ( g_Gamepads[i].fX2 < -0.30f )
			{
				retval |= XBOX_RTHUMB_LEFT ;
			}
			if ( g_Gamepads[i].fY2 > 0.30f )
			{
				retval |= XBOX_RTHUMB_UP ;
			}
			if ( g_Gamepads[i].fY2 < -0.30f )
			{
				retval |= XBOX_RTHUMB_DOWN ;
			}
		}
		m_xboxControllers[i] = retval ;

		emuval = 0 ;
		keystroke_iter = 0 ;


		m_emuControllers[i] = emuval ;
		//sprintfx( "emucont %u val %08.8Xu\r\n", i, emuval ) ;

	}


	return 0 ;
}

BOOL CXBoxSample::SetRefreshRate(INT iRefreshRate)
{
	char xmsg[100] ;

	/*
	CHAR szDebug[64];
	wsprintf(szDebug,"SetRefreshRate: %d\n",iRefreshRate);
	OutputDebugString(szDebug);

	BOOL bIsUsingWidescreenSignal	= m_d3dpp.Flags & D3DPRESENTFLAG_WIDESCREEN;
	BOOL bIsUsingPAL							= XGetVideoStandard() & XC_VIDEO_STANDARD_PAL_I;
	BOOL bSupports60Hz						= ( (XGetVideoFlags() & XC_VIDEO_FLAGS_PAL_60Hz) || (!bIsUsingPAL) );

	
	if ( (!bIsUsingPAL) && (iRefreshRate==50) )
	{
		OutputDebugString("User display does not support 50hz\n");
		return FALSE;
	}

	if ( (!bSupports60Hz) && (iRefreshRate==60) )
	{
		OutputDebugString("User display does not support 60hz\n");
		return FALSE;
	}

	/* resolutions which support pal 60:
	/* 640x480, 720x480 
	/* 640x240, 720x240 

	bool bResolutionOK=false;
	if (m_d3dpp.BackBufferWidth ==640 && m_d3dpp.BackBufferHeight==480) bResolutionOK=true;
	if (m_d3dpp.BackBufferWidth ==720 && m_d3dpp.BackBufferHeight==480) bResolutionOK=true;
	if (m_d3dpp.BackBufferWidth ==640 && m_d3dpp.BackBufferHeight==240) bResolutionOK=true;
	if (m_d3dpp.BackBufferWidth ==720 && m_d3dpp.BackBufferHeight==240) bResolutionOK=true;
	if ( !bResolutionOK && bIsUsingPAL && (iRefreshRate==60) )
	{
		wsprintf(szDebug,	"Unable to use PAL60 at %dx%d resolution.\n",
							m_d3dpp.BackBufferWidth,
							m_d3dpp.BackBufferHeight);
		OutputDebugString(szDebug);
		return FALSE;
	}

	if ( (bIsUsingPAL && bIsUsingWidescreenSignal) && (iRefreshRate==60) )
	{
		OutputDebugString("Xbox hardware does not support PAL60 and widescreen signal.\n");
		OutputDebugString("Widescreen signal has been disabled.\n");
		m_d3dpp.Flags ^= D3DPRESENTFLAG_WIDESCREEN;
	}
	*/

	//if (m_d3dpp.FullScreen_RefreshRateInHz != iRefreshRate)
	//{
		m_d3dpp.FullScreen_RefreshRateInHz = iRefreshRate;
	DWORD res = 	m_pd3dDevice->Reset(&m_d3dpp);

	sprintf(xmsg, "res=%u, ok=%u\r\n", res, DS_OK ) ;

	//}

	return TRUE;
}

HRESULT CXBoxSample::Initialize()
{


	//m_logfile = fopen( "D:\\err.log", "wb" ) ;



    // Create DirectSound
    if( FAILED( DirectSoundCreate( NULL, &(m_sound.dsound),  NULL ) ) )
        return E_FAIL;

	if ( ( XCreateSaveGame( "U:\\", PLATFORM_SAV, OPEN_ALWAYS, 0, g_savePath, 500 ) ) != ERROR_SUCCESS )
	{
        //return E_FAIL;
	}

	m_sound.dsound_init() ;

	m_sound.m_fps = m_d3dpp.FullScreen_RefreshRateInHz ;



	return S_OK ;
}


#define EMU_RESET			0x3B		//; F1  (Reset)
#define EMU_SELECT			0x3C		//; F2  (Select)
#define EMU_BW				0x3D		//; F3  (B/W)
#define EMU_COLOR			0x3E		//; F4  (Color)
#define EMU_P1EASY			0x3F		//; F5  (P0 easy)
#define EMU_P1HARD			0x40		//; F6  (P0 hard)
#define EMU_P2EASY			0x41		//; F7  (P1 easy)
#define EMU_P2HARD			0x42		//  F8  (P1 hard)


#define P1LEFT 		0x4B		//; p1 left
#define P1RIGHT		0x4D		//; p1 right
#define P1UP 		0x48		//; p1 up
#define P1DOWN 		0x50		//; p1 down
#define P1FIRE 		0x1d		//; p1 fire
#define P1BG_B 		0x36        //; p1 booster bg
#define P1BG_T 		0x35		//; p1 trigger bg

#define P2LEFT 			0x1f		//; S (P2 left)
#define P2RIGHT			0x21		//; F (P2 right)
#define P2UP 			0x12		//; E (P2 up)
#define P2DOWN 			0x20		//; D (P2 down)
#define P2FIRE 			0x31		//; N (P2 fire)
#define P2BG_T 			0x30		//; B (P2 booster grip - trigger)
#define P2BG_B 			0x2F		//; V (P2 booster grip - booster)


#define Key0 			0x00b
#define Key1 			0x002
#define Key2 			0x003
#define Key3 			0x004
#define Key4 			0x005
#define Key5 			0x006
#define Key6 			0x007
#define Key7 			0x008
#define Key8 			0x009
#define Key9 			0x00a

#define KeyQ 			0x010
#define KeyW 			0x011
#define KeyA 			0x01E
#define KeyZ 			0x02C
#define KeyX 			0x02D
#define KeyC 			0x02E
#define KeyU 			0x016
#define KeyI 			0x017
#define KeyO 			0x018
#define KeyJ 			0x024
#define KeyK 			0x025
#define KeyL 			0x026
#define KeyM 			0x032
#define KeyComma 		0x033		
#define KeyDot 		0x034		

#define KeyG 			0x022
#define KeyH 			0x023
#define KeyP 			0x019
#define KeyR 			0x013
#define KeyT 			0x014
#define KeyY 			0x015
#define KeyColon 		0x027

#define KeyS 			0x01f
#define KeyF 			0x021
#define KeyE 			0x012
#define KeyD 			0x020
#define KeyN 			0x031
#define KeyB 			0x030
#define KeyV 			0x02F

#define P1Pad1 	Key7
#define P1Pad2 	Key8
#define P1Pad3 	Key9
#define P1Pad4 	KeyU
#define P1Pad5 	KeyI
#define P1Pad6 	KeyO
#define P1Pad7 	KeyJ
#define P1Pad8 	KeyK
#define P1Pad9 	KeyL
#define P1PadStar 	KeyM			
#define P1Pad0 	KeyComma
#define P1PadPound 	KeyDot			

#define P2Pad1 	Key1
#define P2Pad2 	Key2
#define P2Pad3 	Key3
#define P2Pad4 	KeyQ
#define P2Pad5 	KeyW
#define P2Pad6 	KeyE
#define P2Pad7 	KeyA
#define P2Pad8 	KeyS
#define P2Pad9 	KeyD
#define P2PadStar 	KeyZ			
#define P2Pad0 	KeyX
#define P2PadPound 	KeyC		

#define		JOY_1		0x0010
#define		JOY_2		0x0020
#define		JOY_3		0x0040
#define		JOY_4		0x0080
#define		JOY_UP		0x0100
#define		JOY_DOWN	0x0200
#define		JOY_LEFT	0x0400
#define		JOY_RIGHT	0x0800
#define		JOY_5		0x1000
#define		JOY_6		0x2000

unsigned int CXBoxSample::handleEvents()
{

	unsigned int retval, joy[2] ;
	static int didfilter = 0 ;


	if ( g_app->pollXBoxControllers() )
	{
		return 0 ;
	}
	
	joy[0] = 0 ;
	joy[1] = 0 ;

	for ( int i = 0 ; i < 2 ; i++ )
	{
		if ( m_xboxControllers[i] & XBOX_A )
		{
			joy[i] |= JOY_1 ;
		}
		if ( m_xboxControllers[i] & XBOX_B )
		{
			joy[i] |= JOY_2 ;
		}
		if ( m_xboxControllers[i] & XBOX_X )
		{
			joy[i] |= JOY_3 ;
		}
		if ( m_xboxControllers[i] & XBOX_Y )
		{
			joy[i] |= JOY_4 ;
		}
		if ( m_xboxControllers[i] & XBOX_START )
		{
			joy[i] |= JOY_5 ;
		}
		if ( m_xboxControllers[i] & XBOX_BACK )
		{
			joy[i] |= JOY_6 ;
		}
		if ( ( m_xboxControllers[i] & XBOX_DPAD_UP ) || ( m_xboxControllers[i] & XBOX_LTHUMB_UP ) )
		{
			joy[i] |= JOY_UP ;
		}
		if ( ( m_xboxControllers[i] & XBOX_DPAD_DOWN ) || ( m_xboxControllers[i] & XBOX_LTHUMB_DOWN ) )
		{
			joy[i] |= JOY_DOWN ;
		}
		if ( ( m_xboxControllers[i] & XBOX_DPAD_LEFT ) || ( m_xboxControllers[i] & XBOX_LTHUMB_LEFT ) )
		{
			joy[i] |= JOY_LEFT ;
		}
		if ( ( m_xboxControllers[i] & XBOX_DPAD_RIGHT ) || ( m_xboxControllers[i] & XBOX_LTHUMB_RIGHT ) )
		{
			joy[i] |= JOY_RIGHT ;
		}

	}

	if ( ( m_xboxControllers[0] & XBOX_RIGHT_THUMB ) || ( m_xboxControllers[1] & XBOX_RIGHT_THUMB ) )
	{
		if ( didfilter == 0 )
		{
			xboxChangeFilter() ;
			didfilter = 1 ;
		}
	}
	else
	{
		didfilter = 0 ;
	}

	return (joy[1] << 16 ) | joy[0] ;

}




void CXBoxSample::xboxChangeFilter() 
{
	g_app->m_xboxSFilter = (g_app->m_xboxSFilter+1)%NUM_SOFTWARE_FILTERS ;

	saveSettings( "e:\\saves\\openborx\\borx.cfg" ) ;

	memset( g_app->g_pDeltaBuff, 0xFF, 480*g_app->m_pitch ) ;

	sprintf( global_error_message, "%s Filtering", SOFTWARE_FILTERS[m_xboxSFilter].name ) ;
	debug_printf("%s Filtering", SOFTWARE_FILTERS[m_xboxSFilter].name);
	m_msgDelay = 120 ;
}








#define CD_SECS 60
#define CD_FRAMES 75


DWORD WINAPI Sound_ThreadFunc( LPVOID lpParam ) 
{ 

	float FPS ;
	unsigned int perfCurr[2] ;
	unsigned int perfPrev[2] ;

	QueryPerformanceCounter((union _LARGE_INTEGER *) perfPrev);

	while ( 1 )
	{

		do
		{
			QueryPerformanceCounter((union _LARGE_INTEGER *) perfCurr);

			if (perfCurr[0] != perfPrev[0])
			{					
				FPS = (float) (m_performanceFreq[0])  / (float) (perfCurr[0] - perfPrev[0]);
				//sprintf( global_error_message, "fps=%.1f %.1f\r\n", FPS, desiredFPS);
				//m_msgDelay = 20 ;
			}
			else
			{
				FPS = 200.0f ;
				//sprintf( global_error_message, "fps=too much...\r\n");
				//m_msgDelay = 20 ;
			}
			Sleep(1) ;

			//view_fps = 0;
		} while ( FPS > 120 ) ;

		perfPrev[0] = perfCurr[0];

		g_app->m_sound.process( g_app->m_throttle ) ;
		
	}

    return 0; 
}

void CXBoxSample::doScreenSize()
{
	WCHAR str[200];
	int x, y, maxx, maxy ;
	float fx, fy, fmaxx, fmaxy ;
	float origw, origh ;
	DWORD mtime ;
	//D3DXVECTOR2 vecScale, vecTranslate ;

	mtime = GetTickCount() ;

	x = m_nScreenX ;
	y = m_nScreenY ;
	maxx = m_nScreenMaxX;
	maxy = m_nScreenMaxY ;

	fx = (float)x ;
	fy = (float)y ;
	fmaxx = (float)maxx ;
	fmaxy = (float)maxy ;

	origw = (float)m_nScreenMaxX/m_gameVecScale.x ;
	origh = (float)m_nScreenMaxY/m_gameVecScale.y ;

	while ( 1 )
	{
		m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,
							 0x00000000, 1.0f, 0L );
		//RenderGradientBackground( 0xFF000000, 0xFF000000 );


		x = (int)fx ;
		y = (int)fy ;
		maxx = (int)fmaxx ;
		maxy = (int)fmaxy ;

		D3DXCOLOR d3color(1.0, 1.0, 1.0, 1.0);
		m_gameVecScale.x = (float)maxx / ((float)origw);
		m_gameVecScale.y = (float)maxy / ((float)origh);
		m_gameVecTranslate.x = x ;
		m_gameVecTranslate.y = y ;
		//m_pnlGameScreen.SetAlpha( 0x80) ;
		m_pnlGameScreen.Render(m_gameRectSource.left,m_gameRectSource.top,m_gameRectSource.right,m_gameRectSource.bottom,x,y,maxx,maxy) ;
		//m_pnlGameScreen.SetAlpha( 0xFF) ;
		//Sprite->Draw(Texture, &m_gameRectSource, &m_gameVecScale, NULL, 0, &m_gameVecTranslate, d3color);


		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );

        XBInput_GetInput();
		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			break ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_nScreenX = x ;
			m_nScreenY = y ;
			m_nScreenMaxX = maxx ;
			m_nScreenMaxY = maxy ;
			saveSettings( "e:\\saves\\openborx\\borx.cfg" ) ;
			break ;
		}
		else
		{
			if ( g_Gamepads[0].hDevice )
			{
				if ( GetTickCount() - mtime > 5 )
				{
					mtime = GetTickCount() ;
					fx += (g_Gamepads[0].fX1) ;
					fy -= (g_Gamepads[0].fY1) ;
					fmaxx += (g_Gamepads[0].fX2) ;
					fmaxy -= (g_Gamepads[0].fY2) ;
				}
			}
		}
	}

}

void CXBoxSample::initConsole( UINT32 idx, int isFavorite, int forceConfig )
{
	char                filename[500] ;
	char				shortpath[100] ;
	unsigned char       *gimage ;
	int                 ntsccol ;
	FILE				*infile ;
	UINT32				fsize ;
	char *forcebuf ;
	int isOther ;



	m_refreshRate = m_d3dpp.FullScreen_RefreshRateInHz ;

	m_skipNext = 0 ;

	sprintfx( "begin initcons\r\n") ;

	xbox_print_memory() ;


	m_throttle = 0 ;

	for ( int i = 0 ; i < 4 ; i++ )
	{
		m_emuControllers[i] = 0 ;
	}


	global_error_message[0] = 0 ;




	m_numFrames = 0 ;


	m_sound.init() ;

	sprintfx("init\r\n") ;

	// Create our texture
	init_texture();

	// Create our sprite driver
	if ( Sprite == NULL )
		D3DXCreateSprite(m_pd3dDevice, &Sprite);
	



	sprintfx("init\r\n") ;

	m_fAppTime = 0.0f ;

	m_steps = 0 ;
	//m_sound.pause( FALSE ) ;

	sprintfx( "about to vba_main %s\r\n", filename ) ;


	m_startTime = GetTickCount() ;

	//m_plaything.FreeSprites() ;



	QueryPerformanceCounter((union _LARGE_INTEGER *) m_performancePrev);

	//processEmu(FALSE) ;
	//sprintfx( "about to vba_main %s\r\n", filename ) ;
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;

	xbox_set_refreshrate(60) ;

	//Then start it up
	m_sound.pause( FALSE ) ;

	loadSettings( "e:\\saves\\openborx\\borx.cfg" ) ;

    g_hSoundThread = CreateThread( 
        NULL,                        // (this parameter is ignored)
        0,                           // use default stack size  
        Sound_ThreadFunc,                  // thread function 
        NULL,                // argument to thread function 
        0,                           // use default creation flags 
        &g_dwSoundThreadId);                // returns the thread identifier 


	bormain( 0, NULL) ;
	//vba_main( 0, filename, 	m_GBAuseBios,

	//put 3 frames of data in the audio buffer
	//processEmu(FALSE) ;
	//sprintfx("init\r\n") ;
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;

	//sprintfx("init\r\n") ;
	//Then start it up


}



void CXBoxSample::cleanupConsole( )
{


}





#ifdef __cplusplus
extern "C" {
#endif


void sprintfx( const char *fmt, ... )
{
    va_list	va;
    va_start(va, fmt);
	vsprintf( gxmsg, fmt, va);
	va_end( va ) ;
	//writexbox(gxmsg) ;
}

void xbox_resize()
{
	g_app->doScreenSize() ;
}

unsigned int xbox_getfix_Xa()  //disable xa
{
	return g_app->m_psxfix_Xa ;
}
unsigned int xbox_getfix_Sio()  //always sio irq on
{
	return g_app->m_psxfix_Sio ;
}
unsigned int xbox_getfix_Mdec()   //b/w movies
{
	return g_app->m_psxfix_Mdec ;
}
unsigned int xbox_getfix_Cdda()  //disable cdda
{
	return g_app->m_psxfix_Cdda ;
}
unsigned int xbox_getfix_Cpu()   //cpu interpreter (slow, maybe more compatible)
{
	return g_app->m_psxfix_Cpu ;
}
unsigned int xbox_getfix_SpuIrq()  //always spu irq on
{
	return g_app->m_psxfix_SpuIrq ;
}
unsigned int xbox_getfix_VSyncWA()   // InuYasha Sengoku Battle fix
{
	return g_app->m_psxfix_VSyncWA ;
}





unsigned int xbox_get_vandal_heart_fix() 
{
	return g_app->m_vandalFix ;
}

DWORD xbox_get_bit_depth() 
{
	return g_app->m_bitDepth ;

}

void xbox_set_memory_ptr( unsigned char *ptr )
{
}

unsigned int xbox_get_framelimit() 
{
	return g_app->m_framelimit ;
}
unsigned int xbox_get_frameskip() 
{
	return g_app->m_frameskip ;
}
unsigned int xbox_get_graphics_fixes() 
{
	//sprintfx("graphicfix=%02.2X\r\n", g_app->m_graphicsFixes ) ;

	return g_app->m_graphicsFixes ;
}

void xbox_clear_screen()
{
	g_app->ClearScreen() ;
}

unsigned char* xbox_get_biosfile() 
{
	return g_app->m_biosfile ;
}

unsigned char* xbox_get_memcard1() 
{
	return g_app->m_memcard1 ;
}

unsigned char* xbox_get_memcard2() 
{
	return g_app->m_memcard2 ;
}

unsigned char* xbox_get_saveprefix()
{
	return (unsigned char*)g_app->g_saveprefix ;
}

unsigned long xbox_get_bytes_buffered() 
{
//	return g_app->m_sound.get_buffered_bytes() ;
	return 0 ;
}



unsigned int xbox_get_pitch()
{
	return g_app->m_pitch ;
}

unsigned char *xbox_cdbuffer() 
{

	return (g_app->m_ptrCdBuf)+12 ;
}


void xbox_feed_stream() 
{
	//sprintfx( "before feed\r\n") ;
	g_app->m_sound.process(g_app->m_throttle) ;
	//sprintfx( "after feed\r\n") ;
	//g_app->m_cdda.process() ;
}



unsigned long xbox_gettime()
{
	
	FILETIME ft ;

	GetSystemTimeAsFileTime( &ft ) ;

	return 0 ;
	//return ft.dwLowDateTime / 100 ;
	
	//return GetTickCount() ;
}
unsigned long xbox_gettime2()
{
	
	return GetTickCount() ;
}

void xbox_loading_msg( LPCTSTR msg ) 
{
//	g_app->WriteLoadMessage(msg) ;

}

void xbox_exception_msg( LPCTSTR msg ) 
{
//	g_app->WriteExceptionMessage(msg) ;

}


unsigned char * xbox_get_screen_buffer()
{
	return g_app->g_pBlitBuff ;

}

void xbox_pause_audio( int state ) 
{
	//g_mp3player->pause( state ) ;
	g_app->m_sound.pause( state ? true : false ) ;
}

int xbox_read_input(int port) 
{
	//writexbox( "before readinput") ;
	//return g_app->ReadJoypad( port ) ;
	//writexbox( "after readinput") ;
	return 0 ;
}

unsigned int xbox_check_events()
{
	//writexbox( "before events") ;
	return g_app->handleEvents() ;
	//writexbox( "after events") ;
	//return 0 ;
}

void xbox_put_image( unsigned char *buf )
{
	//writexbox( "before render") ;
	//g_sound->process() ;
	//g_app->m_sound.process( g_app->m_throttle ) ;

	if ( g_app->m_throttle )
		g_app->m_throttle-- ;

	if ( g_app->m_throttle == 0 )
		g_app->render_to_texture(buf) ;

	//writexbox( "after render") ;
}

void xbox_set_palette( char *palette )
{
	g_app->setPalette( (unsigned char*)palette) ;
}

void xbox_init()
{
	XGetCustomLaunchData();
}

void xbox_return() 
{
	XReturnToLaunchingXBE() ;
}


void xbox_Sleep( int d )
{
	Sleep( d ) ;
}

unsigned int xbox_read_port( int which )
{
	return g_app->m_emuControllers[which] ;
}

unsigned int xbox_get_throttle()
{
	return g_app->m_throttle ;
}

unsigned long lastCount = 0 ;

void xbox_timer_init()
{
	lastCount = GetTickCount() ;
}

unsigned long xbox_timer_getinterval( int freq ) 
{
	unsigned long newCount = GetTickCount() ;
	unsigned long retval ;

	retval = (newCount - lastCount)/ ( 1000/freq) ;

	if ( ( retval == 0 ) && ( freq < 100 ) )
		retval = 1 ;

	lastCount = newCount ;

	return retval ;
}

void xbox_open_zip( char *hugozipfile )
{
	//writexbox( "before zip") ;
	//g_app->rom_load_zip( hugozipfile ) ;
	//writexbox( "after zip") ;
}
void xbox_set_RAM_location() 
{
	m_memory_locations[0] = NULL ;


}

int xbox_get_filter()
{
	return g_app->m_xboxSFilter ;
}


#ifdef __cplusplus
}
#endif
void CXBoxSample::processEmu( BOOL render )
{
/*			
			updateCheats2() ;

		    sms_frame( m_skipNext );

			if ( render  )
			{
				render_to_texture(1,1);
				m_numFrames++ ;
			}

			m_skipNext = m_sound.process( (char*)snd.buffer, snd.bufsize )  ;
			m_mp3player.process() ;
			UpdatePalette() ;
			handleEvents();
			
			while ( m_skipNext && ( m_state != MAIN_MENU ) )
			{
				sprintfx( "trapped in hold loop\r\n") ;
				updateCheats2() ;

				sms_frame( m_skipNext );

				m_skipNext = m_sound.process( (char*)snd.buffer, snd.bufsize )  ;
				m_mp3player.process() ;
				UpdatePalette() ;
				handleEvents();
			}

*/
}



