#define KEYBOARDMENU 1
#define FLOATSTICK
#define CHECKRUMBLECHEATS
#define CHECKGAMESCREENSIZE
#define NATIVEASPECT
#define BOOTXBOX
#define NEWSAVEPOS2
#define CHECKAVAILROMS
#define EMU_VERSION 4
#define CHECKED_RESET_SOFTEN
#define NEWSAVEPOS
#define SHOWFPS
#define WEBSITE
//#define NO_EXTRA_ZIP
#define XBOX_COMPAT_NAME
#define FRSPRITES
#define SAVE_SCREENSTATE
//#define LAUNCHABLE_MEDIA
//#define NO_FILTERS
//#define VIRTUAL_MEM
#define CHECKED_RESET_FLICKER
//#define NO_NETWORK
//#define NO_MP3
#define HARDFILTER_APPLY
#define RELAXCASE
#define CHEAT5000
//#define LIGHTGUN 1
//#define USE_DEBUGCLIENT
//#define NO_CONFIGURATION
//#define SUPPORT_4X
#define USE4X_BLITBUF
#define USE_NETPLAY
//#define DEBUG_KEYBOARD
#define DEBUG_MOUSE 
//#define SAVE_MEMORY



#include <xtl.h>
#include <XBApp.h>
#include <XBFont.h>
#include <XBHelp.h>
#include <xgraphics.h>
#include <assert.h>
#include <d3d8perf.h>
#include "SndXBOX.hxx"
#include <stdio.h>
#include <vector>
#undef UNIX
#include "zlib.h"
#include "unzip.h"
#define UNIX
#include "debugclient.h"
#include "Mp3Player.h"
#include <XBSound.h>
#include "undocumented.h"
#include "iosupport.h"
#include "panel.h"
#include "fonthelper.h"
#include "plaything.h"
#include "smb++.h"
#include "relax.h"
#include "custom_launch_params.h"
#include "colormap.h"
#include "arrow.h"
#include "numpad.h"
#include "numpadg.h"
#include "png.h"
#include "gamescreen.h"
//#include "src\includes\winston.h"
//#include "src\includes\memorysnapshot.h"
//#include "src\includes\keymap.h"
//#include "src\includes\ikbd.h"
//#include "src\includes\decode.h"
//#include "src\includes\floppy.h"
//#include "src\includes\screen.h"
//#include "src\includes\dialogconfigure.h"
//#include "src\includes\dialog.h"
#include "keyboard_api.h"
#include "mouse.h"

#ifdef XPROFILER
#include "XbDm.h"
#endif

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

extern int CPUThrottle;									// Whether or not the CPU is throttled
extern int max_cpf;
char key[256];										// keyboard state buffer
//extern unsigned short *framedata;					// The actual pixel data
unsigned char g_cdr_readmethod = 0 ;
DWORD g_lastScreen = 0 ;

unsigned char g_try_center_screen = 0 ;

#ifdef __cplusplus
extern "C" {
#endif

int throttling =0 ;
int xbox_genlock ;

struct zfile {
    char *name;
    char *zipname;
    FILE *f;
    unsigned char *data;
    int size;
    int seek;
    int deleteafterclose;
    struct zfile *next;
};


int g_textureLocked = 0 ;


int   m_mouseX, m_mouseY, m_mouseButtons ;
int   m_mouseX2, m_mouseY2, m_mouseButtons2 ;
int vkey_to_amiga[256] ;


int throttle = 0 ;
void xbox_set_RAM_location( char *ptr) ;

#include "writepng.h"

#ifdef NO_NETWORK
typedef unsigned int uint32;
typedef unsigned char uint8;
#endif

int Init_2xSaI(uint32 BitFormat);

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 ;
byte keyboard_keystate[256] ;

typedef enum joystick_button ;

int fusemain(int argc, char **argv);
int joystick_press( int which, joystick_button button, int press ) ;
void win32keyboard_keypress( WPARAM wParam, LPARAM lParam ) ;
void win32keyboard_keyrelease( WPARAM wParam, LPARAM lParam ) ;
int snapshot_write( const char *filename ) ;
int snapshot_read( const char *filename ) ;
void fuse_emulation_pause();
void fuse_emulation_unpause();
extern unsigned char RAM[ 17 ][0x4000];
int machine_reset( void );
void display_refresh_all(void) ;

#ifdef __cplusplus
}
#endif

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

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


//extern unsigned char CPU[65536];

#define STATEMEM_SIZE 65536

char *ASPECT_RATIO_NAMES[] = { "None", "Default (Best)", "Spectrum-TV" };
float ASPECT_RATIOS[] = { 1.0f, 1.0f, 320.0f/240.0f };
#define NUM_ASPECT_RATIOS 3

#define PLATFORM_NAME "SPECTRUM"
#define PLATFORM_SAV L"XSPECTRUMSAV"
#define READING_ROMS_STRING L"Reading specgames directory...please wait."
#define PLATFORM_INI "xspectrum.ini"
#define PLAYTHING_INI "plaything.cfg"
#define PLATFORM_MEMORY_POINTER NULL
#define THEMEMUSIC "D:\\XSPECTRUMTHEME.MP3"
#define PLATFORM_FILE_DIR m_defaultRomDir
#define CONSOLE_MEMORY_SIZE 17*0x4000
#define DEFAULT_PARENT_DIR "D:\\specgames\\*"
#define CD_BUF_SECTORS 10
#define CD_DATA_BUFFER_SIZE CD_BUF_SECTORS*2352
#define PROJECTILE_DEF 4 
#define DEFAULT_SKIN "default_xspectrum"
#define DEFAULT_SKIN_DIR "D:\\EMUSKINS"
#define MAIN_MENU_STRING L"DidntXSpectrum Main Menu"
#define MLINE 
#define DEFAULT_SAVE_PATH "E:\\SAVES\\XSPECTRUM"
//#define GAME_GENIE 1
#define EMU_RECORDING_SIZE ( sizeof(DWORD)*4*60*60*10 )

#define DEFAULT_PATTERN_X 320
#define DEFAULT_PATTERN_Y 240

int CODE_LENGTHS[] = { 12  } ;


unsigned char *m_memory_locations[] = { (unsigned char*)RAM } ;
unsigned int  m_memory_sizes[] = { 17*0x4000 } ;

#define NUM_MEMORY_LOCATIONS 1



struct { short Code; byte Pos,Mask; } Keys[256] =
{
  {VK_SPACE,8,0x01},{VK_OEM_7,2,0x01},
  {VK_OEM_4,1,0x20},{VK_OEM_5,1,0x10},{VK_OEM_6,1,0x40},
  {VK_OEM_COMMA,2,0x04},{VK_OEM_MINUS,1,0x04},{VK_OEM_PERIOD,2,0x08},{VK_OEM_2,2,0x10},
  {'0',0,0x01},{'1',0,0x02},{'2',0,0x04},{'3',0,0x08},
  {'4',0,0x10},{'5',0,0x20},{'6',0,0x40},{'7',0,0x80},
  {'8',1,0x01},{'9',1,0x02},{VK_OEM_1,1,0x80},{VK_OEM_PLUS,1,0x08},
  {VK_OEM_3,2,0x02},{'A',2,0x40},{'B',2,0x80},{'C',3,0x01},
  {'D',3,0x02},{'E',3,0x04},{'F',3,0x08},{'G',3,0x10},
  {'H',3,0x20},{'I',3,0x40},{'J',3,0x80},{'K',4,0x01},
  {'L',4,0x02},{'M',4,0x04},{'N',4,0x08},{'O',4,0x10},
  {'P',4,0x20},{'Q',4,0x40},{'R',4,0x80},{'S',5,0x01},
  {'T',5,0x02},{'U',5,0x04},{'V',5,0x08},{'W',5,0x10},
  {'X',5,0x20},{'Y',5,0x40},{'Z',5,0x80},
  {VK_BACK,  7,0x20},
  {VK_TAB,        7,0x08},
  {VK_RETURN,     7,0x80},
  {VK_ESCAPE,     7,0x04},
  {VK_LEFT,       8,0x10},
  {VK_UP,         8,0x20},
  {VK_RIGHT,      8,0x80},
  {VK_DOWN,       8,0x40},
  {VK_F1,         6,0x20},
  {VK_F2,         6,0x40},
  {VK_F3,         6,0x80},
  {VK_F4,         7,0x01},
  {VK_F5,         7,0x02},
  {VK_LSHIFT,    6,0x01}, /* SHIFT      */
  {VK_RSHIFT,    6,0x08}, /* CAPSLOCK   */
  {VK_LCONTROL,  6,0x02}, /* CONTROL    */
  {VK_RCONTROL,  6,0x02}, /* CONTROL    */
  {VK_F5,        6,0x04}, /* GRAPH      */
  {VK_F5,        6,0x04}, /* GRAPH      */
  {VK_DELETE,     8,0x08}, /* DELETE     */
  {VK_INSERT,     8,0x04}, /* INSERT     */
  {VK_PRIOR,  6,0x10}, /* COUNTRY    */
  {VK_NEXT,    7,0x10}, /* STOP/BREAK */
  {VK_HOME,       8,0x02}, /* HOME/CLS   */
  {VK_END,        7,0x40}, /* SELECT     */
  {VK_SPACE,8,0x01},
  {0,0,0x00}               /** The End. **/
};


typedef struct
{

	unsigned int mapping ;
	unsigned int moves[32] ;
	unsigned char endmove ;
	unsigned char delay ;
	unsigned char currmove ;
	unsigned char currdelay ;
} COMBO ;

typedef struct
{
	unsigned int analog_sensitivity ;
	unsigned int emu_buttons[32] ;
	unsigned char emu_buttons_autofire[32] ;
	unsigned char emu_buttons_autofire_last[32] ;
	unsigned int emu_buttons_definition[32] ;
	unsigned int sfx_vol_up ;
	unsigned int sfx_vol_down ;
	unsigned int bgm_vol_up ;
	unsigned int bgm_vol_down ;
	unsigned int throttle ;
	unsigned int save_state ;
	unsigned int load_state ;
	unsigned int change_save_slot ;
	unsigned int screenshot ;
	unsigned int options_menu ;
	unsigned int change_gfx_filter;
	unsigned int toggle_bgm ;
	unsigned int start_recording ;
	unsigned int stop_recording ;
	unsigned int start_playing ;
	unsigned int stop_playing ;
	unsigned int capture_mode ;
	unsigned int virtual_keyboard ;
	unsigned int text_browser ;
	float        stick_sensitivity ;
	unsigned int rewind ;
	unsigned int toggle_rewind ;
	unsigned int toggle_slowdown ;
	COMBO combos[10] ;

} MAPPINGS ;

typedef struct _PLAYTHING_CONFIG
{
	SPRITE_PARAMS sprites[20] ;
	EFFECT_PARAMS effects[3] ;

} PLAYTHING_CONFIG ;

typedef struct _MENU_PARAMS
{
	char bkg[100] ;
	CPanel *panel ;
	int  transparency ;
	int  borderWidth ;
	int  halign ;
	int  valign ;
	int  offsetx ;
	int  offsety ;
	int  maxTextWidth ;
	int  maxNumLines ;
	DWORD normalColor ;
	DWORD selectedColor ;
	DWORD selectedAndNotedColor ;
	DWORD notedColor ;
	DWORD selectBarColor ;
	unsigned int  size ;
	unsigned int  lineHeight; 
	int screenshotX ;
	int screenshotY ;
	int screenshotW ;
	int screenshotH ;
	int screenshotTransparency ;
	int animationDelay ;

	PLAYTHING_CONFIG ptConfig ;

} MENU_PARAMS ;

typedef struct _SKIN_PARAMS
{
	char loadEmuSplash[100] ;
	char loadGameSplash[100] ;
	char menuMoveSound[100] ;
	char menuCancelSound[100] ;
	char menuSelectSound[100] ;
	char menuBkgMusic[100] ;
	char font[100] ;
	int  fade ;
	int  transition ;
	int  loopbgm ;

	MENU_PARAMS mainMenu ;
	MENU_PARAMS gameSelectMenu ;
	MENU_PARAMS otherMenu ;
	MENU_PARAMS popupMenu ;
	MENU_PARAMS loadingMenu ;

} SKIN_PARAMS ;

typedef struct _BUTTON_DEFINITION
{
	char name[40] ;
	unsigned int  value ;
} BUTTON_DEFINITION ;


#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


	BUTTON_DEFINITION g_xboxButtonDefinitions[] = {
		{ "DPad Up", XBOX_DPAD_UP },
		{ "DPad Down", XBOX_DPAD_DOWN },
		{ "DPad Left", XBOX_DPAD_LEFT },
		{ "DPad Right", XBOX_DPAD_RIGHT },
		{ "Start", XBOX_START },
		{ "Back", XBOX_BACK },
		{ "Left Thumb", XBOX_LEFT_THUMB },
		{ "Right Thumb", XBOX_RIGHT_THUMB },
		{ "A", XBOX_A },
		{ "B", XBOX_B },
		{ "X", XBOX_X },
		{ "Y", XBOX_Y },
		{ "Black", XBOX_BLACK },
		{ "White", XBOX_WHITE },
		{ "LTrigger", XBOX_LEFT_TRIGGER },
		{ "RTrigger", XBOX_RIGHT_TRIGGER },
		{ "LThumb Up", XBOX_LTHUMB_UP },
		{ "LThumb Down", XBOX_LTHUMB_DOWN },
		{ "LThumb Left", XBOX_LTHUMB_LEFT },
		{ "LThumb Right", XBOX_LTHUMB_RIGHT },
		{ "RThumb Up", XBOX_RTHUMB_UP },
		{ "RThumb Down", XBOX_RTHUMB_DOWN },
		{ "RThumb Left", XBOX_RTHUMB_LEFT },
		{ "RThumb Right", XBOX_RTHUMB_RIGHT },
		{ "Nothing", 0 },
	} ;

#define NUM_XBOX_BUTTONS ( sizeof( g_xboxButtonDefinitions ) / sizeof(BUTTON_DEFINITION) )

#define VK_0 '0'
#define VK_1 '1'
#define VK_2 '2'
#define VK_3 '3'
#define VK_4 '4'
#define VK_5 '5'
#define VK_6 '6'
#define VK_7 '7'
#define VK_8 '8'
#define VK_9 '9'

#define VK_A 'A'
#define VK_B 'B'
#define VK_C 'C'
#define VK_D 'D'
#define VK_E 'E'
#define VK_F 'F'
#define VK_G 'G'
#define VK_H 'H'
#define VK_I 'I'
#define VK_J 'J'
#define VK_K 'K'
#define VK_L 'L'
#define VK_M 'M'
#define VK_N 'N'
#define VK_O 'O'
#define VK_P 'P'
#define VK_Q 'Q'
#define VK_R 'R'
#define VK_S 'S'
#define VK_T 'T'
#define VK_U 'U'
#define VK_V 'V'
#define VK_W 'W'
#define VK_X 'X'
#define VK_Y 'Y'
#define VK_Z 'Z'


#define JOY_UP           0x01
#define JOY_DOWN         0x02
#define JOY_LEFT         0x04
#define JOY_RIGHT        0x08
#define JOY_1            0x10
#define JOY2_UP          0x20
#define JOY2_DOWN        0x40
#define JOY2_LEFT        0x80
#define JOY2_RIGHT       0x100
#define JOY2_1           0x200
#define SPECRESET        0x400

	BUTTON_DEFINITION g_emuButtonDefinitions[] = {
		{ "Joy1 Up", JOY_UP },
		{ "Joy1 Down", JOY_DOWN },
		{ "Joy1 Left", JOY_LEFT },
		{ "Joy1 Right", JOY_RIGHT },
		{ "Joy1 Fire", JOY_1 },
		{ "Joy2 Up", JOY2_UP },
		{ "Joy2 Down", JOY2_DOWN },
		{ "Joy2 Left", JOY2_LEFT },
		{ "Joy2 Right", JOY2_RIGHT },
		{ "Joy2 Fire", JOY2_1 },

		{ "Space", 0x80000000 | VK_SPACE },
		{ "Enter", 0x80000000 | VK_RETURN },

		{ "0", 0x80000000 | '0' },
		{ "1", 0x80000000 | '1' },
		{ "2", 0x80000000 | '2'},
		{ "3", 0x80000000 | '3' },
		{ "4", 0x80000000 | '4' },
		{ "5", 0x80000000 | '5' },
		{ "6", 0x80000000 | '6' },
		{ "7", 0x80000000 | '7' },
		{ "8", 0x80000000 | '8' },
		{ "9", 0x80000000 | '9' },
		{ "A", 0x80000000 | 'A' },
		{ "B", 0x80000000 | 'B' },
		{ "C", 0x80000000 | 'C' },
		{ "D", 0x80000000 | 'D' },
		{ "E", 0x80000000 | 'E' },
		{ "F", 0x80000000 | 'F' },
		{ "G", 0x80000000 | 'G' },
		{ "H", 0x80000000 | 'H' },
		{ "I", 0x80000000 | 'I' },
		{ "J", 0x80000000 | 'J' },
		{ "K", 0x80000000 | 'K' },
		{ "L", 0x80000000 | 'L' },
		{ "M", 0x80000000 | 'M' },
		{ "N", 0x80000000 | 'N' },
		{ "O", 0x80000000 | 'O' },
		{ "P", 0x80000000 | 'P' },
		{ "Q", 0x80000000 | 'Q' },
		{ "R", 0x80000000 | 'R' },
		{ "S", 0x80000000 | 'S' },
		{ "T", 0x80000000 | 'T' },
		{ "U", 0x80000000 | 'U' },
		{ "V", 0x80000000 | 'V' },
		{ "W", 0x80000000 | 'W' },
		{ "X", 0x80000000 | 'X' },
		{ "Y", 0x80000000 | 'Y' },
		{ "Z", 0x80000000 | 'Z' },

		{ "SemiColon", 0x80000000 | VK_OEM_1 },
		{ "/", 0x80000000 | VK_OEM_2 },
		{ "Period", 0x80000000 | VK_OEM_PERIOD },
		{ "Comma", 0x80000000 | VK_OEM_COMMA },
		{ "Minus", 0x80000000 | VK_OEM_MINUS } ,
		{ "=", 0x80000000 | VK_OEM_PLUS },
		{ "Backspace", 0x80000000 | VK_BACK },
		{ "'", 0x80000000 | VK_OEM_7 },
		{ "Tab", 0x80000000 | VK_TAB },
		{ "Escape", 0x80000000 | VK_ESCAPE },

		{ "Shift", 0x80000000 | VK_LSHIFT },
		{ "Control", 0x80000000 | VK_LCONTROL },

		{ "Up", 0x80000000 | VK_UP },
		{ "Down", 0x80000000 | VK_DOWN },
		{ "Left", 0x80000000 | VK_LEFT },
		{ "Right", 0x80000000 | VK_RIGHT },
		{ "Caps Lock", 0x80000000 | VK_CAPITAL },
		{ "RESET", SPECRESET },

		{ "Nothing", 0 },


	} ;

#define NUM_EMU_BUTTONS ( sizeof( g_emuButtonDefinitions ) / sizeof(BUTTON_DEFINITION) )

#define DEFAULT_BUTTON1  XBOX_DPAD_UP
#define DEFAULT_BUTTON2  XBOX_DPAD_DOWN
#define DEFAULT_BUTTON3  XBOX_DPAD_LEFT
#define DEFAULT_BUTTON4  XBOX_DPAD_RIGHT
#define DEFAULT_BUTTON5  XBOX_A
#define DEFAULT_BUTTON6  0
#define DEFAULT_BUTTON7  0
#define DEFAULT_BUTTON8  0
#define DEFAULT_BUTTON9  0
#define DEFAULT_BUTTON10 0
#define DEFAULT_BUTTON11 XBOX_B
#define DEFAULT_BUTTON12 XBOX_X
#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 MoveCursor() ;
	virtual void    initConsole( UINT32 idx, int isFavorite, int forceConfig ) ;
	virtual void    cleanupConsole( ) ;
	int             handleEvents(  );
	virtual int     init_texture() ;
	virtual void    copyOldSaves() ;
	virtual BOOL    SetRefreshRate(INT iRefreshRate);
	virtual int		init_white_texture();
	virtual int		render_to_texture( unsigned char *msg ) ;
	virtual void    createLocal( char *origfilename, char *newfilename, char* zipfilename, int *zipnumber );
	virtual void	FindAvailRoms(char *dir) ;
	virtual void    editPlaylist( char *filename ) ;
	virtual void    managePlaylists( );
	void            renderMenuText( int selectable, int selected, WCHAR **lines, int numlines, int isPopup, int firstisfirst, int lastislast ) ;
	int             renderMenuTextWrapper( int selectable, int selected, WCHAR **lines, int numlines, int isPopup, CPanel *panel, int menuChoice, int dualColumn, int colSpacing ) ;
	void            renderDualMenuText( int selectable, int selected, WCHAR **lines, int numlines, int isPopup, int colSpacing ) ;
	int             getValuePopup( char *title, int oldValue, int minval, int maxval, CPanel *panel );
	virtual void    doStartSearchMenu() ;
	virtual void	saveKeys( char *keyfile ) ;
	virtual void	loadKeys( char *keyfile ) ;
	virtual int     selectMsxFile( char *msxfilename, char *msxzipfilename, int *msxzipnumber ) ;
	virtual void    doCodeListMenu() ;
	virtual int     receiveNetworkData( );
	virtual int     doMouse( int port);
	virtual void    doChangeHWFilter() ;
	virtual void    applyGameGenie( byte *ROM, unsigned int romsize);
	virtual void    doChangeSWFilter() ;
#ifdef LIGHTGUN
	virtual void    doZapper();
	virtual void    doCalibrateLightgun() ;
#endif
	virtual void    doPlaythingClear( );
	virtual void    saveSettings( char *filename );
	virtual int     loadSettings( char *filename );
	virtual void    doAutofireConfig( int port );
	virtual void    doMainMenu() ;
	virtual int     encodeGameGenie( CHEAT_CODE *code ) ;
	virtual int     decodeGameGenie( CHEAT_CODE *code ) ;
	virtual int     validateCode( char *code, CHEAT_CODE *ccode, int codetype ) ;
	virtual void    checkGeneralEvents() ;
	void            loadMostRecentSaveState( );
	virtual void    loadControllerSettings( char *buf ) ;
	virtual void    saveControllerSettings( FILE *outfile ) ;
	virtual void    doManageCheatCode( int selected );
	virtual void    doConfigureSkin() ;
	virtual void    updateEmuSpecificCheats() ;
	virtual void    applyHardwareFilter() ;
	virtual void    doBrowseScreenshots( ) ;
	void            handleScreenKeyboard( );
	virtual void    doUploadWebsiteConfiguration( char *defaultname );
	virtual void    doDownloadWebsiteConfiguration();
	void            renderScreenKeyboard( );
	virtual void    getKeyboardString( char *buf, int bufsize ) ;
	void            musicControlMenu( CPanel *panel );
	void            doDefaultDirs();
	virtual void    performEmuSpecificOption( int start, int menuChoice ) ;
	int             addEmuSpecificOptions( int start ) ;
	virtual int		showScreenshot( int screenNum, int currSelection, int onlyFavorites, MENU_PARAMS *menu ) ;
	virtual void    saveGameSpecificSettings() ;
	virtual void    doDeleteCode( int selected );
	virtual void    doGraphicsFiltering() ;
	virtual void    doSelectColor( DWORD *pColor, MENU_PARAMS *menuParams );
	virtual void    doTransition( CPanel *pnl1, CPanel *pnl2, int speed, int effect ) ;
	virtual void    emuLaunch( unsigned int gameSelected, unsigned int isFavorite, int forceConfig ) ;
	virtual void    getNewRoot( char *szRoot) ;
	unsigned int    getNewDefinition( unsigned int oldMapping );
	unsigned int    doSelectGame( int onlyFavorites, int canChangeDir, int getPath=0 ) ;
	virtual void    SetupPlaything( );
	virtual void    doLoadNewDisk( int which ) ;
	virtual void    xboxStartRecording() ;
	virtual void    xboxStopRecording() ;
	virtual void    viewTextFile( char *filename ) ;
	virtual void    xboxStartPlaying() ;
	virtual void    xboxStopPlaying() ;
	virtual void    xboxOptionsMenu() ;
	virtual void    doSelectBackground( char *bkgfile, CPanel *ppanel ) ;
	void            createBlankDisk( int floppy_hd, int dd_hd ) ;
	virtual void    doSelectSound( char *soundfile, CXBSound *psound ) ;
	virtual void    doSelectBGM( char *bgmfile ) ;
	virtual void    doSelectFont( char *fontfile ) ;
	virtual void    doConfigureSkinMenu( MENU_PARAMS *menuparams, char *title ) ;
	virtual void    doMenuBackgroundSettings( MENU_PARAMS *menuparams) ;
	virtual void    doMenuTextSettings( MENU_PARAMS *menuparams) ;
	virtual void    doMenuSpriteSettings( MENU_PARAMS *menuparams) ;
	virtual void    doScreenshotSize( MENU_PARAMS *menu );
	virtual void    doSelectTransition() ;
	virtual void    doChangeVideoMode() ;
	virtual void    doSavePlaything() ;
	virtual int     setupNetplay() ;
	virtual void    doLoadPlaything() ;
	virtual void    ColorBar( int xpos, int ypos, int xlen, int ylen, DWORD color );
	virtual void    renderPopupBkg( int numlines ) ;
	unsigned int    getNewMapping( unsigned int oldMapping ) ;
	virtual void    doConfigureControllers() ;
	virtual void    doConfigureController( int port ) ;
	virtual void    doEmulatorDefinitions( int port ) ;
	virtual void    doConfigureGame( char *settingsname, char *keysname ) ;
	virtual void    configureHardDrives( ) ;
	virtual void    doJoypadMappings( int port ) ;
	unsigned int    getNewEmuMapping( unsigned int port, unsigned int combo, unsigned int oldMapping );
	virtual void    doChangeCombo( int port, int combo );
	virtual void    doChangeComboMoves( int port, int combo );
	virtual void    doComboConfig( int port );
	virtual void    doGameJoypadMappings( int port ) ;
	virtual void    doUIJoypadMappings( int port ) ;
	void            doAddGamesharkCodes( char *filepos, char *codedesc);
	void            doShowGamesharkCodes( int which);
	virtual void    doAddFoundCodes() ;
	virtual void    doContinueSearchMenu() ;
	virtual void    doCodeListMenu2() ;
	virtual int     pollXBoxControllers( );
	virtual int     pollNetworkControllers( );
	virtual void    doAddFoundCodes2() ;
	virtual void    doCDGame( ) ;
	virtual void	viewCheatMatches();
	virtual void	viewMemoryDump( unsigned int offset );
	virtual void	doRumbleConfigSelect( int port );
	virtual void	doRumbleConfig( void *rumble );


	
	virtual void    changeMenu( MENU_PARAMS *menuparams1, MENU_PARAMS *menuparams2 ) ;
	virtual void    doConfigureSprite( MENU_PARAMS *menuparams, int which ) ;
	virtual void    doConfigureEffects(MENU_PARAMS *menuparams, int which) ;
	virtual void    doEditCode2( int selected, int numpositions, int codetype ) ;
	virtual void    doContinueSearchMenu2() ;
	virtual void	popupMsg( char *msg, CPanel *panel, int onetime=0 ) ;
	virtual void    doCheatMenu() ;
	virtual void    doEmulatorOptions() ;
	virtual void    doEditGameGenie( int selected ) ;
	virtual void    doFontSize() ;
	virtual void    xboxSaveState() ;
	virtual void    xboxThrottle( int throttle ) ;
	void            configureHardDrive( int drive );
	virtual void    xboxLoadState() ;
	virtual void    xboxChangeFilter() ;
	virtual int     handleExtension( char *ext, char *newfilename, char *zipfilename, int *zipnumber )  ;
	virtual void    xboxScreenshot() ;
	virtual void    xboxChangeState() ;
	virtual int     unzipMSX( char *zipfile, char *newfilename, int *zipnumber );
	virtual void    doLoadSkin( char *skinname, int forceRoot ) ;
	virtual void    doSaveSkin( ) ;
	virtual void    loadSkinMenuSettings( char *szbuf, char *basesection, MENU_PARAMS *menu );
	virtual void    saveSkinMenuSettings( FILE *outfile, char *basesection, MENU_PARAMS *menu );
	virtual void    doSelectSkin() ;
	virtual void    doLoadIni( int forceRoot ) ;
	virtual int		unzipFile( char *zipfile, char *newfilename, int *zipnumber );
	virtual void    doSaveIni() ;
	virtual void    doLoadEmuSpecificIni( char *szbuf) ;
	virtual void    doSaveEmuSpecificIni( FILE *outfile ) ;
	virtual void    doSaveConfig() ;
	virtual void    doScreenSize(int istext ) ;
	virtual void    doNetplayOptions();
	virtual void    addNewNetplayServer( );
	virtual void    saveFavorites();
	virtual int     selectFile( char *filename, char *dirname, int canchangedir, int selectdir, int refreshlist, int initlist  ) ;
	virtual void    viewPlaylist( );
	virtual void    addFavorite( char *favorite ) ;
	virtual void    removeFavorite( unsigned int whichfav) ;
	virtual void    loadFavorites();
	virtual int     yesNoMenu( char *msg, CPanel *panel ) ;
	virtual int     selectNetplayServer() ;
	virtual void    doTextOffset() ;
	virtual int     addGameGenieCode() ;
	virtual int     selectMachineDefaults() ;
	void            ClearScreen() ;
	virtual void    doConfiguration() ;
	virtual void    updateCheats() ;
	virtual void    updateCheats2() ;
	void            doSwapDrive();
	virtual void    processEmu( BOOL render ) ;
	virtual void    fillPresentationParams() ;
	virtual void    cht_load() ;
	virtual void    cht_save() ;
	virtual void    doUtilities( );
	virtual void    doHelp( );
	virtual void    doSettings( );
	virtual void    doSettings2( );
	virtual void    doCheatCodes( );
	virtual void    doGameUtilities( );
	virtual int     selectState( );
	virtual void    deleteSaveFiles( int which, int onlyFavorites ) ;
	virtual void    doEditCode( int which ) ;
	virtual BOOL    hasFiles( int which ) ;
	virtual int     rom_load_zip( char *hugozipfile ) ;
	virtual void    QuickSort( int start, int end ) ;
	void			MenuBar( int xpos, int ypos, int xlen, int ylen ) ;
	virtual void    GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b);
	void            SetPalette( const unsigned int *p, const unsigned char numentries );
	void            renderImage( unsigned char *image) ;
	virtual void    putImage() ;

	

    //Bliss32 m_bliss32;
	DWORD m_startTime ;
	int m_changedGenie ;
	DWORD m_joypad ;
	DWORD m_zapperDat[3] ;
	D3DCOLOR			color_palette[256];
	int                 PaletteChanged ;	
	int m_msxType, m_msxMapper, m_msxController1, m_msxController2 ;
	int m_msxVideo ;
	DWORD m_xboxControllers[4] ;
	DWORD m_prevEmuControllers[4] ;
	DWORD m_emuControllers[4] ;
#ifndef NO_NETWORK
	DWORD m_networkEmuControllers[4] ;
	DWORD m_networkStatus ;
	NETPLAY_SERVER m_netplayServers[32] ;
#endif
	char m_screenshotDir[MAX_PATH] ;
	int m_defaultScreenshots ;

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

	CRelax m_relaxTracks[102] ;
	SMB m_smb;
	Util m_smbUtil ;
	int m_stateNumber ;
	char *m_configurefile ;
	int m_noconfigfile ;
	int  m_smbCdFile ;
	int  m_bUsingSamba ;
	int m_xboxHFilter ;
	int m_xboxSFilter ;
	char m_smbShare[500] ;
	int m_SPECzipnumber ;
	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_tiImageType ;
	unsigned int m_specFileType;
	unsigned int m_specMachineType;
	unsigned int m_specAutoload;
	unsigned int m_specKempston;
	unsigned int m_specJoy1;
	unsigned int m_specJoy2;
	unsigned int m_specJoyKey;
	unsigned int m_specSLT;
	unsigned int m_specTRAP;
	unsigned int m_specTapeSound ;

#ifdef USE_NETPLAY
	CXBSocket m_sockListener ;
	CDebugClient m_sockNetplay;
#endif
#ifndef NO_NETWORK

	int       m_bNetplay ;
	unsigned int m_bNetworkCD ;
#endif
	char m_szSkin[100] ;
	char m_szSkinDir[MAX_PATH] ;
	SKIN_PARAMS m_skin ;
	MENU_PARAMS *pmenuParams ;


	unsigned int m_changedSettings ;
	WCHAR *m_menuText[200] ;

	CPlayThing m_plaything ;



	//PLAYTHING_CONFIG m_ptConfig ;

	PLAYTHING_CONFIG m_ptConfig ;


	MAPPINGS m_mappings[4] ;

	UINT32 topIdx  ;
	UINT32 curr  ;
	CDebugClient m_debugClient ;
	D3DPalette			*m_pd3dPalette ;
	BOOL m_bIsDDrive ;

    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 ;

	CFontHelper m_Font ;

	byte *m_memBuf1, *m_memBuf2, *m_consoleMemory, *m_memMatches ;
	UINT32 m_currentMemMatches ;

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


	FILENAME *files ;
	FAVORITE *m_filesFavorites ;
	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] ;
	gzFile m_cdfile ;
	char m_memcard1[MAX_PATH] ;
	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;
	Mp3Player			m_mp3player;
	//Mp3Player			m_mp3player_cdda;
	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 ;


};

typedef struct {
	DWORD baseAddress ;
	DWORD totalSize ;
	DWORD commitSize ;
	DWORD *allocatedPages ;
	DWORD numpages ;
	DWORD head ;
	DWORD fileoffset ;
	unsigned char readonly ;
} VIRTMEM_LOC ;

VIRTMEM_LOC virtualmem_locs[] =
{
	{ 0, CONSOLE_MEMORY_SIZE, 64*1024, 0, 0, 0, 0 },
	{ 0, CONSOLE_MEMORY_SIZE, 64*1024, 0, 0, 0, 0 },
	{ 0, CONSOLE_MEMORY_SIZE, 64*1024, 0, 0, 0, 0 }  
} ;

#define NUM_VIRTMEM 3
//CDDAXbox  *g_cdda ;

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


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 },
};




void CXBoxSample::doLoadEmuSpecificIni( char *szbuf ) 
{


	//m_noUpdateConfig = GetIniInt( szbuf, "EMU_SPECIFIC", "no_update_config", 0 ) ;
}

void CXBoxSample::doSaveEmuSpecificIni( FILE *outfile ) 
{


	//fprintf( outfile, "[EMU_SPECIFIC]\r\n" ) ;
	//fprintf( outfile, "no_update_config=%u\r\n", m_noUpdateConfig ) ;
	//fprintf( outfile, "\r\n" ) ;


}


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

	D3DCOLOR *palette ;


	Init_2xSaI(565) ;

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

	// Release any previous texture
	if (Texture) 
	{ 
		return 1 ;
		Texture->BlockUntilNotBusy() ;
		Texture->Release();
		Texture = NULL;
	}
	
	theWidth = 1280 ;
	theHeight = 960 ;

	xbox_print_memory() ;



	// Create the texture
	if (D3DXCreateTextureFromFileInMemoryEx(m_pd3dDevice, GAMESCREEN_FILE, sizeof(GAMESCREEN_FILE),
		 //theWidth, theHeight, 1, 0, D3DFMT_LIN_X1R5G5B5, D3DPOOL_MANAGED,
		 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[ 1280*980*2 ];
//	XBuf = g_pBlitBuff ;

	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[1280*980*2];
	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::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) ;


	if ( g_autoLaunchGame )
	{
		changeMenu( &m_skin.otherMenu, &m_skin.mainMenu ) ;
	}
	else
	{
		changeMenu( &m_skin.otherMenu, &m_skin.gameSelectMenu ) ;
	}

	if ( !m_bBgmInGame )
	{
		m_mp3player.pause( FALSE ) ;
	}

	//m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
	//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( const unsigned int *p, const unsigned char numentries )
{

	sprintfx( "setpalette\r\n") ;

	int r,g,b ;
	//m_pd3dPalette->Lock( &color_palette, 0 ) ;


	for ( int i = 0 ; i < numentries ; i++ )
	{
		DWORD color = p[i] ;

		r = ( color >> 19 ) & 0x1F ;
		g = ( color >> 10 ) & 0x3F  ;
		b = ( color >> 3 ) & 0x1F ;

		color_palette[i] = (r << 11 ) | ( g << 5 ) | b ;
	}

	//m_pd3dPalette->Unlock() ;

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

}



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 ) ;
	fwrite( &m_specFileType, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specMachineType, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specAutoload, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specKempston, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specJoy1, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specJoy2, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specJoyKey, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specSLT, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specTRAP, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_SPECzipnumber, sizeof(unsigned int), 1, setfile ) ;
	fwrite( &m_specTapeSound, sizeof(unsigned int), 1, setfile ) ;

	fclose( setfile ) ;

}


int CXBoxSample::loadSettings( char *filename )
{

	FILE *setfile ;
	int sizeread ;

	m_changedSettings = 0 ;

	m_tiImageType = 0 ;
	m_specFileType = 0 ;
	m_specMachineType = 1 ;
	m_specAutoload = 1 ;
	m_specKempston = 1;
	m_specJoy1 = 2;
	m_specJoy2 = 2;
	m_specJoyKey = 2;
	m_specSLT = 1;
	m_specTRAP = 1;
	m_SPECzipnumber = 0 ;
	m_xboxSFilter = 0 ;
	m_specTapeSound = 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 ) ;
	fread( &m_specFileType, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specMachineType, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specAutoload, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specKempston, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specJoy1, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specJoy2, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specJoyKey, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specSLT, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specTRAP, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_SPECzipnumber, sizeof(unsigned int), 1, setfile ) ;
	fread( &m_specTapeSound, sizeof(unsigned int), 1, setfile ) ;

	fclose( setfile ) ;


	if ( ( m_xboxSFilter < 0 ) || ( m_xboxSFilter > NUM_SOFTWARE_FILTERS-1 ) )
		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 CXBoxSample::encodeGameGenie( CHEAT_CODE *code ) 
{
	DWORD encodedVal ;
	int codesize ;
	byte andVal ;
	byte shiftval ;
	byte codeofs ;
	byte highbit ;

	codesize = 6 ;

	code->adr &= 0xFFFF ;
	code->val &=0xFF ;

	encodedVal = ( ( code->adr & 0xF000 ) >> 4 ) |
				 ( ( code->adr & 0x0F00 ) >> 8 ) |
				 ( ( code->adr & 0x00F0 ) << 8 ) |
				 ( ( code->adr & 0x000F ) << 4 ) |
				 ( ( code->val & 0x00F0 ) << 12 ) |
				 ( ( code->val & 0x000F ) << 20 )  ;


	if ( code->type == 0x98 ) //8 char code
	{
		codesize = 8 ;

		encodedVal |= 0x800 ; //8 char codes must have high bit of adr set to 1

		encodedVal = encodedVal << 8 ;
		encodedVal = encodedVal |
				 ( ( code->code[16] & 0x00F0 ) >> 4 ) |
				 ( ( code->code[16] & 0x000F ) << 4 )  ;

		highbit = ( encodedVal & 0x80000000 ) >> 31;
	}
	else
	{
		encodedVal &= ~0x800 ; //6 char codes must have high bit of adr set to 0
		highbit = ( encodedVal & 0x800000 ) >> 23;
	}

	encodedVal = (encodedVal << 1) | highbit;

	andVal = 0xF ;
	shiftval = 0 ;

	if ( codesize == 6 )
		codeofs = 2 ;

	for ( int i = codesize-1 ; i >= 0 ; i-- )
	{
		code->code[i] = GENIETABLE[ ( ( encodedVal & andVal ) >> shiftval ) & 0xF ].code ;
		andVal = andVal << 4 ;
		shiftval += 4 ;

	}

	code->code[codesize] = 0 ;

	return 0 ;
}

int CXBoxSample::decodeGameGenie( CHEAT_CODE *code ) 
{
	DWORD encodedVal ;
	int codesize ;
	byte andVal ;
	byte shiftval ;
	byte codeofs ;
	byte nibble;
	DWORD highbit ;

	codesize = strlen( code->code ) ;
	strupr( code->code ) ;


	encodedVal = 0 ;
	shiftval = 0 ;

	for ( int i = codesize-1 ; i >= 0 ; i-- )
	{
		for ( int j = 0 ; j < 16 ; j++ )
		{
			if ( code->code[i] == GENIETABLE[j].code ) 
			{
				nibble = GENIETABLE[j].nibble ;
				break ; 
			}
		}

		encodedVal |= ( nibble << shiftval ) ;
		shiftval += 4 ;

	}


	if ( codesize == 8 )
	{
		highbit = ( encodedVal & 0x01 ) << 31 ;
	}
	else
	{
		highbit = ( encodedVal & 0x01 ) << 23 ;
	}

	encodedVal = encodedVal >> 1 ;

	encodedVal &= 0x7FFFFFFF ;

	encodedVal |= highbit ;

	if ( codesize == 8 )
	{
		code->type = 0x98 ;
		code->code[16] = ( ( encodedVal & 0x0F ) << 4 ) |
						 ( ( encodedVal & 0xF0 ) >> 4 ) ;
		encodedVal = encodedVal >> 8 ;
	}
	else
	{
		code->type = 0x99 ;
	}



	code->adr = ( ( encodedVal & 0x0F00 ) << 4 ) |
				( ( encodedVal & 0x000F ) << 8 ) |
				( ( encodedVal & 0xF000 ) >> 8 ) |
				( ( encodedVal & 0x00F0 ) >> 4 )  ;

	code->val = ( ( encodedVal & 0x0F0000 ) >> 12 ) |
				( ( encodedVal & 0xF00000 ) >> 20 ) ;

	code->desc[0] = 0 ;

	if ( code->adr >= 0x8000 )
		code->adr -= 0x8000 ;

	return 0 ;
}

int CXBoxSample::addGameGenieCode()
{
	int value ;
	int menuChoice = 0 ;
	int numitems ;

	value = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu);

	
		swprintf( m_menuText[0], L"Add Game Genie Code"  );
		swprintf( m_menuText[1], L"Add 6-Char Code");
		swprintf( m_menuText[2], L"Add 8-Char Code");

		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 3, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			XBInput_GetInput();
			return 1  ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;

			m_changedGenie = 1 ;

			CHEAT_CODE code ;

			code.adr = 0 ;
			code.val = 0 ;
			code.enabled = 0 ;
			code.desc[0] = 0 ;
			memset( code.code, 0, sizeof(code.code) ) ;

			code.type = menuChoice == 0 ? 0x99 : 0x98 ;

			encodeGameGenie( &code ) ;

			m_cheatCodes = (CHEAT_CODE*)realloc( m_cheatCodes, sizeof(CHEAT_CODE) * ( m_numCheats  + 1 ) ) ;

			memcpy( &(m_cheatCodes[m_numCheats]),&code, sizeof(CHEAT_CODE) ) ;
			m_numCheats++ ;

			return 0 ;
		}
	}

	return 1 ;
}


void CXBoxSample::doEditGameGenie( int selected )
{
	char szNewDir[MAX_PATH] ;
	DWORD color ;
	int numpositions ;
	CHEAT_CODE editedCode ;
	FILE *outfile ;
	int numpad ;
	int pos ;
	int panelx, panely ;
	CPanel panel ;
	LPDIRECT3DTEXTURE8	panelTexture ;
	int charspacing ;
	char truncCode[30] ;
	WCHAR msg[50] ;
	WCHAR *lines[100] = { L"L/R Trigger - Change Position", 
							L"A - Select Digit",
							L"START - Save Code",
							L"B - Cancel" } ;
	int posx[4] ;



	if ( selected == -1 )
	{
		return ;
	}


	for ( int i = 0 ; i < 4 ; i++ )
	{
		posx[i] = (640-m_Font.GetWidth( lines[i] )) / 2 ;
	}


	numpad = 0 ;
	pos = 0 ;

	outfile = fopen( "X:\\NUMPADG.PNG", "wb" ) ;
	if ( outfile == NULL )
		return ;

	fwrite( NUMPADG_PNG, sizeof(char), sizeof(NUMPADG_PNG), outfile ) ;
	fclose( outfile ) ;



	pmenuParams = &(m_skin.otherMenu) ;
	
	if (D3DXCreateTextureFromFileEx(m_pd3dDevice, "X:\\NUMPADG.PNG",
		 NUMPADG_WIDTH, NUMPADG_HEIGHT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED,
		 //D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED,
		 D3DX_FILTER_NONE , D3DX_FILTER_NONE, 0, NULL, NULL, &panelTexture )==D3D_OK)
	{
		if ( FAILED(panel.Create(m_pd3dDevice, panelTexture , FALSE, NUMPADG_WIDTH, NUMPADG_HEIGHT)) )
		{
			panelTexture->Release() ;
			return  ;
		}
	}
	else
	{
		return  ;
	}
	
	charspacing = 0 ;

	for ( int i = 0 ; i < 10 ; i++ )
	{
		swprintf( msg, L"%c", '0' + i ) ;
		if ( m_Font.GetWidth( msg ) > charspacing )
			charspacing = m_Font.GetWidth( msg ) ;
	}
	for ( int i = 0 ; i < 6 ; i++ )
	{
		swprintf( msg, L"%c", 'A' + i ) ;
		if ( m_Font.GetWidth( msg ) > charspacing )
			charspacing = m_Font.GetWidth( msg ) ;
	}






	truncCode[0] = 0 ;
	int cnt = 0 ;

	if ( m_cheatCodes[selected].type == 0x98 )
	{
		numpositions = 8 ;
	}
	else
	{
		numpositions = 6 ;
	}

	for ( int i = 0 ; ( cnt < numpositions ) && ( i<19) ; i++ )
	{
		if ( m_cheatCodes[selected].code[i] != ' ' ) 
		{
			truncCode[cnt] = m_cheatCodes[selected].code[i] ;
			cnt++ ;
		}
	}

	truncCode[cnt] = 0 ;

	charspacing += 5 ;
	
	LPDIRECT3DTEXTURE8	colorSquareTexture;

	D3DXCreateTexture(m_pd3dDevice, 1, 1, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &colorSquareTexture);
	
	D3DSURFACE_DESC desc;
    colorSquareTexture->GetLevelDesc(0, &desc);


	RECT rectSource;
	D3DLOCKED_RECT d3dlr;


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


	color = 0x800066CC ;

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

	colorSquareTexture->LockRect(0, &d3dlr, &rectSource, 0);

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

	colorSquareTexture->UnlockRect(0);

	panelx = (640-NUMPAD_WIDTH)/2 ;
	panely = 82 ; 

	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu) ;

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

		D3DXCOLOR d3color( 1.0, 1.0, 1.0, 0.5 ) ;
		//DWORD holdTrans = pmenuParams->panel->m_colDiffuse ;
		//pmenuParams->panel->SetAlpha( (holdTrans>>24) / 2 ) ;
		pmenuParams->panel->Render( );
		m_pnlGameScreen.SetAlpha( 0x80) ;
		m_pnlGameScreen.Render(0,0,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY) ;
		m_pnlGameScreen.SetAlpha( 0xFF) ;

		//Sprite->Draw(Texture, &m_gameRectSource, &m_gameVecScale, NULL, 0, &m_gameVecTranslate, d3color);
		//pmenuParams->panel->SetAlpha( (holdTrans>>24)  ) ;

		panel.Render( panelx, panely, NUMPAD_WIDTH, NUMPAD_HEIGHT ) ;


		//m_mp3player.process() ;


		D3DXVECTOR2 vecScale( 1, 1 ) ;
		D3DXVECTOR2 vecTranslate( panelx + 4 + ( 53 * ( numpad % 4 )), panely + 4 + ( 53 * ( numpad / 4 ) ) ) ;
		D3DXCOLOR sd3color(1.0, 1.0, 1.0, 1.0);
		rectSource.top = 0;
		rectSource.left = 0;
		rectSource.bottom = 49;
		rectSource.right  = 49 ;

		MenuSprite->Draw(colorSquareTexture, &rectSource, &vecScale, NULL, 0, &vecTranslate, sd3color);

		for ( int i = 0 ; i < numpositions ; i++ )
		{
			swprintf( msg, L"%c", truncCode[i] ) ;
			m_Font.DrawText( ((640-(charspacing*numpositions))/2) + i*charspacing, (panely-pmenuParams->lineHeight)-10, 
				pos==i ? pmenuParams->selectedColor : pmenuParams->normalColor, msg, pmenuParams->selectBarColor, pos==i, 0, 0, 0, 0) ;
		}

		for ( int i = 0 ; i < 4 ; i++ )
		{
			m_Font.DrawText( posx[i], panely+NUMPAD_HEIGHT+10 + (pmenuParams->lineHeight*i), 
				pmenuParams->normalColor, lines[i], pmenuParams->selectBarColor, 0, 0, 0, 0, 0) ;
		}


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

		XBInput_GetInput();
		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			XBInput_GetInput();
			break ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;

			switch ( numpad )
			{
				case 0 : truncCode[pos] = 'A' ; break ; 
				case 1 : truncCode[pos] = 'E' ; break ; 
				case 2 : truncCode[pos] = 'G' ; break ; 
				case 3 : truncCode[pos] = 'I' ; break ; 
				case 4 : truncCode[pos] = 'K' ; break ; 
				case 5 : truncCode[pos] = 'L' ; break ; 
				case 6 : truncCode[pos] = 'N' ; break ; 
				case 7 : truncCode[pos] = 'O' ; break ; 
				case 8 : truncCode[pos] = 'P' ; break ; 
				case 9 : truncCode[pos] = 'S' ; break ; 
				case 10 : truncCode[pos] = 'T' ; break ; 
				case 11 : truncCode[pos] = 'U' ; break ; 
				case 12 : truncCode[pos] = 'V' ; break ; 
				case 13 : truncCode[pos] = 'X' ; break ; 
				case 14 : truncCode[pos] = 'Y' ; break ; 
				case 15 : truncCode[pos] = 'Z' ; break ; 
			}

			pos = (pos+1)%numpositions ;
		}
		else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_RIGHT )
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			if ( ( numpad %4 ) == 3 )
				numpad -= 3 ;
			else
				numpad++ ;

		}
		else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_LEFT )
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			if ( ( numpad %4 ) == 0 )
				numpad += 3 ;
			else
				numpad-- ;

		}
		else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_UP )
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			if ( numpad < 4 )
				numpad += 12 ;
			else
				numpad -= 4 ;

		}
		else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_DOWN )
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			if ( numpad > 11 )
				numpad -= 12 ;
			else
				numpad += 4 ;

		}
		else if (g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER])
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			pos = (pos+1)%numpositions ;
		}
		else if (g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER])
		{
			m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
			pos = (pos+(numpositions-1))%numpositions ;
		}
		else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_START )
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;

			memcpy( &editedCode, &(m_cheatCodes[selected]), sizeof(CHEAT_CODE) ) ;
			strcpy( editedCode.code, truncCode ) ;

			if ( ! decodeGameGenie( &editedCode ) )
			{
				memcpy( &(m_cheatCodes[selected]), &editedCode, sizeof(CHEAT_CODE) ) ;
				m_changedGenie = 1 ;
				break ;
			}
			else
			{
				popupMsg( "The code you entered is invalid.", &m_pnlBackgroundOther ) ;
			}
		}
	}

	panelTexture->Release() ;
	colorSquareTexture->Release() ;

}





int CXBoxSample::addEmuSpecificOptions( int start )
{
	swprintf( m_menuText[start], L"Reset Machine" );

	return start+1 ;


}

void CXBoxSample::saveGameSpecificSettings( )
{
	saveKeys( g_keysfile ) ;
	saveSettings( g_settingsfile ) ;

}


void CXBoxSample::doDeleteCode( int selected )
{
	CHEAT_CODE *tempbuf ;

	tempbuf = (CHEAT_CODE*)malloc( sizeof(CHEAT_CODE) * ( m_numCheats - 1 ) ) ;

	memcpy( tempbuf, m_cheatCodes, sizeof(CHEAT_CODE) * selected ) ;

	if ( selected < m_numCheats-1 )
	{
		memcpy( &(tempbuf[selected]), &(m_cheatCodes[selected+1]), sizeof(CHEAT_CODE) * ( (m_numCheats - selected ) - 1) ) ;
	}

	free( m_cheatCodes ) ;

	m_cheatCodes = tempbuf ;
	m_numCheats-- ;
}


void CXBoxSample::updateEmuSpecificCheats( ) 
{
}
void CXBoxSample::doLoadNewDisk( int which )
{

}

void CXBoxSample::performEmuSpecificOption( int start, int menuChoice ) 
{

	if ( menuChoice == start )
	{
		machine_reset() ;
	}

}

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 ;
}

int CXBoxSample::validateCode( char *code, CHEAT_CODE *ccode, int codetype )
{

			ccode->type = strToHex( code, 2 ) ;
			ccode->adr = strToHex( code+2, 6 ) ;
			ccode->val = strToHex( code+8, 4 ) ;


			sprintf( ccode->code, "%02.2X%06.6X %04.4X", ccode->type, ccode->adr, ccode->val & 0xFFFF ) ;

			if ( ( ccode->adr >= CONSOLE_MEMORY_SIZE ) )
			{
				return 0 ;
			}
			else if ( ! ( ( ccode->type == 0x80 ) || ( ccode->type == 0x30 ) || ( ccode->type == 0xD0 ) || ( ccode->type == 0xD1 ) || 
								( ccode->type == 0xD2 ) || ( ccode->type == 0xD3 ) || ( ccode->type == 0xE0 ) || ( ccode->type == 0xE1 ) || 
								( ccode->type == 0xE2 ) || ( ccode->type == 0xE3 ) || ( ccode->type == 0x10 ) || ( ccode->type == 0x11 ) || 
								( ccode->type == 0x20 ) || ( ccode->type == 0x21 ) ) )
			{
				return 0 ;
			}


	return 1 ;
}









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

	InitializeWithScreen() ;
    return S_OK;
}


int CXBoxSample::render_to_texture( unsigned char *amibuf )
{
	RECT src, dst;
	byte *curr1 ; 
	byte *curr2 ;
	DWORD pitchDiff ; 
	D3DCOLOR *palette ;
	char palstr[200] ;
	DWORD pixel ;
	byte r,g,b ;
	int w,h ;

	w = 640 ;
	h = 480 ;
	g_lastScreen = GetTickCount() ;

	m_numFrames++ ;



	if ( m_xboxSFilter == 0 )
	{


	}
	else
	{
#ifndef NO_FILTERS
		//xboxRender( g_pBlitBuff, m_pitch ) ;
		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);
		//SOFTWARE_FILTERS[m_xboxSFilter].blitfunc((unsigned char*)g_pBlitBuff + 640*2,640*2, g_pDeltaBuff, ((unsigned char*)d3dlr.pBits)+d3dlr.Pitch, d3dlr.Pitch, w, h, 0 ) ;
		SOFTWARE_FILTERS[m_xboxSFilter].blitfunc(g_pBlitBuff+1280*2,1280*2, g_pDeltaBuff, ((unsigned char*)d3dlr.pBits)+d3dlr.Pitch, d3dlr.Pitch, 640, 480, 0 ) ;
#endif
	}

	float mx, my ;

	if ( m_xboxSFilter )
	{
		//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)w*SOFTWARE_FILTERS[m_xboxSFilter].multiplier) ;
		my = (float)m_nScreenMaxY / ((float)h*SOFTWARE_FILTERS[m_xboxSFilter].multiplier);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = (h )*SOFTWARE_FILTERS[m_xboxSFilter].multiplier ;
		m_gameRectSource.right  = (w )*SOFTWARE_FILTERS[m_xboxSFilter].multiplier;
	}
	else
	{
		//systemDrawScreenNoFilter( (unsigned char*)d3dlr.pBits) ;
		//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();

		mx = (float)m_nScreenMaxX / ((float)w) ;
		my = (float)m_nScreenMaxY / ((float)h);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		//m_gameRectSource.bottom = screen_h ;
		//m_gameRectSource.right  = screen_w;
		m_gameRectSource.bottom = (h ) ;
		m_gameRectSource.right  = (w );
	}



	g_textureLocked = 0 ;

	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(0,0,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY) ;

//	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 ( g_bShowFPS )
	{
		sprintf( global_error_message, "fps=%.1f", (float)m_numFrames*1000.0/((float)(GetTickCount() - g_dwStartTime)) );
		m_msgDelay = 3 ;

		if ( GetTickCount() - g_dwStartTime > 1000 )
		{
			g_dwStartTime = GetTickCount() ;
			m_numFrames = 0 ;
		}
	}
	if ( global_error_message[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 ( 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
	renderScreenKeyboard() ;
	// End the scene.
	g_pd3dDevice->EndScene();

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

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

/*
	float FPS, desiredFPS ;
	static float statfps = 50 ;
	static float statiter = 1 ;
	static float maxfps = 0 ;

	desiredFPS = 60.0f ;

	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]);
			statfps += FPS ;
			statiter++ ;

			if ( ( FPS < 55 ) && ( FPS > maxfps ) )
				maxfps = FPS ;

			sprintf( global_error_message, "fps=%.1f %.1f %.1f %.1f", FPS, desiredFPS, statfps/statiter, maxfps);
		}
		else
		{
			FPS = 100.0f ;
			sprintf( global_error_message, "fps=too much...\r\n");
		}

		m_msgDelay = 10 ;
		//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::renderImage( unsigned char *image) 
{
	RECT src, dst;
	WORD *curr1 ; 
	byte *curr2 ;
	DWORD pitchDiff ; 
	D3DCOLOR *palette ;
	char palstr[200] ;
	DWORD pixel ;
	byte r,g,b ;
	int w,h ;

	//sprintfx( "renderimage\r\n") ;

	w = 160 ;
	h = 192 ;

	m_numFrames++ ;

	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);



	for ( unsigned int y = 0 ; y < 192 ; y++ )
	{
		DWORD color ;

		if ( 0 ) //m_xboxSFilter )
			curr1 = (WORD*)( g_pBlitBuff + ( y*d3dlr.Pitch )) ;
		else
			curr1 = (WORD*)( (unsigned char*)d3dlr.pBits + ( y*d3dlr.Pitch )) ;

		curr2 = ((byte*)image) + ( y*160 )  ;

		for ( int x = 0 ; x < 160 ; x++ )
		{
			*curr1++ = (color_palette[*curr2++])&0xFFFF ;
		}
		//memcpy( curr1, curr2, theWidth ) ;
	}



	SOFTWARE_FILTERS[m_xboxSFilter].blitfunc(g_pBlitBuff + d3dlr.Pitch,d3dlr.Pitch, g_pDeltaBuff, ((unsigned char*)d3dlr.pBits)+m_pitch, m_pitch, 160, 192, 0 ) ;

	float mx, my ;

	Texture->UnlockRect(0);



}

void CXBoxSample::putImage( ) 
{
	RECT src, dst;
	WORD *curr1 ; 
	byte *curr2 ;
	DWORD pitchDiff ; 
	D3DCOLOR *palette ;
	char palstr[200] ;
	DWORD pixel ;
	byte r,g,b ;
	int w,h ;

	//sprintfx( "putimage\r\n") ;

	w = 160 ;
	h = 192 ;

	m_numFrames++ ;


	float mx, my ;

	if ( 0 ) //m_xboxSFilter )
	{
		//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)w*SOFTWARE_FILTERS[m_xboxSFilter].multiplier) ;
		my = (float)m_nScreenMaxY / ((float)h*SOFTWARE_FILTERS[m_xboxSFilter].multiplier);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = (h )*SOFTWARE_FILTERS[m_xboxSFilter].multiplier ;
		m_gameRectSource.right  = (w )*SOFTWARE_FILTERS[m_xboxSFilter].multiplier;
	}
	else
	{
		//systemDrawScreenNoFilter( (unsigned char*)d3dlr.pBits) ;
		//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();

		mx = (float)m_nScreenMaxX / ((float)w) ;
		my = (float)m_nScreenMaxY / ((float)h);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = (h ) ;
		m_gameRectSource.right  = (w );
	}



	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(0,0,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 ) ;

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

		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 = 60.0f;

	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];
*/

	
}

void CXBoxSample::InitializeEmuSpecific()
{

	FILE *outfile ;

	m_tiImageType = 0 ;
	m_SPECzipnumber = 0 ;
	m_specFileType = 0 ;
	m_specMachineType = 1 ;
	m_specAutoload = 1 ;
	m_specKempston = 1;
	m_specJoy1 = 2;
	m_specJoy2 = 2;
	m_specJoyKey = 2;
	m_specSLT = 1;
	m_specTRAP = 1;
	m_xboxSFilter = 0 ;
	m_specTapeSound = 0 ;

    //m_bliss32.setProgramName("bliss");


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


	//global_init();
	g_pUnpaletteBuff = 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

int CXBoxSample::doMouse( int port)
{
	//xbinput_getinput already called


	//writexbox("readingmouse" ) ;

		if ( m_mouseX < -127 )
			m_mouseX = -127 ;
		if ( m_mouseY < -127 )
			m_mouseY = -127 ;
		if ( m_mouseX > 127 )
			m_mouseX = 127 ;
		if ( m_mouseY > 127 )
			m_mouseY = 127 ;

		return 0x30000 | (m_mouseY<<8) |  m_mouseX ;
		//return 0x30022 ;

	//return 0x32222 ;
}

void kbd_handle_keyup( unsigned int vcode, unsigned int vcode2 )
{
	win32keyboard_keyrelease( vcode, 0 ) ;
	key[vcode] = 0 ;
}
void kbd_handle_keydown( unsigned int vcode, unsigned int vcode2 )
{
	win32keyboard_keypress( vcode, 0 ) ;
	key[vcode] = 1 ;
}


void CXBoxSample::handleScreenKeyboard( )
{
	DWORD color ;
	static DWORD movetime = 0 ;

	XBInput_GetInput();
	if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
	{
		m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;

		while ( g_Gamepads[0].hDevice && g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_B] )
			XBInput_GetInput();

		m_bKeyboardMode = 0 ;

		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
		}
		if ( m_currKeyboardKey & KEYCAPS )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x30],KEYBOARD_VKMAP[0x30] ) ;
		}
		if ( m_currKeyboardKey & KEYLSHIFT )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x40],KEYBOARD_VKMAP[0x40] ) ;
		}
		if ( m_currKeyboardKey & KEYRSHIFT )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x4D],KEYBOARD_VKMAP[0x4D] ) ;
		}
		if ( m_currKeyboardKey & KEYLCTRL )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x50],KEYBOARD_VKMAP[0x50] ) ;
		}
		if ( m_currKeyboardKey & KEYRCTRL )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x5A],KEYBOARD_VKMAP[0x5A] ) ;
		}
		if ( m_currKeyboardKey & KEYLALT )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x53],KEYBOARD_VKMAP[0x53] ) ;
		}
		if ( m_currKeyboardKey & KEYRALT )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[0x58],KEYBOARD_VKMAP[0x58] ) ;
		}

		m_currKeyboardKey &= 0x000000FF ;

		return ;
	}

	if(g_Gamepads[0].hDevice && g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_A])
	{
		if ( (m_currKeyboardKey&0xFF) == 13 )
		{
			int currAlpha = (m_pnlKeyboard.m_colDiffuse >> 24 )&0xFF ;

			currAlpha += 1 ;

			if ( currAlpha > 0xFF )
				currAlpha = 0xFF ;

			m_pnlKeyboard.SetAlpha( currAlpha ) ;
		}

		if ( (m_currKeyboardKey&0xFF) == 14 )
		{
			int currAlpha = (m_pnlKeyboard.m_colDiffuse >> 24 )&0xFF ;

			currAlpha -= 1 ;

			if ( currAlpha < 0  )
				currAlpha = 0 ;

			m_pnlKeyboard.SetAlpha( currAlpha ) ;
		}

		if ( m_currKeyboardKey & KEYPRESSING )
		{
		}
		else
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
			
			switch( m_currKeyboardKey&0xFF )
			{
				case 0x30 : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYCAPS ) )
						{
							m_currKeyboardKey |= KEYCAPS ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYCAPS ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x40 :
				case 0x41 : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYLSHIFT ) )
						{
							m_currKeyboardKey |= KEYLSHIFT ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYLSHIFT ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x4C :
				case 0x4D : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYRSHIFT ) )
						{
							m_currKeyboardKey |= KEYRSHIFT ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYRSHIFT ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x50 :
				case 0x51 : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYLCTRL ) )
						{
							m_currKeyboardKey |= KEYLCTRL ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYLCTRL ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x5A :
				case 0x5B : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYRCTRL ) )
						{
							m_currKeyboardKey |= KEYRCTRL ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYRCTRL ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x52 :
				case 0x53 : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYLALT ) )
						{
							m_currKeyboardKey |= KEYLALT ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYLALT ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				case 0x58 :
				case 0x59 : 
				{
					if ( g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A] )
					{
						if ( ! ( m_currKeyboardKey & KEYRALT ) )
						{
							m_currKeyboardKey |= KEYRALT ; 
							kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
						else
						{
							m_currKeyboardKey &= ~KEYRALT ; 
							kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
						}
					}
					break ;
				}
				default : 
				{
					m_currKeyboardKey |= KEYPRESSING ; 
					m_currKeyboardKey |= (( m_currKeyboardKey&0xFF)<<8) ;
					kbd_handle_keydown( KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey)&0xFF] ) ;
					break ;
				}
			}
		}
	}
	else
	{
		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
			m_currKeyboardKey &= ~KEYPRESSING ;
			m_currKeyboardKey &= 0xFFFF00FF ;
		}
	}

	if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_WHITE])
	{
		m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
		if ( ! ( m_currKeyboardKey & KEYLSHIFT ) )
		{
			m_currKeyboardKey |= KEYLSHIFT ; 
			kbd_handle_keydown( KEYBOARD_VKMAP[0x40],KEYBOARD_VKMAP[0x40] ) ;
		}
		else
		{
			m_currKeyboardKey &= ~KEYLSHIFT ; 
			kbd_handle_keyup( KEYBOARD_VKMAP[0x40],KEYBOARD_VKMAP[0x40] ) ;
		}
	}
	else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_Y])
	{
		m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
		if ( ! ( m_currKeyboardKey & KEYLCTRL ) )
		{
			m_currKeyboardKey |= KEYLCTRL ; 
			kbd_handle_keydown( KEYBOARD_VKMAP[0x50],KEYBOARD_VKMAP[0x50] ) ;
		}
		else
		{
			m_currKeyboardKey &= ~KEYLCTRL ; 
			kbd_handle_keyup( KEYBOARD_VKMAP[0x50],KEYBOARD_VKMAP[0x50] ) ;
		}
	}
	else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_BLACK])
	{
		m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
		if ( ! ( m_currKeyboardKey & KEYLALT ) )
		{
			m_currKeyboardKey |= KEYLALT ; 
			kbd_handle_keydown( KEYBOARD_VKMAP[0x52],KEYBOARD_VKMAP[0x52] ) ;
		}
		else
		{
			m_currKeyboardKey &= ~KEYLALT ; 
			kbd_handle_keyup( KEYBOARD_VKMAP[0x52],KEYBOARD_VKMAP[0x52] ) ;
		}
	}
	else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_START )
	{
		m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
		kbd_handle_keydown( KEYBOARD_VKMAP[0x3C],KEYBOARD_VKMAP[0x3C] ) ;
		kbd_handle_keyup( KEYBOARD_VKMAP[0x3C],KEYBOARD_VKMAP[0x3C] ) ;
	}
	else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_BACK )
	{
		m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
		kbd_handle_keydown( KEYBOARD_VKMAP[0x1F],KEYBOARD_VKMAP[0x1F] ) ;
		kbd_handle_keyup( KEYBOARD_VKMAP[0x1F],KEYBOARD_VKMAP[0x1F] ) ;
	}

	if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_RIGHT )
	{
		m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;

		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
			m_currKeyboardKey &= ~KEYPRESSING ;
			m_currKeyboardKey &= 0xFFFF00FF ;
		}

		if ( ( m_currKeyboardKey%16 ) == 15 )
			m_currKeyboardKey -= 15 ;
		else
			m_currKeyboardKey++ ;

	}
	else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_LEFT )
	{
		m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
			m_currKeyboardKey &= ~KEYPRESSING ;
			m_currKeyboardKey &= 0xFFFF00FF ;
		}
		if ( ( m_currKeyboardKey%16 ) == 0 )
			m_currKeyboardKey += 15 ;
		else
			m_currKeyboardKey-- ;

	}
	else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_UP )
	{
		m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
			m_currKeyboardKey &= ~KEYPRESSING ;
			m_currKeyboardKey &= 0xFFFF00FF ;
		}
		if ( (m_currKeyboardKey&0xFF) < 16 )
			m_currKeyboardKey += (5*16) ;
		else
			m_currKeyboardKey -= 16 ;

	}
	else if ( g_Gamepads[0].hDevice && g_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_DOWN )
	{
		m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;
		if ( m_currKeyboardKey & KEYPRESSING )
		{
			kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
			m_currKeyboardKey &= ~KEYPRESSING ;
			m_currKeyboardKey &= 0xFFFF00FF ;
		}
		if ( (m_currKeyboardKey&0xFF) > (5*16)-1 )
			m_currKeyboardKey -= 5*16 ;
		else
			m_currKeyboardKey += 16 ;

	}

	if ( g_Gamepads[0].hDevice && ( g_Gamepads[0].sThumbLX > 9800 )  )
	{
		if ( movetime == 0 )
		{
			movetime = GetTickCount() ;
		}
		else
		{
			if ( GetTickCount() > movetime+(1000.0f/( (float)(g_Gamepads[0].sThumbLX)/ 2000.0f  )) )
			{
				movetime = 0 ;
				m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;

				if ( m_currKeyboardKey & KEYPRESSING )
				{
					kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
					m_currKeyboardKey &= ~KEYPRESSING ;
					m_currKeyboardKey &= 0xFFFF00FF ;
				}

				if ( ( m_currKeyboardKey%16 ) == 15 )
					m_currKeyboardKey -= 15 ;
				else
					m_currKeyboardKey++ ;
			}
		}
	}
	if ( g_Gamepads[0].hDevice && ( g_Gamepads[0].sThumbLX < -9800 )  )
	{
		if ( movetime == 0 )
		{
			movetime = GetTickCount() ;
		}
		else
		{
			if ( GetTickCount() > movetime+(1000.0f/( (float)(abs(g_Gamepads[0].sThumbLX))/ 2000.0f  )) )
			{
				movetime = 0 ;
				m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;

				if ( m_currKeyboardKey & KEYPRESSING )
				{
					kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
					m_currKeyboardKey &= ~KEYPRESSING ;
					m_currKeyboardKey &= 0xFFFF00FF ;
				}
				if ( ( m_currKeyboardKey%16 ) == 0 )
					m_currKeyboardKey += 15 ;
				else
					m_currKeyboardKey-- ;
			}
		}
	}
	if ( g_Gamepads[0].hDevice && ( g_Gamepads[0].sThumbLY > 9800 )  )
	{
		if ( movetime == 0 )
		{
			movetime = GetTickCount() ;
		}
		else
		{
			if ( GetTickCount() > movetime+(1000.0f/( (float)(g_Gamepads[0].sThumbLY)/ 2000.0f  )) )
			{
				movetime = 0 ;
				m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;

				if ( m_currKeyboardKey & KEYPRESSING )
				{
					kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
					m_currKeyboardKey &= ~KEYPRESSING ;
					m_currKeyboardKey &= 0xFFFF00FF ;
				}
				if ( (m_currKeyboardKey&0xFF) < 16 )
					m_currKeyboardKey += (5*16) ;
				else
					m_currKeyboardKey -= 16 ;
			}
		}
	}
	if ( g_Gamepads[0].hDevice && ( g_Gamepads[0].sThumbLY < -9800 )  )
	{
		if ( movetime == 0 )
		{
			movetime = GetTickCount() ;
		}
		else
		{
			if ( GetTickCount() > movetime+(1000.0f/( (float)(abs(g_Gamepads[0].sThumbLY))/ 2000.0f  )) )
			{
				movetime = 0 ;
				m_sfxMenuMove.Play( DSBPLAY_FROMSTART ) ;

				if ( m_currKeyboardKey & KEYPRESSING )
				{
					kbd_handle_keyup( KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF],KEYBOARD_VKMAP[(m_currKeyboardKey>>8)&0xFF] ) ;
					m_currKeyboardKey &= ~KEYPRESSING ;
					m_currKeyboardKey &= 0xFFFF00FF ;
				}
				if ( (m_currKeyboardKey&0xFF) > (5*16)-1 )
					m_currKeyboardKey -= 5*16 ;
				else
					m_currKeyboardKey += 16 ;
			}
		}
	}
}


int CXBoxSample::handleEvents(  )
{

    INT32 resistance ;
	float newRes ;
	DWORD vcode ;
	int lmousedown, rmousedown, mmousedown ;
	int lmousedown2, rmousedown2, mmousedown2 ;
	//XINPUT_DEBUG_KEYSTROKE   keystroke ;
	char stkey ;
	int foundfirstUSB ;
	char nummice = 0 ;
	byte held_keys[256] ;
	byte oldkeystate[256] ;
	static int doRotate[4] = {0,0,0,0} ;
	int firstdrive, lastdrive ;
	unsigned char didup, diddown, didleft, didright, didfire ;
	unsigned char didup2, diddown2, didleft2, didright2, didfire2 ;

	//xbox_print_memory() ;

	memcpy( oldkeystate, keyboard_keystate, 256 ) ;

	updateCheats2() ;

	memset( held_keys, 0, 256 ) ;

	if( m_bKeyboardMode )
	{
		handleScreenKeyboard() ;
		return 0 ;
	}

	if ( g_app->pollXBoxControllers() )
	{
		m_state = MAIN_MENU ;
		throttling = 1 ;
		return 1;
	}
	
	g_app->checkGeneralEvents() ;	

#ifndef NO_NETWORK
	if ( g_app->m_bNetplay )
	{
		if ( m_netplayCurr == m_netplaySkip ) //we have read some network data
		{
			if ( g_app->m_bNetplay == 2 )  //server
			{
				g_app->m_emuControllers[1] = g_app->m_networkEmuControllers[0] ;
			}
			else //client
			{
				g_app->m_emuControllers[1] = g_app->m_emuControllers[0] ;
				g_app->m_emuControllers[0] = g_app->m_networkEmuControllers[0] ;
			}
		}
		else //we did not poll network - use last values
		{
			if ( g_app->m_bNetplay == 2 )  //server
			{
				g_app->m_emuControllers[0] = g_app->m_prevEmuControllers[0] ;
				g_app->m_emuControllers[1] = g_app->m_networkEmuControllers[0] ;
			}
			else //client
			{
				g_app->m_emuControllers[1] = g_app->m_prevEmuControllers[0] ;
				g_app->m_emuControllers[0] = g_app->m_networkEmuControllers[0] ;
			}
		}
	}
#endif


	didup = diddown = didleft = didright = didfire = didup2 = diddown2 = didleft2 = didright2 = didfire2 = 0 ;

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

		for ( int j = 0 ; j < 32 ; j++ )
		{
			if ( g_keystroke_queue[i][j] )
			{
				vcode = g_keystroke_queue[i][j] & ~0x80000000 ;
				held_keys[vcode] = 1 ;
				if ( keyboard_keystate[vcode]==0 )
				{
					win32keyboard_keypress( vcode, 0 ) ;
					key[vcode] = 1 ;
					keyboard_keystate[vcode] = 1 ;
				}
			}
			else
			{
				break ;
			}
		}

		if ( m_emuControllers[i] & SPECRESET )
		{
			machine_reset() ;
		}

		if ( m_emuControllers[i] & JOY_UP )
		{
			joystick_press( 2, (joystick_button)2, 1 ) ;
			didup = 1 ;
		}

		if ( m_emuControllers[i] & JOY_DOWN )
		{
			joystick_press( 2, (joystick_button)3, 1 ) ;
			diddown = 1 ;
		}

		if ( m_emuControllers[i] & JOY_LEFT )
		{
			joystick_press( 2, (joystick_button)0, 1 ) ;
			didleft = 1 ;
		}
		
		if ( m_emuControllers[i] & JOY_RIGHT )
		{
			joystick_press( 2, (joystick_button)1, 1 ) ;
			didright = 1 ;
		}

		if ( m_emuControllers[i] & JOY_1 )
		{
			joystick_press( 2, (joystick_button)4, 1 ) ;
			didfire = 1 ;
		}

		/*
		if ( m_emuControllers[i] & JOY2_UP )
			joystick_press( 1, (joystick_button)2, 1 ) ;
		else 
			joystick_press( 1, (joystick_button)2, 0 ) ;

		if ( m_emuControllers[i] & JOY2_DOWN )
			joystick_press( 1, (joystick_button)3, 1 ) ;
		else 
			joystick_press( 1, (joystick_button)3, 0 ) ;

		if ( m_emuControllers[i] & JOY2_LEFT )
			joystick_press( 1, (joystick_button)0, 1 ) ;
		else 
			joystick_press( 1, (joystick_button)0, 0 ) ;
		
		if ( m_emuControllers[i] & JOY2_RIGHT )
			joystick_press( 1, (joystick_button)1, 1 ) ;
		else 
			joystick_press( 1, (joystick_button)1, 0 ) ;

		if ( m_emuControllers[i] & JOY2_1 )
			joystick_press( 1, (joystick_button)4, 1 ) ;
		else 
			joystick_press( 1, (joystick_button)4, 0 ) ;
*/

	}

	if ( didup == 0 )
		joystick_press( 2, (joystick_button)2, 0 ) ;
	if ( diddown == 0 )
		joystick_press( 2, (joystick_button)3, 0 ) ;
	if ( didleft == 0 )
		joystick_press( 2, (joystick_button)0, 0 ) ;
	if ( didright == 0 )
		joystick_press( 2, (joystick_button)1, 0 ) ;
	if ( didfire == 0 )
		joystick_press( 2, (joystick_button)4, 0 ) ;
	


	while ( Keyboard_GetVKInput() )
	{
		if ( g_keyboardStroke.Flags & XINPUT_DEBUG_KEYSTROKE_FLAG_KEYUP )
		{
			win32keyboard_keyrelease( g_keyboardStroke.VirtualKey, 0 ) ;
			keyboard_keystate[g_keyboardStroke.VirtualKey] = 0 ;
			key[g_keyboardStroke.VirtualKey] = 0 ;
			held_keys[g_keyboardStroke.VirtualKey] = 0 ;

		}
		else
		{
			if ( g_keyboardStroke.Flags & XINPUT_DEBUG_KEYSTROKE_FLAG_REPEAT )
			{
				/*
				if ( keyboard_keystate[g_keyboardStroke.VirtualKey] == 2 )
				{
					if ( vkey_to_amiga[g_keyboardStroke.VirtualKey] )
						handle_input_event( vkey_to_amiga[g_keyboardStroke.VirtualKey], 1, 1, 0 ) ;
					keyboard_keystate[g_keyboardStroke.VirtualKey] = 2 ;
					held_keys[g_keyboardStroke.VirtualKey] = 1 ;
				}*/
			}
			else
			{
				win32keyboard_keypress( g_keyboardStroke.VirtualKey, 0 ) ;
				key[g_keyboardStroke.VirtualKey] = 1 ;
				keyboard_keystate[g_keyboardStroke.VirtualKey] = 2 ;
				held_keys[g_keyboardStroke.VirtualKey] = 1 ;
			}
		}
	}

	for ( int j = 0 ; j < 256 ; j++ )
	{
		if ( ( keyboard_keystate[j] == 1 ) && ( held_keys[j] == 0 ) )
		{
			win32keyboard_keyrelease( j, 0 ) ;
			key[j] = 0 ;
			keyboard_keystate[j] = 0 ;
		}

	}


//	m_joypad = ( g_app->m_emuControllers[0] & 0xFF ) | ( ( g_app->m_emuControllers[1] & 0xFF ) << 8 )  | 
				//( ( g_app->m_emuControllers[2] & 0xFF ) << 16 ) | ( ( g_app->m_emuControllers[3] & 0xFF ) << 24 ) ;


#ifdef LIGHTGUN
	if ( m_zapperNum )
	{
		doZapper() ;
	}
#endif


	return 0 ;
}



void CXBoxSample::xboxSaveState() 
{
	FILE *sfile ;

	if ( m_bStateMenu )
	{
		int statenum ;
		g_app->m_state = IN_GAME_PAUSED ;
		g_app->m_sound.pause( TRUE ) ;

		#ifdef NEED_CDDA
		//g_app->m_cdda.pause(TRUE) ;
		//g_app->m_mp3player_cdda.pause(TRUE) ;
		#endif

		statenum = selectState() ;

		freeTextures() ;
		m_sound.pause( FALSE ) ;

		#ifdef NEED_CDDA
		//m_cdda.pause(FALSE) ;
		//m_mp3player_cdda.pause(FALSE) ;
		#endif

		m_state = IN_GAME ;

		if ( statenum >= 0 )
		{
			m_stateNumber = statenum ;
		}
		else
		{
			return ;
		}
	}

	if ( g_statefile && strlen( g_statefile ) )
	{
		g_statefile[ strlen(g_statefile)-1 ] = '0' + m_stateNumber ;

		xboxScreenshot() ;

		g_statefile[ strlen(g_statefile)-2 ] = 'p' ;

		MoveFileEx( g_szLastScreenshot, g_statefile, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING ) ;

		g_statefile[ strlen(g_statefile)-2 ] = 't' ;

		//fuse_emulation_pause();
		snapshot_write( g_statefile ) ;
		//fuse_emulation_unpause();
		//save_state( g_statefile, "description" ) ;


		sprintf( global_error_message, "State %u Saved", m_stateNumber+1 ) ;
		m_msgDelay = 120 ;
	}
}

void CXBoxSample::xboxLoadState() 
{
		
	char				localfile[512] ;
	char				zipfile[512] ;
	char *usefile ;
	char szholder[500] ;
	FILE *sfile ;

	if ( m_bStateMenu )
	{
		int statenum ;
		g_app->m_state = IN_GAME_PAUSED ;
		g_app->m_sound.pause( TRUE ) ;

		#ifdef NEED_CDDA
		//g_app->m_cdda.pause(TRUE) ;
		//g_app->m_mp3player_cdda.pause(TRUE) ;
		#endif

		statenum = selectState() ;

		freeTextures() ;
		m_sound.pause( FALSE ) ;

		#ifdef NEED_CDDA
		//m_cdda.pause(FALSE) ;
		//m_mp3player_cdda.pause(FALSE) ;
		#endif

		m_state = IN_GAME ;

		if ( statenum >= 0 )
		{
			m_stateNumber = statenum ;
		}
		else
		{
			return ;
		}
	}

	if ( g_statefile && strlen( g_statefile ) )
	{
		if ( m_stateNumber == 0 )
		{
			g_statefile[ strlen(g_statefile)-1 ] = 'A' ;
			strcpy( szholder, g_statefile ) ;
			g_statefile[ strlen(g_statefile)-1 ] = '0' ;
			MoveFileEx( szholder, g_statefile, MOVEFILE_REPLACE_EXISTING ) ;
		}

		g_statefile[ strlen(g_statefile)-1 ] = '0' + m_stateNumber ;

		sfile = fopen( g_statefile, "rb" ) ;

		if ( sfile )
		{
			fclose(sfile) ;

			g_statefile[ strlen(g_statefile)-2 ] = 't' ;

			//fuse_emulation_pause();
			snapshot_read( g_statefile ) ;
			//fuse_emulation_unpause();

			sprintf( global_error_message, "State %u Loaded", m_stateNumber+1 ) ;
			m_msgDelay = 120 ;
		}
	

	}
	
}

void CXBoxSample::xboxChangeFilter() 
{
#ifdef NO_FILTERS
	m_xboxHFilter = (m_xboxHFilter+1)%4 ;

	applyHardwareFilter() ;

	sprintf( global_error_message, "%s Filtering", XBOX_FILTERS[m_xboxHFilter] ) ;
	m_msgDelay = 120 ;
#else
	
	g_app->m_xboxSFilter = (g_app->m_xboxSFilter+1)%NUM_SOFTWARE_FILTERS ;

	memset( g_pDeltaBuff, 0xFF, 1280*980*2 ) ;
	//memset( g_pBlitBuff, 0x00, 1280*500*2 ) ;

	display_refresh_all() ;

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

	//changegfxfilter() ;
#endif
}

void CXBoxSample::xboxScreenshot() 
{
	mainprog_info wpng_info;
	char scr_filename[MAX_PATH] ;
	char scr_prefix[MAX_PATH] ;
	char dir[MAX_PATH] ;
	int maxnum = 0 ;
	HANDLE hFind;	
	WIN32_FIND_DATAA oFindData;

	g_szLastScreenshot[0] = 0 ;

	CreateDirectory( m_screenshotDir, NULL ) ;

	sprintf( scr_prefix, "%s\\%s", m_screenshotDir, PLATFORM_NAME ) ; 

	CreateDirectory( scr_prefix, NULL ) ;

	sprintf( scr_prefix, "%s\\%s\\%s", m_screenshotDir, PLATFORM_NAME, strrchr(g_saveprefix, '\\')+1 ) ;

	CreateDirectory( scr_prefix, NULL ) ;

	sprintf( dir, "%s\\*.png", scr_prefix ) ;

	hFind = FindFirstFile( dir, &oFindData);

	if ( hFind != INVALID_HANDLE_VALUE) 
	{
		do
		{
			strcpy( scr_filename, oFindData.cFileName ) ;

			if ( strchr( scr_filename, '.' ) == NULL )
				continue ;

			*(strchr( scr_filename, '.' )) = 0 ;

			//sprintfx( "%s %u %s\r\n", scr_filename, strlen(scr_prefix), scr_filename + strlen(scr_prefix) ) ;

			if ( atoi( scr_filename ) > maxnum )
			{
				maxnum = atoi( scr_filename ) ;
			}
			
		} while (FindNextFile(hFind, &oFindData) ) ;
		FindClose( hFind );
	}

	maxnum++ ;

	if ( maxnum > 9999 )
		return ;

	sprintf( scr_filename, "%s\\%04.4u.png", scr_prefix, maxnum ) ;


	memset( &wpng_info, 0, sizeof( wpng_info ) ) ;

	wpng_info.width = ((float)m_nScreenMaxX/m_gameVecScale.x);
	wpng_info.height = ((float)m_nScreenMaxY/m_gameVecScale.y) ;

	wpng_info.sample_depth = 8;

	wpng_info.bpp = 24 ;

	wpng_info.outfile = NULL;
	wpng_info.image_data = NULL;
	wpng_info.row_pointers = NULL;
	wpng_info.interlaced = false;
	wpng_info.have_bg = false;
	wpng_info.have_time = false;
	wpng_info.have_text = 0;
	wpng_info.gamma = 1.0;

    /* open the output file, or register an error and abort */
	if ((wpng_info.outfile = fopen( scr_filename, "wb") ) == NULL)
	{
		return ;
    }
	
	// allocate libpng stuff, initialize transformations, write pre-IDAT data
	

	int rc ;
	if ((rc=writepng_init(&wpng_info)) != 0)
	{
		fclose( wpng_info.outfile )  ;
		return ; 
		/*
		switch (rc)
		{
			case 2:
				fprintf(stderr, "WritePNG: libpng initialization problem (longjmp)\n");
			break;
			case 4:
				fprintf(stderr, "WritePNG: insufficient memory\n");
				break;
			case 11:
				fprintf(stderr, "WritePNG: internal logic error (unexpected PNM type)\n");
				break;
			default:
				fprintf(stderr, "WritePNG: unknown writepng_init() error\n");
				break;
        }
        exit(rc); */
    }
	
	long j;
	
	wpng_info.image_data = (unsigned char *)malloc( (wpng_info.bpp/8) * wpng_info.width);
		
	if (wpng_info.image_data == NULL)
	{
		writepng_cleanup(&wpng_info);
		fclose( wpng_info.outfile )  ;
		return ; 
		/*
		fprintf(stderr, "WritePNG:  insufficient memory for row data\n");
		writepng_cleanup(&wpng_info);
		cleanup();
		exit(5);
		*/
	}
		
	unsigned char *data ;

	
	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);


	data = (unsigned char*)d3dlr.pBits;
	//data += (screen_x*2) ;
	//data += (screen_y*d3dlr.Pitch) ;

	WORD pixel ;
		
	for (j = wpng_info.height;  j > 0L;  --j)
	{
		unsigned char* img_data = wpng_info.image_data;
		WORD *wdata = (WORD*)data;

		int i=0;

		for ( i = 0 ; i < wpng_info.width ; i++ )
		{
			pixel = wdata[i] ;
			img_data[2] = (pixel<<3) & 0xFF ;
			img_data[1] = ((pixel>>5)<<2) & 0xFF ;
			img_data[0] = ((pixel>>11)<<3) & 0xFF ;
			img_data += 3 ;
		}

		data += d3dlr.Pitch;
			
	
			
		if( writepng_encode_row(&wpng_info) != 0)
		{
			writepng_cleanup(&wpng_info);
			free(wpng_info.image_data) ;
			fclose( wpng_info.outfile )  ;
			Texture->UnlockRect(0) ;
			return ; 

/*			fprintf(stderr, "WritePNG:  libpng problem (longjmp) while writing row %ld\n",
			wpng_info.height-j);
			++error;
			break;*/
		}
	}
	Texture->UnlockRect(0) ;
		
		/*
	if (error)
	{
		writepng_cleanup(&wpng_info);
		cleanup();
		exit(2);
	}
	*/
	if (writepng_encode_finish(&wpng_info) != 0)
	{
		//fprintf(stderr, "WritePNG:  error on final libpng call\n");
		writepng_cleanup(&wpng_info);
		free(wpng_info.image_data) ;
		fclose( wpng_info.outfile )  ;
		return ;
	}
	
	/* OK, we're done (successfully):  clean up all resources and quit */

	writepng_cleanup(&wpng_info);
	free(wpng_info.image_data) ;
	fclose( wpng_info.outfile )  ;

	strcpy( g_szLastScreenshot, scr_filename ) ;

	sprintf( global_error_message, "%s", scr_filename) ;
	m_msgDelay = 120 ;
}

#define CLOCK_MHZ 3000000
#define DEFAULT_CPF (CLOCK_MHZ/60)

void CXBoxSample::xboxThrottle( int xthrottle ) 
{
	throttling = xthrottle ;

	if ( xthrottle ) 
	{
		//change_framerate( m_throttleSpeed ) ;
		if ( m_throttle <= 0 )
			m_throttle = m_throttleSpeed ;
		//CPUThrottle = 0 ;
		//max_cpf = DEFAULT_CPF*3 ;
	}
	else
	{
		m_throttle = 0 ;
		//CPUThrottle = 1 ;
		//max_cpf = DEFAULT_CPF ;
	}
	//m_throttle = throttle ;
	//SpeedThrottle() ;
}

void CXBoxSample::xboxChangeState() 
{
	m_stateNumber = (m_stateNumber+1)%10 ;

	sprintf( global_error_message, "Switched to State Slot %u", m_stateNumber+1 ) ;
	m_msgDelay = 120 ;
}

void CXBoxSample::xboxOptionsMenu( )
{
	g_app->m_state = IN_GAME_PAUSED ;
	g_app->m_sound.pause( TRUE ) ;
	//g_app->m_cdda.pause(TRUE) ;
	//g_app->m_mp3player_cdda.pause(TRUE) ;
	g_app->m_mp3player.pause( TRUE ) ;
	g_app->m_dwStartPause = GetTickCount();

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

	Sleep( 100 ) ;
	g_app->doCheatMenu() ;

	freeTextures() ;

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

	applyHardwareFilter() ;

	//m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	//m_pd3dDevice->Reset( &m_d3dpp ) ;
	g_app->m_sound.pause( FALSE ) ;
	//g_app->m_cdda.pause(FALSE) ;
	//g_app->m_mp3player_cdda.pause(FALSE) ;
	m_startTime = GetTickCount() ;
	m_numFrames = 0 ;

}

void CXBoxSample::xboxStartRecording( )
{
	if ( m_emuRecording || m_emuPlaying )
		return ;


	m_sound.pause(TRUE ) ;
	//m_cdda.pause(TRUE) ;
	//m_mp3player_cdda.pause(TRUE) ;
	FILE *checkfile ;

	while ( 1 )
	{
		pmenuParams = &(m_skin.popupMenu) ;

		//m_mp3player.process() ;
		//m_plaything.Render( 0,0,0 ) ;



		swprintf( m_menuText[0], L"Confirm Start Recording" ) ;
		swprintf( m_menuText[1], L"" ) ;
		swprintf( m_menuText[2], L"WARNING" ) ;
		swprintf( m_menuText[3], L"This function is going to load the currently" ) ;
		swprintf( m_menuText[4], L"selected save state and start recording."   ) ;
		swprintf( m_menuText[5], L"" ) ;
		swprintf( m_menuText[6], L"Press B if you want to cancel this action." ) ;
		swprintf( m_menuText[7], L"Press Y to load the state and start recording.") ;

		renderPopupBkg( 8 ) ;
		renderMenuText( 0, 0, m_menuText, 8, 0 ) ;
		
		
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );


        XBInput_GetInput();

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			//m_cdda.pause(FALSE) ;
			//m_mp3player_cdda.pause(FALSE) ;
			m_sound.pause(FALSE) ;
			return ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_Y])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
			break ;
		}
	}

	xboxLoadState() ;

	checkfile = fopen( g_statefile, "rb" ) ;

	if ( checkfile == NULL )
	{
		xboxSaveState() ;
	}
	else
	{
		fclose( checkfile ) ;
	}

	m_emuRecordSlot = m_stateNumber ;
	m_emuRecordPosition = 0 ;
	m_emuRecording = 1 ;

	m_sound.pause(FALSE) ;
	//m_cdda.pause(FALSE) ;
	//m_mp3player_cdda.pause(FALSE) ;

	sprintf( global_error_message, "Started Recording at Slot %u", m_emuRecordSlot+1 ) ;
	m_msgDelay = 120 ;

}
void CXBoxSample::xboxStopRecording( )
{
	if ( ! m_emuRecording )
		return ;

	char recname[500] ;
	FILE *recfile ;

	sprintf( recname, "%s.sr0", g_saveprefix ) ;

	recname[ strlen(recname)-1 ] = '0' + m_emuRecordSlot  ;


	recfile = fopen( recname, "wb") ;

	if ( recfile == NULL )
	{
		sprintf( global_error_message, "Could not open %s for writing", recname ) ;
		m_msgDelay = 120 ;
		return ;
	}

	fwrite( m_szEmuRecorder, sizeof(char), m_emuRecordPosition, recfile  ) ;
	fclose( recfile ) ;

	m_emuRecording = 0 ;

	sprintf( global_error_message, "Stopped Recording at Slot %u", m_emuRecordSlot+1 ) ;
	m_msgDelay = 120 ;

}
void CXBoxSample::xboxStartPlaying( )
{
	if ( m_emuPlaying || m_emuRecording )
		return ;

	char recname[500] ;
	FILE *recfile ;
	unsigned int filesize ;

	m_sound.pause(TRUE) ;
	//m_cdda.pause(TRUE) ;
	//m_mp3player_cdda.pause(TRUE) ;
	while ( 1 )
	{
		pmenuParams = &(m_skin.popupMenu) ;

		//m_mp3player.process() ;
		//m_plaything.Render( 0,0,0 ) ;



		swprintf( m_menuText[0], L"Confirm Start Playing" ) ;
		swprintf( m_menuText[1], L"" ) ;
		swprintf( m_menuText[2], L"WARNING" ) ;
		swprintf( m_menuText[3], L"This function is going to load the currently" ) ;
		swprintf( m_menuText[4], L"selected save state and start playing the recording."   ) ;
		swprintf( m_menuText[5], L"" ) ;
		swprintf( m_menuText[6], L"Press B if you want to cancel this action." ) ;
		swprintf( m_menuText[7], L"Press Y to load the state and start playing.") ;

		renderPopupBkg( 8 ) ;
		renderMenuText( 0, 0, m_menuText, 8, 0 ) ;
		
		
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );


        XBInput_GetInput();

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			m_sound.pause(FALSE) ;
			//m_cdda.pause(FALSE) ;
			//m_mp3player_cdda.pause(FALSE) ;
			return ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_Y])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
			break ;
		}
	}

	m_emuRecordSlot = m_stateNumber ;

	sprintf( recname, "%s.sr0", g_saveprefix ) ;

	recname[ strlen(recname)-1 ] = '0' + m_emuRecordSlot  ;


	recfile = fopen( recname, "rb") ;

	if ( recfile == NULL )
	{
		sprintf( global_error_message, "Could not open %s for reading", recname ) ;
		m_msgDelay = 120 ;
		m_sound.pause(FALSE) ;
		//m_cdda.pause(FALSE) ;
		//m_mp3player_cdda.pause(FALSE) ;
		return ;
	}

	fseek( recfile, 0, SEEK_END ) ;
	m_emuPlaySize = ftell( recfile ) ;
	fseek( recfile, 0, SEEK_SET ) ;

	fread( m_szEmuRecorder, sizeof(char), m_emuPlaySize, recfile ) ;
	fclose( recfile ) ;

	m_emuPlayPosition = 0 ;

	m_emuPlaying = 1 ;

	xboxLoadState() ;

	m_sound.pause(FALSE) ;
	//m_cdda.pause(FALSE) ;
	//m_mp3player_cdda.pause(FALSE) ;
	sprintf( global_error_message, "Started Playing Slot %u", m_emuRecordSlot+1 ) ;
	m_msgDelay = 120 ;
}

void CXBoxSample::xboxStopPlaying( )
{
	if ( ! m_emuPlaying )
		return ;

	m_emuPlaying = 0 ;

	sprintf( global_error_message, "Stopped Playing Slot %u", m_emuRecordSlot+1 ) ;
	m_msgDelay = 120 ;
}


int CXBoxSample::handleExtension( char *ext, char *newfilename, char *zipfilename, int *zipnumber )  
{
#if 0
	if ( ( ( strlen(ext) == 3 ) && ( toupper(ext[0]) == 'Z' ) && ( toupper(ext[1]) == 'I' ) && ( toupper(ext[2]) == 'P' ) ) ||
		    ( ( strlen(ext) == 3 ) && ( toupper(ext[0]) == 'A' ) && ( toupper(ext[1]) == 'D' ) && ( toupper(ext[2]) == 'Z' ) ) )
	{
		unzipMSX( newfilename, zipfilename, zipnumber ) ;
		return 1;
	}
#endif
	return 0 ;
}

/*
void CXBoxSample::createLocal( char *filename, char *newfilename, char* zipfilename, int *zipnumber )
{
	int usingSamba = ( strncmp( filename, "SMB:", 4 ) == 0 ) || ( strncmp( filename, "smb:", 4 ) == 0 ) ;
	int usingRelax = ( strncmp( filename, "RLX:", 4 ) == 0 ) || ( strncmp( filename, "rlx:", 4 ) == 0 ) ;
	char *ext ;
	char shortpath[100] ;
	char *p ;


	if ( strlen( strrchr( filename, '\\' )+1 ) > 42 )
	{
		strncpy( shortpath, strrchr( filename, '\\' )+1, 42 ) ;
		shortpath[42] = 0 ;

		p = strrchr( filename, '.' ) ;

		if ( p )
		{
			strcpy( shortpath+( 41 - strlen(p) ), p ) ;
		}
	}
	else
	{
		strcpy( shortpath, strrchr( filename, '\\' )+1 ) ;
	}


	while( strchr( shortpath, ',' ) )
		*strchr( shortpath, ',' ) = '_' ;


	if ( usingSamba )
	{

		char smbfilename[1024] ;
		char *smbp ;
		int sambafile ;
		FILE *outfile ;


		sprintf( smbfilename, "%s%s", m_smbShare, filename+4 ) ;

		while ( smbp = strchr( smbfilename, '\\' ) )
			*smbp = '/' ;


		sambafile = m_smb.open( smbfilename,O_RDONLY|O_BINARY);

		sprintfx( "%s\r\n", smbfilename ) ;



		if ( sambafile <= 0 )
		{
			*zipnumber = 0 ;
			return ;
		}

		sprintf( smbfilename, "Z:\\%s", shortpath ) ;

		outfile = fopen(smbfilename, "wb") ;

		if ( outfile == NULL )
		{
			m_smb.close( sambafile ) ;
			*zipnumber = 0 ;
			return ;
		}

		int filesize = m_smb.lseek(sambafile,0,SEEK_END);
		m_smb.lseek(sambafile,0,SEEK_SET);

		char *fbuf = (char*) malloc( 64*1024 ) ;

		for ( int i = 0 ; i < filesize / (64*1024) ; i++ )
		{
			m_smb.read(sambafile,fbuf, 64*1024) ;
			fwrite( fbuf, sizeof(char), 64*1024, outfile ) ;
		}

		if ( filesize % (64*1024) )
		{
			m_smb.read(sambafile,fbuf, filesize % (64*1024)) ;
			fwrite( fbuf, sizeof(char), filesize % (64*1024), outfile ) ;
		}

		fclose(outfile) ;
		m_smb.close( sambafile ) ;

		free(fbuf) ;

		strcpy( newfilename, smbfilename ) ;
	}
	else if ( usingRelax )
	{
		char rlxfilename[1024] ;
		FILE *outfile ;
		int filesize ;
		char *fbuf ;

		if ( m_relax.Open( filename ) )
		{
			sprintfx( "opened rlx %s\r\n", filename ) ;
			filesize = m_relax.GetLength() ;


			sprintf( rlxfilename, "Z:\\%s", shortpath ) ;

			outfile = fopen(rlxfilename, "wb") ;

			if ( outfile == NULL )
			{
				m_relax.Close( ) ;
				*zipnumber = 0 ;
				return ;
			}


			fbuf = (char*) malloc( 64*1024 ) ;

			if ( !fbuf )
			{
				m_relax.Close() ;
				*zipnumber = 0 ;
				return ;
			}
			for ( int i = 0 ; i < filesize / (64*1024) ; i++ )
			{
				if ( ! m_relax.ReadAll( fbuf, 64*1024 ) )
				{
					free(fbuf) ;
					m_relax.Close() ;
					*zipnumber = 0 ;
					return ;
				}
				fwrite( fbuf, 1, 64*1024, outfile ) ;
			}

			if ( filesize % (64*1024)  )
			{
				if ( ! m_relax.ReadAll( fbuf, filesize % (64*1024) ) )
				{
					free(fbuf) ;
					m_relax.Close() ;
					*zipnumber = 0 ;
					return ;
				}
				fwrite( fbuf, 1, filesize % (64*1024), outfile ) ;
			}

			m_relax.Close() ;

			fclose( outfile ) ;
			free(fbuf) ;

			strcpy( newfilename, rlxfilename ) ;
		}
		else
		{
			*zipnumber = 0 ;
			return ;
		}
	}
	else if ( ( strncmp( filename, "S:", 2 ) == 0 ) || ( strncmp( filename, "s:", 2 ) == 0 ) )
	{
		char isofilename[1024] ;
		FILE *outfile ;
		int filesize ;
		char *fbuf ;


		if ( m_iso9660.OpenFile( filename+2 ) > 0 )
		{
			sprintfx( "opened iso %s\r\n", filename ) ;
			filesize = m_iso9660.GetFileSize() ;


			sprintf( isofilename, "Z:\\%s", shortpath ) ;

			outfile = fopen(isofilename, "wb") ;

			if ( outfile == NULL )
			{
				m_iso9660.CloseFile(1) ;
				*zipnumber = 0 ;
				return ;
			}


			fbuf = (char*) malloc( 64*1024 ) ;

			if ( !fbuf )
			{
				m_iso9660.CloseFile(1) ;
				fclose( outfile ) ;
				*zipnumber = 0 ;
				return ;
			}

			for ( int i = 0 ; i < filesize / (64*1024) ; i++ )
			{
				if ( ! m_iso9660.ReadFile( 1, (byte*)fbuf, 64*1024) )
				{
					free(fbuf) ;
					fclose( outfile ) ;
					m_iso9660.CloseFile(1) ;
					*zipnumber = 0 ;
					return ;
				}
				fwrite( fbuf, 1, 64*1024, outfile ) ;
			}

			if ( filesize % (64*1024 ) )
			{
				if ( ! m_iso9660.ReadFile( 1, (byte*)fbuf, filesize % (64*1024 )) )
				{
					free(fbuf) ;
					fclose( outfile ) ;
					m_iso9660.CloseFile(1) ;
					*zipnumber = 0 ;
					return ;
				}
				fwrite( fbuf, 1, filesize % (64*1024 ), outfile ) ;
			}


			m_iso9660.CloseFile(1) ;

			fclose( outfile ) ;
			free(fbuf) ;

			strcpy( newfilename, isofilename ) ;
		}
		else
		{
			*zipnumber = 0 ;
			return ;
		}
	}
	else
	{
		strcpy( newfilename, filename ) ;
	}


	ext = strrchr( newfilename, '.' ) ;

	if ( ext )
	{
		ext++ ;

		if ( ( ( strlen(ext) == 3 ) && ( toupper(ext[0]) == 'Z' ) && ( toupper(ext[1]) == 'I' ) && ( toupper(ext[2]) == 'P' ) ) ||
		     ( ( strlen(ext) == 3 ) && ( toupper(ext[0]) == 'A' ) && ( toupper(ext[1]) == 'D' ) && ( toupper(ext[2]) == 'Z' ) ) )
		{
			unzipMSX( newfilename, zipfilename, zipnumber ) ;
			return ;
		}
	}
	*zipnumber = 0 ;
}
*/


int CXBoxSample::selectMsxFile( char *msxfilename, char *msxzipfilename, int *msxzipnumber ) 
{
	unsigned int selectedGame ;
	char filename[512] ;
	char localfile[512] ;
	char zipfile[512] ;
	char *ext ;
	char *usefile ;
	int zipnumber ;
	int retval ;

	selectedGame = 0 ;
	zipnumber = 0 ;
	retval = 0 ;

	localfile[0] = zipfile[0] = 0 ;

	changeMenu( &m_skin.otherMenu, &m_skin.gameSelectMenu ) ;

	if ( ( selectedGame = doSelectGame( 0, 1 ) ) != 0xFFFFFFFF ) 
	{

		strcpy((char*)filename, m_szCurrentDir ) ;
		strcat( (char*)filename, (const char*)files[selectedGame].filename ) ;


		createLocal( filename, localfile, zipfile, &zipnumber ) ;
		usefile = ( strlen(zipfile) ) ? zipfile : localfile ;

		strcpy( msxfilename, usefile ) ;
		strcpy( msxzipfilename, filename ) ;
		*msxzipnumber = zipnumber ;

		retval = 1 ;

	}

	changeMenu( &m_skin.gameSelectMenu, &m_skin.otherMenu ) ;

	return retval ;
}


void CXBoxSample::configureHardDrive( int drive )
{
#if 0
	int menuChoice = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu);

	
		swprintf( m_menuText[0], L"Configure Hard Drives"  );
		swprintf( m_menuText[1], L"File/Directory : %S", strchr(pProperties->harddrive[drive].slot, '\\' ) ? strrchr( pProperties->harddrive[drive].slot, '\\' ) +1 : pProperties->harddrive[drive].slot); 
		swprintf( m_menuText[2], L"Device Name : %S", pProperties->harddrive[drive].devicename );
		swprintf( m_menuText[3], L"Volume Name : %S", pProperties->harddrive[drive].volumename );
		swprintf( m_menuText[4], L"Permissions : %S", pProperties->harddrive[drive].readOnly ? "Read Only" : "Read/Write"  );
		swprintf( m_menuText[5], L"Boot Priority : %u", pProperties->harddrive[drive].bootPriority  );

		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 6, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			int needVol = 0 ;
			int isOK = 1 ;

			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;

			if ( strlen( pProperties->harddrive[drive].slot ) )
			{
				DWORD attr ;

				attr = GetFileAttributes( pProperties->harddrive[drive].slot ) ;

				if ( attr != (DWORD)-1 )
				{
					needVol = ( attr & FILE_ATTRIBUTE_DIRECTORY ) ;
				}

				if (strlen ( pProperties->harddrive[drive].devicename) == 0 )
				{
					popupMsg( "Device Name cannot be blank.", &m_pnlBackgroundOther ) ;
					isOK = 0 ;
				}

				if ( needVol && (strlen ( pProperties->harddrive[drive].volumename ) == 0 ) )
				{
					popupMsg( "Volume Name cannot be blank.", &m_pnlBackgroundOther ) ;
					isOK = 0 ;
				}
			}

			if ( isOK )
			{
				XBInput_GetInput();
				return ;
			}
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;

			switch ( menuChoice )
			{
				case 0 : 
				{
					int askeject = 0 ;
					DWORD selectedGame = 0 ;
					int res = yesNoMenu( "Select a Directory as a Hard Drive?", &m_pnlBackgroundOther ) ;

					if ( res < 0 )
					{
						askeject = 1 ;
					}
					else if ( res == 0 )
					{
						if ( ( selectedGame = doSelectGame( 0,1,1 ) ) != 0xFFFFFFFF ) 
						{
							strcpy( pProperties->harddrive[drive].slot, m_szCurrentDir ) ;
							while ( strlen( pProperties->harddrive[drive].slot) && ( pProperties->harddrive[drive].slot[strlen(pProperties->harddrive[drive].slot)-1] == '\\' ) )
							{
								pProperties->harddrive[drive].slot[strlen(pProperties->harddrive[drive].slot)-1] = 0 ;
							}
							strcpy( pProperties->harddrive[drive].slotZip, pProperties->harddrive[drive].slot) ;
						}
						else
						{
							askeject = 1 ;
						}
					}
					else
					{

						if ( selectMsxFile( pProperties->harddrive[drive].slot, pProperties->harddrive[drive].slotZip, &(pProperties->harddrive[drive].zipNumber) ) )
						{
						}
						else
						{
							askeject = 1 ;
						}
					}

					if ( askeject )
					{
						char msg[50] ;

						sprintf( msg, "Remove Hard Drive %u?", menuChoice+1 ) ;
						if ( yesNoMenu( msg, &m_pnlBackgroundOther ) == 0 )
						{
							pProperties->harddrive[drive].zipNumber = 0 ;
							strcpy( pProperties->harddrive[drive].slot, "" ) ;
							strcpy( pProperties->harddrive[drive].slotZip, "" ) ;
						}
					}
					break ;
				}
				case 1 : getKeyboardString( pProperties->harddrive[drive].devicename, 29 ) ; break ;
				case 2 : getKeyboardString( pProperties->harddrive[drive].volumename, 29 ) ; break ;
				case 3 : pProperties->harddrive[drive].readOnly = ! pProperties->harddrive[drive].readOnly ;  break ;
				case 4 : pProperties->harddrive[drive].bootPriority = (pProperties->harddrive[drive].bootPriority+1)%5 ;  break ;
			}


		}
	}
#endif
}

void CXBoxSample::configureHardDrives()
{
#if 0
	int menuChoice = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu);

	
		swprintf( m_menuText[0], L"Configure Hard Drives"  );
		swprintf( m_menuText[1], L"Hard Drive 1 - %S", strchr(pProperties->harddrive[0].slot, '\\' ) ? strrchr( pProperties->harddrive[0].slot, '\\' ) +1 : pProperties->harddrive[0].slot);
		swprintf( m_menuText[2], L"Hard Drive 2 - %S", strchr(pProperties->harddrive[1].slot, '\\' ) ? strrchr( pProperties->harddrive[1].slot, '\\' ) +1 : pProperties->harddrive[1].slot);
		swprintf( m_menuText[3], L"Hard Drive 3 - %S", strchr(pProperties->harddrive[2].slot, '\\' ) ? strrchr( pProperties->harddrive[2].slot, '\\' ) +1 : pProperties->harddrive[2].slot);
		swprintf( m_menuText[4], L"Hard Drive 4 - %S", strchr(pProperties->harddrive[3].slot, '\\' ) ? strrchr( pProperties->harddrive[3].slot, '\\' ) +1 : pProperties->harddrive[3].slot);
		swprintf( m_menuText[5], L"Hard Drive 5 - %S", strchr(pProperties->harddrive[4].slot, '\\' ) ? strrchr( pProperties->harddrive[4].slot, '\\' ) +1 : pProperties->harddrive[4].slot);

		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 6, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			XBInput_GetInput();
			return ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;

			configureHardDrive( menuChoice ) ;

		}
	}
#endif
}


int CXBoxSample::selectMachineDefaults( )
{
	return 0 ;
}


void CXBoxSample::doConfigureGame( char *settingsname, char *keysname )
{

	int menuChoice ;
	char localfile[512], zipfile[512] ;
	char *usefile ;
	char *ext ;
	int zipnumber ;
	char *filetypes[] = { "AutoDetect", "Tape", "Snapshot", "Plus-3 Disk", "TRDOS Disk", "SimpleIDE HDF" } ;
	char *machines[] = { "16", "48", "128", "Plus2", "Plus2a", "Plus3", "Plus3e", "TC2048", "TC2068", "TS2068", "Pentagon", "Scorpion", "SE" } ;
	char *joytypes[] = {   "None", "Cursor", "Kempston", "Sinclair 1", "Sinclair 2", "Timex 1", "Timex 2" } ;

	menuChoice = 0 ;

	localfile[0] = zipfile[0] = 0 ;

	zipnumber = 0 ;
	m_SPECzipnumber = 0 ;


	loadKeys( keysname ) ;


	while ( 1 )
	{
		pmenuParams = &(m_skin.otherMenu);

		swprintf( m_menuText[0], L"Game Configuration" );
		swprintf( m_menuText[1], L"Image Type - %S", filetypes[m_specFileType]  );
		swprintf( m_menuText[2], L"Machine Type - %S", machines[m_specMachineType]  );
		swprintf( m_menuText[3], L"Autoload - %S", m_specAutoload ? "Yes" : "No" ) ;
		swprintf( m_menuText[4], L"Kempston Joystick - %S", m_specKempston ? "Enabled" : "Disabled" ) ;
		swprintf( m_menuText[5], L"Joystick 1 - %S", joytypes[m_specJoy1] ) ;
		swprintf( m_menuText[6], L"Joystick 2 - %S", joytypes[m_specJoy2] ) ;
		swprintf( m_menuText[7], L"Joystick Keyboard - %S", joytypes[m_specJoyKey] ) ;
		swprintf( m_menuText[8], L"SLT Instructions - %S", m_specSLT ? "Enabled" : "Disabled" ) ;
		swprintf( m_menuText[9], L"TRAPs - %S", m_specTRAP ? "Enabled" : "Disabled" ) ;
		swprintf( m_menuText[10], L"Tape Sounds - %S", m_specTapeSound ? "Enabled" : "Disabled" ) ;
		swprintf( m_menuText[11], L"Configure Controllers"  );

		
		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 12, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
	        XBInput_GetInput();
			break ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			switch ( menuChoice )
			{
				case 0 : m_specFileType = (m_specFileType+1)%6 ; break ;
				case 1 : m_specMachineType = (m_specMachineType+1)%13 ; break ;
				case 2 : m_specAutoload = !m_specAutoload ; break ;
				case 3 : m_specKempston = !m_specKempston ; break ;
				case 4 : m_specJoy1 = (m_specJoy1+1)%7 ; break ;
				case 5 : m_specJoy2 = (m_specJoy2+1)%7 ; break ;
				case 6 : m_specJoyKey = (m_specJoyKey+1)%7 ; break ;
				case 7 : m_specSLT = !m_specSLT ; break ;
				case 8 : m_specTRAP = !m_specTRAP ; break ;
				case 9 : m_specTapeSound = !m_specTapeSound ; break ;
				case 10 : doConfigureControllers() ; break ; 
				default : break ;
			}
		}


	}



	saveSettings( settingsname ) ;
	saveKeys( keysname ) ;

}



void CXBoxSample::createBlankDisk( int floppy_hd, int dd_hd) 
{
}


#define CD_SECS 60
#define CD_FRAMES 75



void CXBoxSample::doCDGame( )
{

}





void CXBoxSample::initConsole( UINT32 idx, int isFavorite, int forceConfig )
{
	char                filename[500] ;
	char				localfile[512] ;
	char				zipfile[512] ;
	char				*usefile ;
	char				*ext ;
	int					zipnumber ;
	char                uprfilename[500] ;
	char				shortpath[100] ;
	unsigned char       *gimage ;
	int                 ntsccol ;
	FILE				*infile ;
	UINT32				fsize ;
	char *forcebuf ;
	int isOther ;
	char *disks[2] ;

	g_cdr_readmethod = 0 ;
	g_lastScreen = GetTickCount() ;
	throttling = 0 ;

	localfile[0] = zipfile[0] = 0 ;
	zipnumber = 0 ;

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

	xbox_print_memory() ;

	isOther = 0 ;
	throttle = 0 ;

	m_throttle = 0 ;

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


	if ( isFavorite )
	{
		strcpy( (char*)filename, m_filesFavorites[idx].filename ) ;
	}
	else
	{
		if ( g_autoLaunchGame )
		{
			strcpy( (char*)filename, g_launchData.szFilename ) ;
		}
		else
		{
			if ( idx == 0xFFFFFFFF )
			{
				strcpy((char*)filename, "Z:\\CDGAME.CDG") ;
			}
			else
			{
				strcpy((char*)filename, m_szCurrentDir ) ;
				strcat( (char*)filename, (const char*)files[idx].filename ) ;
			}
		}
	}

	m_bUsingSamba = ( strncmp( filename, "SMB:", 4 ) == 0 ) || ( strncmp( filename, "smb:", 4 ) == 0 ) ;
	m_bUsingRelax = ( strncmp( filename, "RLX:", 4 ) == 0 ) || ( strncmp( filename, "rlx:", 4 ) == 0 ) ;

	xbox_print_memory() ;
	if ( (strstr (filename, ".MP3")) || (strstr (filename, ".mp3")) )
	{
		if ( m_mp3player.loadFile( filename, 1, 0, 9999999 ) )
		{
			//writexbox( "nonomp3\r\n") ;
		}
		else
		{
			m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}

	if ( (strstr (filename, ".M3U")) || (strstr (filename, ".m3u")) )
	{
		if ( m_mp3player.loadPlaylist( filename ) )
		{
			//writexbox( "nonomp3\r\n") ;
		}
		else
		{
			m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}

	xbox_print_memory() ;

	char *p ;

	sprintfx("init\r\n") ;

	xbox_compatible_name( filename, shortpath ) ;




	strcpy( g_saveprefix, g_savePath ) ;
	strcat( g_saveprefix, "\\" ) ;
	strcat( g_saveprefix, shortpath ) ;
	p = strrchr(g_saveprefix, '.');
	if (p) *p = 0;

	CreateDirectory( g_saveprefix, NULL ) ;

	strcat( g_saveprefix, "\\" ) ;
	strcat( g_saveprefix, shortpath ) ;
	p = strrchr(g_saveprefix, '.');
	if (p) *p = 0;


	strcpy(g_settingsfile, g_saveprefix);
	strcat(g_settingsfile, ".stg");

	strcpy(g_keysfile, g_saveprefix);
	strcat(g_keysfile, ".key");

	strcpy(g_sramfile, g_saveprefix);
	strcat(g_sramfile, ".sav");

	strcpy(g_statefile, g_saveprefix);
	strcat(g_statefile, ".st0");

	strcpy(g_chtfile, g_saveprefix);
	strcat(g_chtfile, ".cht");

	sprintfx("init\r\n") ;

	if ( g_bIsBoot )
	{
		g_bIsBoot = 0 ;
		struct stat s ;

		if ( stat( g_keysfile, &s ) != 0 )
		{
			if ( stat( "d:\\boot.key", &s ) == 0 )
			{
				CopyFile( "d:\\boot.key", g_keysfile, TRUE ) ;
			}
			else
			{
				saveKeys( g_keysfile ) ;
			}
		}
		if ( stat( g_settingsfile, &s ) != 0 )
		{
			if ( stat( "d:\\boot.stg", &s ) == 0 )
			{
				CopyFile( "d:\\boot.stg", g_settingsfile, TRUE ) ;
			}
			else
			{
				loadSettings( g_settingsfile ) ;
			}
		}
	}

	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;

	xbox_print_memory() ;

	m_configurefile = filename ;
	m_noconfigfile = loadSettings( g_settingsfile ) ;


	if ( idx == 0xFFFFFFFF )
		forceConfig = 1 ;

	if ( m_noconfigfile )
	{
		//no current settings
	    
		if ( idx != 0xFFFFFFFF )
		{
		}
	}
	else
	{
				//createLocal( pProperties->diskdrive.slotZip[i], localfile, zipfile, &(pProperties->diskdrive.autostart[i]) ) ;
				//usefile = ( strlen(zipfile) ) ? zipfile : localfile ;
				//strcpy( pProperties->diskdrive.slot[i], usefile ) ;
	}




	if ( forceConfig || m_noconfigfile )
	{
		m_SPECzipnumber = 0 ;
		changeMenu( &m_skin.gameSelectMenu, &m_skin.otherMenu ) ;
		doConfigureGame( g_settingsfile, g_keysfile ) ;
		isOther = 1 ;
	}

	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;

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

	global_error_message[0] = 0 ;




	if ( g_autoLaunchGame )
	{
		m_pnlSplashGame.Render() ;
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
	}
	else
	{
#ifndef NO_NETWORK
		if ( m_bNetplay )
		{
			changeMenu( &m_skin.gameSelectMenu, &m_skin.otherMenu ) ;
			if ( setupNetplay() )
				return ;
			doTransition( &m_pnlBackgroundOther, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
		else
#endif
		{
			if ( isOther )
			{
				doTransition( &m_pnlBackgroundOther, &m_pnlSplashGame, m_skin.fade, 1 ) ;
			}
			else
			{
				doTransition( &m_pnlBackgroundSelect, &m_pnlSplashGame, m_skin.fade, 1 ) ;
			}
		}
	}

	xbox_print_memory() ;
	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;

	if ( !m_bBgmInGame )
	{
		m_mp3player.pause( TRUE ) ;
	}



	//if ( !isOther )
	//{
		loadKeys( g_keysfile ) ;
	//}


	xbox_print_memory() ;


	m_numFrames = 0 ;

	//xbox_set_RAM_location() ;

	sprintfx("init\r\n") ;

	//PaletteChanged = 0 ;


	m_sound.init() ;

	// Create our texture
	init_texture();

	// Create our sprite driver
	if ( Sprite == NULL )
		D3DXCreateSprite(m_pd3dDevice, &Sprite);
	
	localfile[0] = zipfile[0] = 0 ;

	createLocal( filename, localfile, zipfile, &m_SPECzipnumber ) ;
	strcpy( filename, ( strlen(zipfile) ) ? zipfile : localfile ) ;

	if ( strlen(filename) == 0 )
		return ;

	saveSettings( g_settingsfile ) ;

	cht_load();


	m_state = IN_GAME ;

	m_fAppTime = 0.0f ;

	g_dwStartTime = GetTickCount() ;
	g_dwTimePaused = 0 ;
	m_dwStartPause = 0 ;

	m_steps = 0 ;
	m_sound.pause( FALSE ) ;


	strcpy( uprfilename, filename ) ;
	strupr( uprfilename ) ;


	int numdisks = 0 ;


	m_startTime = GetTickCount() ;

	//m_plaything.FreeSprites() ;
	freeTextures() ;


	if ( Keyboard_Init( 25, 500, 50 ) )
	{
	    OUTPUT_DEBUG_STRING( "Inited keyboard success\n" );
	}
	else
	{
	    OUTPUT_DEBUG_STRING( "Inited keyboard failure\n" );
	}

	memset(keyboard_keystate, 0, 256 ) ;
	m_mouseX = 0 ;
	m_mouseY = 0 ;
	m_mouseButtons = 0 ;

	char szLine[1024] ;

	//sprintf( szLine, "/rom1 \"%s\"", filename ) ;
	szLine[0] = 0 ;



	QueryPerformanceCounter((union _LARGE_INTEGER *) m_performancePrev);

	//xbox_set_refreshrate( pProperties->ntscmode ? 60 : 50 ) ;
	xbox_set_refreshrate( 50 ) ;



	applyHardwareFilter() ;

#ifdef VIRTUAL_MEM
    __try {
#endif
		memset( m_memMatches, 1, CONSOLE_MEMORY_SIZE ) ;
		m_currentMemMatches = CONSOLE_MEMORY_SIZE ;

#ifdef XPROFILER
		DmStartProfiling( "d:\\profile.log", 1024*1024*3 ) ;
#endif

		char filetype[25] ;
		char machine[15] ;
		char autoload[20] ;
		char kempston[20] ;
		char joy1[5] ;
		char joy2[5] ;
		char joykey[5] ;
		char slt[20] ;
		char trap[20] ;
		char tapesound[20] ;
		char fastload[20] ;


		itoa( m_specJoy1, joy1, 10 ) ;
		itoa( m_specJoy2, joy2, 10 ) ;
		itoa( m_specJoyKey, joykey, 10 ) ;

		if ( m_specTapeSound )
		{
			strcpy( tapesound, "--loading-sound" ) ;
			strcpy( fastload, "--no-fastload" ) ;
		}
		else
		{
			strcpy( tapesound, "--no-loading-sound" ) ;
			strcpy( fastload, "--fastload" ) ;
		}

		if ( m_specSLT )
			strcpy( slt, "--slt" ) ;
		else
			strcpy( slt, "--no-slt" ) ;

		if ( m_specTRAP )
			strcpy( trap, "--traps" ) ;
		else
			strcpy( trap, "--no-traps" ) ;

		if ( m_specAutoload )
			strcpy( autoload, "--auto-load" ) ;
		else
			strcpy( autoload, "--no-auto-load" ) ;

		if ( m_specKempston )
			strcpy( kempston, "--kempston" ) ;
		else
			strcpy( kempston, "--no-kempston" ) ;

		switch ( m_specFileType )
		{
			case 1 : strcpy( filetype, "--tape" ); break ;
			case 2 : strcpy( filetype, "--snapshot" ); break ;
			case 3 : strcpy( filetype, "--plus3disk" ); break ;
			case 4 : strcpy( filetype, "--trdosdisk" ); break ;
			case 5 : strcpy( filetype, "--simpleide-masterfile" ); break ;
			default : strcpy( filetype, "" ); break ;
		}

		switch ( m_specMachineType )
		{
			case 0 : strcpy( machine, "16" ); break ;
			case 1 : strcpy( machine, "48" ); break ;
			case 2 : strcpy( machine, "128" ); break ;
			case 3 : strcpy( machine, "plus2" ); break ;
			case 4 : strcpy( machine, "plus2a" ); break ;
			case 5 : strcpy( machine, "plus3" ); break ;
			case 6 : strcpy( machine, "plus3e" ); break ;
			case 7 : strcpy( machine, "2048" ); break ;
			case 8 : strcpy( machine, "2068" ); break ;
			case 9 : strcpy( machine, "ts2068" ); break ;
			case 10 : strcpy( machine, "pentagon" ); break ;
			case 11 : strcpy( machine, "scorpion" ); break ;
			case 12 : strcpy( machine, "se" ); break ;
			default : strcpy( machine, "" ) ; break ;
		}
		
		if ( m_specFileType == 0 )
		{
			char *myargs[] = { "xspectrum", kempston, autoload, fastload, tapesound, trap, slt, "--joystick-keyboard-output", joykey, 
							"--joystick-1-output", joy1, "--joystick-2-output", joy2, 
							"--machine", machine, filename } ;
			//char *myargs[] = { "xspectrum", filename } ;
			//char *myargs[] = { "xspectrum", "--tape", filename } ;
			//char *myargs[] = { "xspectrum", "--no-auto-load", "--tape", filename } ;

			fusemain( 16, myargs ) ;
		}
		else
		{
			char *myargs[] = { "xspectrum", kempston, autoload, fastload, tapesound, trap, slt, "--joystick-keyboard-output", joykey, 
							"--joystick-1-output", joy1, "--joystick-2-output", joy2, 
							"--machine", machine, filetype, filename } ;
			//char *myargs[] = { "xspectrum", filename } ;
			//char *myargs[] = { "xspectrum", "--tape", filename } ;
			//char *myargs[] = { "xspectrum", "--no-auto-load", "--tape", filename } ;

			fusemain( 17, myargs ) ;
		}
#ifdef XPROFILER
		DmStopProfiling() ;
#endif

#ifdef VIRTUAL_MEM
    } __except(ExceptionFilter(GetExceptionInformation())) {
		popupMsg( "Exception occurred - you should probably restart.", &m_pnlBackgroundOther ) ;
    };
#endif


	saveKeys( g_keysfile ) ;
	cleanupConsole() ;

	char tmpfilename[1024] ;

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

	m_sound.cleanup() ;
	sprintfx( "done bliss\r\n") ;
	m_state = MAIN_MENU ;
#ifdef USE_NETPLAY
	m_sockNetplay.m_debugClientSock.Close() ;
#endif
	sprintfx( "done bliss\r\n") ;

	throttling = 0 ;

}



void CXBoxSample::cleanupConsole( )
{
	sprintfx( "done2\r\n") ;
	cht_save() ;
	sprintfx( "done2\r\n") ;


	if (m_cheatCodes != NULL)
	{
		free(m_cheatCodes);
		m_cheatCodes = NULL;
	}
	if ( g_rumbleCodes != NULL )
	{
		free(g_rumbleCodes) ;
		g_rumbleCodes = NULL ;
	}
	sprintfx( "done2\r\n") ;
	//see loader_unload() for other things to free
}


void CXBoxSample::applyGameGenie( unsigned char *ROM, unsigned int romsize )
{
	unsigned char *currpos ;


/*
	for ( unsigned int i = 0 ; i < m_numCheats ; i++ )
	{

		if ( ! m_cheatCodes[i].enabled )
			continue ;

		if ( ( m_cheatCodes[i].type & 0xF0 ) != 0x90 )
			continue ;

		if ( m_cheatCodes[i].type == 0x99 )   //6char code
		{
			currpos = ROM + m_cheatCodes[i].adr ; 

			while ( romsize > ( currpos-ROM) )
			{
				*currpos = ( m_cheatCodes[i].val & 0xFF) ;
				currpos += 0x8000 ;
			}
		}
		else  //8char code
		{
			currpos = ROM + ( m_cheatCodes[i].adr & 0x1FFF ) ; 

			while ( romsize > ( currpos-ROM ) )
			{
				//sprintfx( "checking for %u at %04.4X\r\n", ((unsigned char)m_cheatCodes[i].code[16]), currpos-ROM ) ;
				if ( *currpos == ((unsigned char)m_cheatCodes[i].code[16]) )
				{
				//sprintfx( "writing %u to %04.4X\r\n", m_cheatCodes[i].val, currpos-ROM ) ;
					*currpos = ( m_cheatCodes[i].val & 0xFF) ;
				}
				currpos += 0x2000 ;
			}
		}

	}
	*/
}



#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_process_sound(  unsigned char *sampleBuffer, unsigned int sampleCount ) 
{
	//g_app->m_mp3player.process() ;
	g_app->m_sound.process( (unsigned char*)sampleBuffer, sampleCount, g_app->m_throttle ) ;
}


void xbox_render( unsigned char *image ) 
{
	//writexbox( "renderimage\r\n") ;
	g_app->renderImage( image ) ;
}

void xbox_set_palette(const unsigned int* p, const unsigned char numEntries) 
{
	//writexbox( "setpal\r\n") ;
	g_app->SetPalette( p, numEntries ) ;

}

int xbox_quit() 
{
	return  ( g_app->m_state == MAIN_MENU ) ;
}

void xbox_set_memory( unsigned char *ptr, unsigned int ramsize )
{
	m_memory_locations[0] = ptr ;
#ifdef _DEBUG
	#ifdef VIRTUAL_MEM
		m_memory_sizes[0] = ramsize ;
	#else
		m_memory_sizes[0] = min(ramsize,4*0x4000) ;
	#endif
#else
	m_memory_sizes[0] = ramsize ;
#endif
}

int xbox_mouse( int port ) 
{
	return g_app->doMouse( port ) ;
}
int xbox_getThrottle() 
{
	return throttle ;
}
void xbox_put_message( char *message ) 
{
}

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


void xbox_lock( unsigned char **ptr )
{
	//if ( 0 ) //g_app->m_xboxSFilter )
	//{
		//*ptr = (unsigned char*)g_app->g_pBlitBuff;
	//}
	//else
	{
		if ( g_textureLocked == 0 )
		{
			D3DLOCKED_RECT d3dlr;
			RECT rectSource;

			g_textureLocked = 1 ;

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

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

			*ptr = (unsigned char*)d3dlr.pBits ;
		}
	}
}


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


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 ; //g_app->m_xboxSFilter ? 908*2 : g_app->m_pitch ;
}

unsigned char *xbox_cdbuffer() 
{

	return (g_app->m_ptrCdBuf)+12 ;
}



int xbox_read_sector_type( unsigned int sector, unsigned int sector_type ) 
{
#if 0
	unsigned char szbuf[6] ;
	DWORD numread ;
	DWORD success ;
	//DWORD begintime, endtime ;
	//static DWORD totaltime = 1 ;
	//static DWORD iters = 0 ;
	//static DWORD cacheiters = 0 ;
	//static float avg = 0.0 ;

	//begintime = GetTickCount() ;

	//sprintfx("read sector %u\r\n", sector  ) ;

	success = 1 ;

	if ( ( sector < g_app->m_currentStartSector ) || ( sector >= g_app->m_currentStartSector + CD_BUF_SECTORS ) )
	{
		if ( 1 || g_app->m_bRealCD )
		{
			memset( g_app->m_cdDataBuffer,0,CD_DATA_BUFFER_SIZE) ;
			for ( int i = 0 ; i < CD_BUF_SECTORS  ; i++ )
			{
				if ( g_app->m_io.ReadSectorCDDA( g_app->m_hCdrom, sector, (LPSTR)(g_app->m_cdDataBuffer + (i*2352))) < 0 )
				{
					success = 0 ;
					break ;
				}
			}
				//g_app->m_io.ReadXASector2( sector, CD_BUF_SECTORS, g_app->m_cdDataBuffer ) ;

			//sprintfx( "read %u bytes from CD\r\n", numread ) ;

		}
		else
		{
#if 0
			if ( g_app->m_bNetworkCD )
			{
				memcpy( szbuf, &sector, 4 ) ;
				szbuf[4] = 2 + sector_type ; //psx is all XA data (2) + 1 for data or 0 for cdda

				g_app->m_sockNetplay.Send( szbuf, 5 ) ;
				numread = g_app->m_sockNetplay.Recv( g_app->m_cdDataBuffer, 2352 ) ;

//				sprintfx("read sector %u bytes %u\r\n", sector, numread ) ;

				while ( numread < 2352 )
				{
					numread += g_app->m_sockNetplay.Recv( g_app->m_cdDataBuffer+numread, 2352-numread ) ;
					//sprintfx("read sector %u bytes %u\r\n", sector, numread ) ;
				}

			}
			else
			{
				if ( g_app->m_bUsingSamba )
				{
					g_app->m_smb.lseek(g_app->m_smbCdFile,sector*2352,SEEK_SET);
					g_app->m_smb.read(g_app->m_smbCdFile,g_app->m_cdDataBuffer, 2352*CD_BUF_SECTORS ) ;
				}
				else
				{
					gzseek( g_app->m_cdfile, 2352*sector, SEEK_SET ) ;
					gzread( g_app->m_cdfile , g_app->m_cdDataBuffer, 2352*CD_BUF_SECTORS ) ;
				}
			}
#endif
		}


		g_app->m_currentStartSector = sector ;
	}
	else
	{
		//cacheiters++ ;
		//sprintfx("read sector %u from cache\r\n", sector  ) ;
	}
	g_app->m_ptrCdBuf = g_app->m_cdDataBuffer + ((sector-g_app->m_currentStartSector)*2352) ;
	return success ;
#endif
	return 0 ;
}




int xbox_read_sector_cdda( unsigned int sector ) 
{
	return xbox_read_sector_type( sector,0 ) ;
}

HANDLE xbox_getcdrom_handle()
{
	return g_app->m_hCdrom ;

}

void xbox_docdda()
{
	//g_app->m_cdda.process() ;
	//g_app->m_mp3player_cdda.processReal() ;
}
void xbox_docdda_mp3()
{
	//g_app->m_mp3player_cdda.processReal() ;
}

void xbox_feed_stream(unsigned char* pSound,long lBytes) 
{
	//sprintfx( "before feed\r\n") ;
	//g_app->m_sound.process(pSound, lBytes ) ;
	//g_app->m_mp3player.process() ;
	//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 int xbox_get_controller_value( int port ) 
{
	return g_app->m_emuControllers[port] ;
}
//void xbox_do_prefs( struct uae_prefs *prefs )
//{
	//strcpy( prefs->df[0], "D:\\amigadisks\\globulus.adf" ) ;
//}

unsigned int xbox_read_input(int port) 
{
	//writexbox( "before readinput") ;

	//return 0 ;

	//MEMORYSTATUS stat;

    // Get the memory status.
    //GlobalMemoryStatus( &stat );

	//sprintfx("available memory = %u\r\n", stat.dwAvailPhys  ) ;


//	return ReadJoypad( port ) ;

	//writexbox( "after readinput") ;
	return 0 ;
}

void xbox_sound( unsigned char *buf, unsigned int bufsize )
{
	g_sound->process( buf, bufsize, g_app->m_throttle ) ;
}

void xbox_mp3_process()
{
	//g_mp3player->process() ;

}
char * xbox_get_config_disk( int num )
{
	//return g_properties.diskdrive.slot[num] ;
	return NULL ;
}

int xbox_frame( unsigned char *buf)
{
	//g_sound->process() ;
	
	//if ( g_app->m_throttle )
		//g_app->m_throttle-- ;

	//if ( g_app->m_throttle == 0 )

	/*
	switch ( CDDAStatus )
	{
		case -1 : 
			{
				g_app->m_mp3player_cdda.pause( TRUE ) ; 
				g_app->m_cdda.pause( TRUE ) ;
				break ;
			}
		case 0  : 
			{
				g_app->m_mp3player_cdda.stop() ; 
				g_app->m_cdda.pause( TRUE ) ;
				memset( g_app->m_cdda.m_pSoundBufferData, 0, g_app->m_cdda.stream_buffer_size ) ;
				break ;
			}
		default :  
			{
				g_app->m_mp3player_cdda.pause( FALSE ) ; 
				break ;
			}

	}
*/

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

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

	return 0 ;
}

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

}
void xbox_get_mousestate(int* dx, int* dy, int* buttons) 
{
	*dx = m_mouseX ;
	*dy = m_mouseY ;
	*buttons = m_mouseButtons ;
}

int xbox_check_events( )
{
	//writexbox( "before events") ;
	//g_app->m_cdda.process();

	//if( m_bKeyboardMode )
	//{
		if ( GetTickCount() - g_lastScreen > 50 )
		{
			if ( g_app->m_throttle==0 )
				g_app->render_to_texture( NULL ) ;
		}
	//}
	return g_app->handleEvents() ;

	//writexbox( "after events") ;
	//return 0 ;
}
char *xbox_save_path()
{
	return g_app->g_savePath ;
}


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 throttling ;
	//return g_app->m_throttle ;
}
unsigned int xbox_get_throttle_speed()
{
	return m_throttleSpeed ;
}
unsigned char xbox_controller( unsigned char N ) 
{
	return ( g_app->m_emuControllers[N] & 0x3F );
}

void xbox_put_image( unsigned char* msg)
{
	//writexbox( "before render") ;
	//g_sound->process() ;
	//g_mp3player->process() ;
	//g_mp3player->process() ;
	if ( g_app->m_throttle )
		g_app->m_throttle-- ;

	if ( g_app->m_throttle == 0 )
		g_app->render_to_texture(msg) ;
	//writexbox( "after render") ;
}
unsigned int xbox_GetTicks() 
{
	return GetTickCount() ;
}

void xbox_process_audio( char *buf, int index, int length )
{
//	g_sound->process( buf, index, length ) ;
	//g_app->m_mp3player.process() ;
	

}

void dopresent()
{
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}

void xbox_open_zip( char *hugozipfile )
{
	//writexbox( "before zip") ;
	//g_app->rom_load_zip( hugozipfile ) ;
	//writexbox( "after zip") ;
}
void xbox_set_RAM_location( char *ptr ) 
{

	m_memory_locations[0] = (byte*)( ptr ) ;

}
unsigned char* xbox_get_screenbuf()
{
	return (unsigned char*)g_app->g_pBlitBuff ;
}
long xbox_stop_cdda() 
{
	//writexbox("stop cdda\r\n") ;
	//g_app->m_cdda.stop() ;
	return 0 ;
}
long xbox_stop_cdda_mp3() 
{
	//writexbox("stop cdda\r\n") ;
	//g_app->m_mp3player_cdda.stop() ;
	return 0 ;
}

unsigned int xbox_getnumframes()
{
	return g_app->m_numFrames ;
}
int xbox_iread( void *buf, int size1, int size2, int fd )
{

	return m_iso9660.ReadFile( fd, (byte*)buf, size1*size2 ) / size1 ;

	//sprintfx( "reade %u %u %d\r\n", size1, size2, fd ) ;
}

int xbox_iopen( char *name, char* type, int tracknum )
{
	return m_iso9660.OpenFile( name ) ;
}

unsigned int xbox_ilength( int fd )
{
	return m_iso9660.GetFileSize( fd ) ;
}

int xbox_iclose( int fd )
{
	m_iso9660.CloseFile( fd ) ;
	return 0 ;
}

int xbox_iseek( int fd, int pos, int type )
{
	m_iso9660.Seek( fd, pos, type ) ;
	return 0 ;
}

int xbox_sread( void *buf, int size1, int size2, int fd )
{
	//sprintfx( "read %u %u %d\r\n", size1, size2, fd ) ;

	return g_app->m_smb.read( fd, buf, size1*size2 ) / size1 ;

	//sprintfx( "reade %u %u %d\r\n", size1, size2, fd ) ;
}

int xbox_sopen( char *name, char* type )
{
	return g_app->m_smb.open( name,O_RDONLY|O_BINARY);
}

int xbox_sclose( int fd )
{
	return g_app->m_smb.close( fd );
}

int xbox_sseek( int fd, int pos, int type )
{
	//sprintfx( "seek %d %d %d\r\n", fd, pos, type ) ;
	g_app->m_smb.lseek( fd, pos, type ) ;
	return 0 ;
	//sprintfx( "seeke %d %d %d\r\n", fd, pos, type ) ;
}
int xbox_rread( void *buf, int size1, int size2, void *fd )
{

	//sprintfx( "read %u %u %d\r\n", size1, size2, fd ) ;
	if ( ((CRelax*)fd)->ReadAll( buf, size1*size2 ) )
		return size2 ;
	else
		return 0 ;

	//sprintfx( "reade %u %u %d\r\n", size1, size2, fd ) ;
}

void* xbox_ropen( char *name, char* type, int tracknum )
{
	if ( g_app->m_relaxTracks[tracknum].Open( name ) )
	{
		//sprintfx( "ptr %d = track %u\r\n", &(g_app->m_relaxTracks[tracknum]), tracknum ) ;
		return &(g_app->m_relaxTracks[tracknum]) ;
	}
	else
		return &(g_app->m_relaxTracks[tracknum]) ;
		//return NULL ;
}
unsigned int xbox_rlength( void *fd )
{
	return ((CRelax*)fd)->GetLength() ;
}

int xbox_rclose( void *fd )
{
	((CRelax*)fd)->Close() ;
	return 0 ;
}

int xbox_rseek( void *fd, int pos, int type )
{
	//sprintfx( "seek %d %d %d\r\n", fd, pos, type ) ;
	((CRelax*)fd)->Seek( pos, type ) ;
	return 0 ;
}

FILE *xbox_fopen( char *filename, char *mode, int tracknum )
{
	if ( strnicmp( filename, "smb", 3 ) == 0 )
	{
		char smbfilename[1024] ;
		char *smbp ;
		FILE *outfile ;
		char *buf ;
		int  smbfile ;

		sprintf( smbfilename, "%s%s", g_app->m_smbShare, filename+4 ) ;

		while ( smbp = strchr( smbfilename, '\\' ) )
			*smbp = '/' ;

		smbfile = xbox_sopen( smbfilename,mode);

		if ( smbfile <= 0 )
		{
			return NULL ;
		}

		g_cdr_readmethod = 1 ;
		return (FILE*)smbfile ;

	}
	else if ( strnicmp( filename, "rlx", 3 ) == 0 )
	{
		FILE *outfile ;

		outfile = (FILE*)xbox_ropen( filename, mode, tracknum ) ;

		if ( outfile == NULL )
			return NULL ;

		g_cdr_readmethod = 2 ;
		return outfile ;
	}
	else if ( ( strncmp( filename, "S:", 2 ) == 0 ) || ( strncmp( filename, "s:", 2 ) == 0 ) )
	{
		FILE *outfile ;
		int filesize ;
		char *fbuf ;
		int isofd ;

		if ( ( isofd = m_iso9660.OpenFile( filename+2 ) ) < 0 )
		{
			return NULL ;
		}

		g_cdr_readmethod = 3 ;
		return (FILE*)(isofd+1) ;

	}
	else
	{
		g_cdr_readmethod = 4 ;
		return fopen( filename, mode ) ;
	}
}

int xbox_fseek( FILE *f, long offset, int origin )
{
	switch ( g_cdr_readmethod )
	{
		case 1 :
		{
			return xbox_sseek( (int)f, offset, origin ) ;
			break ;
		}
		case 2 :
		{
			return xbox_rseek( f, offset, origin ) ;
			break ;
		}
		case 3 :
		{
			return xbox_iseek( ((int)f)-1, offset, origin ) ;
			break ;
		}
		case 4 :
		default :
		{
			return fseek( f, offset, origin ) ;
			break ;
		}
	}

	return 0 ;
}
size_t xbox_fread( void *buffer, size_t size, size_t count, FILE *f )
{
	switch ( g_cdr_readmethod )
	{
		case 1 :
		{
			return xbox_sread( buffer, size, count, (int)f ) ;
			break ;
		}
		case 2 :
		{
			return xbox_rread( buffer, size, count, f ) ;
			break ;
		}
		case 3 :
		{
			return xbox_iread( buffer, size, count, ((int)f)-1 ) ;
			break ;
		}
		case 4 :
		default:
		{
			return fread( buffer, size, count, f ) ;
			break ;
		}
	}

	return 0 ;
}
int xbox_fclose( FILE *f )
{
	switch ( g_cdr_readmethod )
	{
		case 1 :
		{
			return xbox_sclose( (int)f ) ;
			break ;
		}
		case 2 :
		{
			return xbox_rclose( f );
			break ;
		}
		case 3 :
		{
			return xbox_iclose( ((int)f)-1 ) ;
			break ;
		}
		case 4 :
		default:
		{
			return fclose( f ) ;
			break ;
		}
	}

	return 0 ;
}
int xbox_fstat( FILE *f, struct stat *buffer )
{
	switch ( g_cdr_readmethod )
	{
		case 1 :
		{
			return g_app->m_smb.fstat( (int)f, buffer ) ;
			break ;
		}
		case 2 :
		{
			buffer->st_size = xbox_rlength( f ) ;
			return 0 ;
			break ;
		}
		case 3 :
		{
			buffer->st_size = xbox_ilength( ((int)f)-1 ) ;
			return 0 ;
			break ;
		}
		case 4 :
		default :
		{
			return fstat( fileno(f), buffer ) ;
			break ;
		}
	}

	return -1 ;
}

char* xbox_fgets( char *string, int n, FILE *f )
{
	char *pos = string ;
	char num = 0 ;
	bool readsome = false ;

	if ( n == 0 )
		return NULL ;

	while ( 1 )
	{
		if ( xbox_fread( pos, 1, 1, f ) != 1 )
		{
			*pos = 0 ;
			if ( readsome )
				return string ;
			else
				return NULL ;
		}

		readsome = true ;

		if ( *pos == '\n' )
		{
			pos++ ;
			*pos = 0 ;
			break ;
		}

		num++ ;

		if ( num >= n )
		{
			*pos = 0 ;
			break ;
		}

		pos++ ;
	}

	return string ;

}
int xbox_get_cdda_mp3_length( FILE *fp ) 
{
	//return g_app->m_mp3player_cdda.getlength( "", fp ) ;
	return 0 ;
}

void xbox_pause_cdda( int paused )
{
	//g_app->m_cdda.pause( paused ) ;
}
void xbox_pause_cdda_mp3( int paused )
{
	//g_app->m_mp3player_cdda.pause( paused ) ;
}

void xbox_stop_audio( ) 
{
	//g_mp3player->stop( ) ;
	//g_cdda->stop( ) ;
	//g_app->m_sound.min_volume() ;
}
void xbox_stop_audio_mp3( ) 
{
	//g_mp3player->stop( ) ;
	//g_app->m_mp3player_cdda.stop( ) ;
	//g_app->m_sound.min_volume() ;
}
void xbox_stop_cd()
{
	//g_cdda->stop() ;

}
void xbox_stop_cd_mp3()
{
	//g_app->m_mp3player_cdda.stop() ;

}
void xbox_read_cd_sector( unsigned char *p, unsigned int sector ) 
{
#if 0
	int result ;
	char xmsg[100] ;

	//result = g_app->m_io.ReadSector( g_app->m_hCdrom, sector, (LPSTR)p ) ;



	if ( ( sector < g_app->m_currentStartSector ) || ( sector >= g_app->m_currentStartSector + CD_BUF_SECTORS ) )
	{
		result = g_app->m_io.ReadSomeSectors( g_app->m_hCdrom, sector, (LPSTR)g_app->m_cdDataBuffer, CD_BUF_SECTORS ) ;

		g_app->m_currentStartSector = sector ;
	}

	memcpy( p, g_app->m_cdDataBuffer + ((sector-g_app->m_currentStartSector)*2048), 2048) ;

#endif
}
void xbox_play_cdda_mp3( FILE *fp, unsigned int lsn, unsigned int numframes ) 
{
	//if ( ( g_app->m_mp3player_cdda.m_mp3file != fp ) || (  g_app->m_mp3player_cdda.m_nFrameOffset != lsn ) || ( g_app->m_mp3player_cdda.m_bDone ) )
		//g_app->m_mp3player_cdda.loadFileReal( "", 1, lsn, numframes, 0, fp ) ;
}

size_t xbox_sizememsnap( void *st ) 
{
	return( ((StateMem *)st)->len );
}

unsigned char *xbox_bufmemsnap( void *st ) 
//int32 smem_read(StateMem *st, void *buffer, uint32 len)
{
	return (unsigned char*)(((StateMem *)st)->data) ;
}

int xbox_play_cdda( unsigned int sectorFrom, unsigned int sectorTo, unsigned char repeat ) 
{
	sprintfx( "play cdda %u %u\r\n", sectorFrom, sectorTo ) ;

	//g_cdda->play_sectors( sectorFrom+150, sectorTo+150, repeat, g_app->m_hCdrom ) ;
	return 1 ;
}

void* xbox_get_framebuffer( unsigned int *pitch )
{
	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	rectSource.bottom = g_app->theHeight-1 ;
	rectSource.right  = g_app->theWidth-1 ;

	// Lock the rect in our texture
	D3DLOCKED_RECT d3dlr;

	if ( g_app->m_xboxSFilter == 0 )
	{
		g_app->Texture->LockRect(0, &d3dlr, &rectSource, 0);
		*pitch = d3dlr.Pitch/2 ;
		return d3dlr.pBits ;
	}
	else
	{
		*pitch = 1280 ;
		return g_app->g_pBlitBuff ;
	}

}

void xbox_free_framebuffer()
{
	if ( g_app->m_xboxSFilter == 0 )
		g_app->Texture->UnlockRect(0);
}

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

void xbox_apply_game_genie( byte *ROM, unsigned int romsize)
{
	sprintfx( "about to apply gg\r\n") ;
	g_app->applyGameGenie( ROM, romsize ) ;

	//http://www.monmouth.com/~colonel/videogames/nes/genie.html
	/*
Game Genie code = SLXPLOVS (SMB3: infinite lives)
The following info is derived from SMB3.PAT:
CPU address: $9123
Compare value: $DE
Patch value: $BD

ROM address to start comparing: $9123 & $1FFF + $10 = $1133.

The value at offset $1133 in the ROM doesn't match, so move on to the next bank at $1133+$2000.
Doesn't match here either, so move on to the next bank. Continue like so and you will eventually reach
$3D133, where the value is indeed our compare value, $DE. Change it to $BD, and Mario will have a
minimum of 4 lives next time you play the game.
*/
}

#ifdef __cplusplus
}
#endif
void CXBoxSample::processEmu( BOOL render )
{
	/*
	static int whichframe = 0 ;

		
			updateCheats2() ;

			handleEvents();
			m_mp3player.process() ;

			//EmLoopOnce();  //makes callback to the audio

			if ( render )
			{
				if ( m_throttle )
				{
					if ( whichframe++ % 4 == 0 )
					{
						render_to_texture();
						m_numFrames++ ;
					}
				}
				else
				{
					render_to_texture();
					m_numFrames++ ;
				}
			}

			while ( m_sound.m_bDanger && ( m_state != MAIN_MENU ))
			{
				handleEvents();
				m_mp3player.process() ;
				//EmLoopOnce();  //makes callback to the audio
			}
			//m_sound.process( m_fAppTime, m_numFrames ) ;
 			
*/

}


int CXBoxSample::unzipMSX( char *zipfile, char *newfilename, int *zipnumber )
{
#if 0
	byte c, *data, *header;
	int len = 0, rlen;
	int menuChoice = 0 ;
	int numlines = 0 ;
	int currnum = 0 ;
	struct zfile *myzfile ;
	char tempdirname[20] ;
	SYSTEMTIME stime ;
	char filename[MAX_PATH];
	int filesize = 0;
	unz_file_info info;
	unzFile file ;

	OUTPUT_DEBUG_STRING( "unzipping\n") ;

	//writexbox( "ttt\r\n" ) ;
	myzfile = zfile_fopen( zipfile, "rb" ) ;

	if ( myzfile->data == 0  )
	{

		file = unzOpen(myzfile);

		if(file == NULL)
			return 0 ;

		//writexbox( "ttt\r\n" ) ;

		int port = unzGoToFirstFile(file);

		swprintf( m_menuText[numlines++], L"Select File From ZIP" ) ;

		//writexbox( "ttt\r\n" ) ;
		while(port == UNZ_OK)
		{
			char name[132];
			unzGetCurrentFileInfo(file, &info, name,128, NULL,0, NULL,0);

			if ( strrchr(name, '.' ) )
				strcpy( filename, strrchr(name,'.')+1 ) ;

			strupr(filename) ;

			if ( ( strcmp( filename, "NFO" ) == 0 ) ||
				( strcmp( filename, "TXT" ) == 0 ) ||
				( strcmp( filename, "DIZ" ) == 0 ) )
			{
			}
			else
			{
				swprintf( m_menuText[numlines++], L"%S", name ) ;
			}

			port = unzGoToNextFile(file);
		}

		//writexbox( "ttt\r\n" ) ;
		if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) )
		{
			unzClose(file) ;
			*zipnumber = 0 ;
			return 0 ;
		}
		//writexbox( "ttt\r\n" ) ;

		sprintfx( "found zipfile %s\r\n", filename ) ;


		if ( *zipnumber )
		{
			menuChoice = (*zipnumber) - 1 ;

			if ( menuChoice+1 > numlines-1 )
			{
				menuChoice = 0 ;
			}
		}
		else if ( numlines < 3 )
		{
			
			menuChoice = 0 ;
		}
		else
		{
			while ( 1 )
			{
				pmenuParams = &(m_skin.popupMenu) ;


				menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, numlines, 1, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;


				if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
				{
					m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
					XBInput_GetInput();
					menuChoice = 0 ;
					break ;
				}
				else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
				{
					m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
					XBInput_GetInput();
					break ;
				}


			}
		}

		*zipnumber = menuChoice +1 ;

		sprintf( filename, "%S", m_menuText[menuChoice+1] ) ;

		unzLocateFile(file,filename,1);
		unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0);
	    
		//writexbox( "ttt\r\n" ) ;
		if( unzOpenCurrentFile(file) != UNZ_OK )
		{
			unzClose(file);
			*zipnumber = 0 ;
			return 0 ;
		}

		//writexbox( "ttt\r\n" ) ;

		data = (byte*)malloc( min(info.uncompressed_size, 32*1024) ) ;

		//writexbox( "ttt\r\n" ) ;
	/*
		int l = unzReadCurrentFile(file,data,info.uncompressed_size);
		if(unzCloseCurrentFile(file) == UNZ_CRCERROR)
		{
			free(data) ;
			unzClose(file);
			*zipnumber = 0 ;
			return 0 ;
		}

		//writexbox( "ttt\r\n" ) ;
		unzClose(file);
	*/

		sprintfx( "loadeddata\n" ) ;

	}
	else
	{
		*zipnumber = 0 ;
		return 0 ;
	}

	char shortpath[100] ;
	char *p ;


	xbox_compatible_name( filename, shortpath ) ;



	Sleep( 2 ) ;
	GetSystemTime( &stime ) ;

	sprintf( tempdirname, "Z:\\%02.2u%02.2u%03.3u", stime.wMinute, stime.wSecond, stime.wMilliseconds ) ;

	CreateDirectory( tempdirname, NULL ) ;


	sprintf( newfilename, "%s\\%s", tempdirname, shortpath  ) ;


	sprintfx( "newfile %s\n", newfilename );

	DeleteFile( newfilename ) ;

	FILE *outfile = fopen( newfilename, "wb") ;

	if ( !outfile )
	{
		free(data) ;
		if ( myzfile->data == 0  )
		{
			unzClose(file);
		}
		*zipnumber = 0 ;
		return 0 ;
	}

	if ( myzfile->data == 0  )
	{
		for ( int i = 0 ; i < info.uncompressed_size / (32*1024) ; i++ )
		{
			int l = unzReadCurrentFile(file,data,32*1024);
			fwrite( data, 1, 32*1024, outfile ) ;
		}

		if ( info.uncompressed_size % (32*1024) )
		{
			int l = unzReadCurrentFile(file,data,info.uncompressed_size % (32*1024));
			fwrite( data, 1, info.uncompressed_size % (32*1024), outfile ) ;
		}


		unzCloseCurrentFile(file) ;
		unzClose(file);
		free(data) ;
	}
	else
	{
		fwrite( myzfile->data, myzfile->size, 1, outfile ) ;
		zfile_free( myzfile ) ;
	}

	fclose( outfile ) ;


#endif
	return 1;
}

#if 0
int CXBoxSample::unzipMSX( char *zipfile, char *newfilename )
{
	byte c, *data, *header;
	int len = 0, rlen;

	OUTPUT_DEBUG_STRING( "unzipping\n") ;

	//writexbox( "ttt\r\n" ) ;
    unzFile file = unzOpen(zipfile);

    if(file == NULL)
		return 0 ;

	//writexbox( "ttt\r\n" ) ;

    char filename[132];
    int filesize = 0;
    int port = unzGoToFirstFile(file);
    unz_file_info info;

	//writexbox( "ttt\r\n" ) ;
    while(port == UNZ_OK)
    {
		char name[132];
		unzGetCurrentFileInfo(file, &info, name,128, NULL,0, NULL,0);

		if ((int) info.uncompressed_size > filesize)
		{
			strcpy(filename,name);
			filesize = info.uncompressed_size;
		}
		port = unzGoToNextFile(file);
    }

	//writexbox( "ttt\r\n" ) ;
    if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) || filesize == 0)
    {
		unzClose(file) ;
		return 0 ;
    }
	//writexbox( "ttt\r\n" ) ;

	sprintfx( "found zipfile %s\r\n", filename ) ;

    unzLocateFile(file,filename,1);
    unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0);
    
	//writexbox( "ttt\r\n" ) ;
    if( unzOpenCurrentFile(file) != UNZ_OK )
    {
		unzClose(file);
		return 0 ;
    }

	//writexbox( "ttt\r\n" ) ;

	data = (byte*)malloc( info.uncompressed_size ) ;

	//writexbox( "ttt\r\n" ) ;

	int l = unzReadCurrentFile(file,data,info.uncompressed_size);
	if(unzCloseCurrentFile(file) == UNZ_CRCERROR)
	{
		free(data) ;
	    unzClose(file);
		return 0 ;
	}

	//writexbox( "ttt\r\n" ) ;
    unzClose(file);

	sprintfx( "loadeddata\n" ) ;

	char *fptr = strrchr( zipfile, '\\' ) ;
	char *eptr = strrchr( filename, '.' ) ;
	char *gptr = strrchr( zipfile, '.' ) ;

	if ( gptr )
		*gptr = 0 ;

	if ( fptr )
	{
		sprintf( newfilename, "X:\\%s%s", fptr+1,eptr  ) ;
	}
	else
	{
		sprintf( newfilename, "X:\\%s%s", zipfile,eptr  ) ;
	}

	sprintfx( "newfile %s\n", newfilename );

	FILE *outfile = fopen( newfilename, "wb") ;

	if ( outfile )
	{
		sprintfx( "opened file %s\n", newfilename );
		fwrite( data, 1, info.uncompressed_size, outfile ) ;
		fclose( outfile ) ;
	}

	free(data) ;


	return 1;
}
#endif
int CXBoxSample::rom_load_zip( char *hugozipfile )
{
	return 1;
}

void emuSpecificVirtualMem()
{
}
