#ifdef _DEBUG
#define MEDNA_NES 1
#define MEDNA_PCE 2
#define MEDNA_LYNX 3
#define MEDNA_TYPE MEDNA_NES
#endif

#if MEDNA_TYPE == MEDNA_NES
#define LIGHTGUN 1
#define DEBUG_MOUSE 
#define GAME_GENIE 1
//#define NORELOADGENIE
#endif

#if MEDNA_TYPE == MEDNA_PCE
#define LAUNCHABLE_MEDIA
#define DEBUG_MOUSE 
#endif

//#define NESFKB
#define NOREWIND
#define KEYBOARDMENU 0
#define STATEMEM_SIZE 0x10000
#define BOOTXBOX
#define FLOATSTICK
#define NATIVEASPECT
#define CHECKGAMESCREENSIZE
#define CHECKRUMBLECHEATS
#define CHECKAVAILROMS
#define EMU_VERSION 2
#define SHOWFPS
#define MP3CDDA
#define NEWSAVEPOS2
#define RELAXCASE
#define CHEAT5000
#define FRSPRITES
#define XBOX_COMPAT_NAME
#define SAVE_SCREENSTATE
#define CHECKED_RESET_FLICKER
#define CHECKED_RESET_SOFTEN
#define HARDFILTER_APPLY
#define NO_EXTRA_ZIP
//#define USE_DEBUGCLIENT

#define GIT_VSUNI 1
#define GIT_FDS   2

#include <XBApp.h>
#include <XBFont.h>
#include <XBHelp.h>
#include <XBSound.h>
#include <xgraphics.h>
#include <assert.h>
#include <d3d8perf.h>
#include "SndXBOX.hxx"
#include "CDDAXbox.h"
#include <stdio.h>
#include <vector>
#include "zlib.h"
#include "debugclient.h"
#include "Mp3Player2.h"
#include "undocumented.h"
#include "iosupport.h"
#include "panel.h"
#include "fonthelper.h"
#include "plaything.h"
#include "smb++.h"
#include "custom_launch_params.h"
#include "colormap.h"
#include "arrow.h"
#include "numpad.h"
#include "numpadg.h"
//#include "numpadsegag.h"
#include "png.h"
//#include "SDL.h"
#include "lightgun.h"
#include "gamescreen.h"
#include "keyboard_api.h"
#include "relax.h"
#include <cdio/cdio.h>

#if MEDNA_TYPE == MEDNA_NES
#include "mouse.h"
#endif

#if MEDNA_TYPE == MEDNA_PCE
#include "mouse.h"
#endif

#define NEED_CDDA
//#define USE_DEBUGCLIENT
//#define GAME_GENIE

int vkey_to_fkb[256] ;

void MDFNI_EnableStateRewind(int enable);
void MDFNI_DoRewind(void);
void MD_SaveState( char *fname );
void MD_LoadState( char *fname );

void MDFNI_Reset() ;
int MDFNI_FDSInsert( int oride ) ;
void MDFNI_FDSSelect() ;
void MDFNI_VSUniCoin() ;
void MDFNI_VSUniToggleDIP( int which ) ;
void MDFNI_Reset() ;
int cdrfile_read_xbox_audio_sector( int track, unsigned int lsn, unsigned char *buf );

extern unsigned char fkbkeys[0x48];

int g_rewind_enabled ;
int   m_mouseX, m_mouseY, m_mouseButtons ;
char m_pcemouseX, m_pcemouseY ;

unsigned char *g_ROM ;
unsigned int g_ROMsize ;

unsigned char g_cdr_readmethod = 0 ;

unsigned char *getNESWRAM();
unsigned int getNESWRAMSize();

unsigned char* getLynxRAM();
int mednafen_main(char *filename, unsigned int loadcd ) ;
extern signed char CDDAStatus ;
unsigned int getSystemType();

#ifdef __cplusplus
extern "C" {
#endif
#include "unzip.h"

extern unsigned char SYSCARD1[];
extern unsigned char SYSCARD3[];


int throttle ;
int throttling ;
int sounddanger ;
int loaded_cue ;
int blittermode ;
int changedblit ;
int multiport =0;
int sleepamount ;

#include "writepng.h"

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) ;
#define INSIDE_XBOX
//#include "pce.h"
#undef INSIDE_XBOX

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

//_CRTIMP extern int * __cdecl _errno(void);
char gxmsg[2000] ;
//extern char *psxM;

int errno ;

#ifdef __cplusplus
}
#endif

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

extern unsigned char CDRAM[262144];
extern unsigned char BaseRAM[32768];
extern unsigned char RAM[0x800];
unsigned char *lynxRAM = NULL ;




#define PLAYTHING_INI "plaything.cfg"
#define CD_BUF_SECTORS 10
#define CD_DATA_BUFFER_SIZE CD_BUF_SECTORS*2352
#define MLINE(x) ((float)( 80 + (( pmenuParams->lineHeight-2 ) * (x)) ))
#define PROJECTILE_DEF 4 
#define DEFAULT_SKIN_DIR "D:\\EMUSKINS"
#define EMU_RECORDING_SIZE ( sizeof(DWORD)*4*60*60*10 )
#define CD_SECS 60
#define CD_FRAMES 75
#define PLATFORM_MEMORY_POINTER RAM
#define PLATFORM_FILE_DIR m_defaultRomDir
//unsigned int g_console_memory_size = 0x58800 ;
#define CONSOLE_MEMORY_SIZE 0x60800 

#if MEDNA_TYPE == MEDNA_NES

	char *ASPECT_RATIO_NAMES[] = { "None", "Default (Best)", "NES-TV", "NES-Native", "NES-256x224" } ;
	float ASPECT_RATIOS[] = { 1.0f, 1.0f, 320.0/240.0, 256.0/240.0 , 256.0/224.0} ;
	#define NUM_ASPECT_RATIOS 5
	#define PLATFORM_NAME "NES"
	#define PLATFORM_INI "mednafenx_nes.ini"
	#define DEFAULT_PARENT_DIR "D:\\nesroms\\*"
	#define DEFAULT_SKIN "default_mednafenx_nes"
	#define DEFAULT_SAVE_PATH "E:\\SAVES\\MEDNAFENX_NES"
	#define MAIN_MENU_STRING L"MednafenX (NES) Main Menu"
	#define DEFAULT_PATTERN_X 256
	#define DEFAULT_PATTERN_Y 224

#elif MEDNA_TYPE == MEDNA_PCE

	char *ASPECT_RATIO_NAMES[] = { "None", "Default (Best)", "PCE-TV" } ;
	float ASPECT_RATIOS[] = { 1.0f, 1.0f, 320.0/240.0 } ;
	#define NUM_ASPECT_RATIOS 3
	#define PLATFORM_NAME "PCE"
	#define PLATFORM_INI "mednafenx_pce.ini"
	#define DEFAULT_PARENT_DIR "D:\\pceroms\\*"
	#define DEFAULT_SKIN "default_mednafenx_pce"
	#define DEFAULT_SAVE_PATH "E:\\SAVES\\MEDNAFENX_PCE"
	#define MAIN_MENU_STRING L"MednafenX (PCE) Main Menu"
	#define DEFAULT_PATTERN_X 256
	#define DEFAULT_PATTERN_Y 232

#elif MEDNA_TYPE == MEDNA_LYNX

	char *ASPECT_RATIO_NAMES[] = { "None", "Default (Best)", "Lynx", "Lynx-Rotated" } ;
	float ASPECT_RATIOS[] = { 1.0f, 1.0f, 160.0/102.0, 102.0/160.0 } ;
	#define NUM_ASPECT_RATIOS 4
	#define PLATFORM_NAME "LYNX"
	#define PLATFORM_INI "mednafenx_lynx.ini"
	#define DEFAULT_PARENT_DIR "D:\\lynxroms\\*"
	#define DEFAULT_SKIN "default_mednafenx_lynx"
	#define DEFAULT_SAVE_PATH "E:\\SAVES\\MEDNAFENX_LYNX"
	#define MAIN_MENU_STRING L"MednafenX (Lynx) Main Menu"
	#define DEFAULT_PATTERN_X 160
	#define DEFAULT_PATTERN_Y 102

#else
#error no medna_type defined
#endif



unsigned char *m_memory_locations[] = { RAM, BaseRAM, CDRAM, lynxRAM, NULL  } ;
unsigned int  m_memory_sizes[] = { 0x800, 0x8000, 0x40000, 0x10000, 0 } ;

unsigned int g_num_memory_locations = 4 ;

#define NUM_MEMORY_LOCATIONS g_num_memory_locations

int CODE_LENGTHS[] = { 12 } ;

byte keyboard_keystate[256] ;


#define PACKED

#pragma pack(1)

typedef struct
{
  BYTE rsvd;
  BYTE ADR;
  BYTE trackNumber;
  BYTE rsvd2;
  BYTE addr[4];
}
PACKED TOCTRACK;

typedef struct
{
  WORD tocLen;
  BYTE firstTrack;
  BYTE lastTrack;
  TOCTRACK tracks[100];
}
PACKED TOC, *PTOC, FAR * LPTOC;

#pragma pack()

#define METHOD_BUFFERED                   0
#define METHOD_OUT_DIRECT     2
//#define FILE_READ_ACCESS                  0x00000001
#define FILE_DEVICE_CD_ROM                0x00000002

#define IOCTL_CDROM_BASE                FILE_DEVICE_CD_ROM
//#define CTL_CODE(DeviceType,Function,Method,Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))

#define IOCTL_CDROM_READ_TOC         CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)

typedef struct {
	unsigned char isdata ;
	DWORD msf ;
	DWORD lsn ;
	DWORD pregap ;
} TRACKINFO ;

TRACKINFO g_perfectTracks[100] ;
DWORD g_numPerfectTracks ;
DWORD g_currentTrack=0 ;

int g_nes_no8lim ;
int g_nes_pal ;
int g_nes_clipsides ;
int g_nes_nofs ;
int g_nes_slstart ;
int g_nes_slend ;
int g_nes_slstartp ;
int g_nes_slendp ;
int g_nes_ntsccol ;
int g_nes_ntsctint ;
int g_nes_ntschue ;
int g_nes_input1 ;
int g_nes_input2 ;
int g_nes_inputfc ;
int g_nes_hackfix;
int g_nes_mapper ;
int g_nes_mirror ;
char g_nes_custom_palette[MAX_PATH] ;
int g_pce_forceus;
int g_pce_forcesgx;
int g_pce_systemcard;
int g_pce_nospritelimit;
int g_pce_ocmultiplier;
int g_pce_controller ;
int g_pce_sherlockhack ;
char g_pce_perfectcue[150] ;
int g_lynx_rotation ;

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 ;
	float        stick_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 ;
	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  loopbgm ;
	int transition ;

	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	JOY_A		  0x01
#define	JOY_B		  0x02
#define	JOY_SELECT	  0x04
#define	JOY_START	  0x08
#define	JOY_UP		  0x10
#define	JOY_RIGHT	  0x20
#define	JOY_DOWN	  0x40
#define	JOY_LEFT	  0x80
#define	JOY_OPTION1   0x100
#define	JOY_OPTION2   0x200
#define INSERT_FDS    0x400
#define CHANGE_FDS    0x800
#define VSUNI_COIN    0x1000
#define JOY_RESET     0x2000
#define TOGGLE_REWIND 0x4000
#define DOREWIND      0x8000
#define VSUNIDIP0     0x10000
#define VSUNIDIP1     0x20000
#define VSUNIDIP2     0x40000
#define VSUNIDIP3     0x80000
#define VSUNIDIP4     0x100000
#define VSUNIDIP5     0x200000
#define VSUNIDIP6     0x400000
#define VSUNIDIP7     0x800000
#define JOY_3         0x1000000
#define JOY_4         0x2000000
#define JOY_5         0x4000000
#define JOY_6         0x8000000

#define	POWERPAD1	  0x01
#define	POWERPAD2     0x02
#define	POWERPAD3	  0x04
#define	POWERPAD4	  0x08
#define	POWERPAD5	  0x10
#define	POWERPAD6	  0x20
#define	POWERPAD7	  0x40
#define	POWERPAD8	  0x80
#define POWERPAD9     0x1000000
#define POWERPAD10    0x2000000
#define POWERPAD11    0x4000000
#define POWERPAD12    0x8000000

#define	HYPERSHOT1_RUN	    0x01
#define	HYPERSHOT1_JUMP		0x02
#define	HYPERSHOT2_RUN		0x04
#define	HYPERSHOT2_JUMP		0x08

#define	QUIZKING1	  0x01
#define	QUIZKING2	  0x02
#define	QUIZKING3	  0x10
#define	QUIZKING4	  0x20
#define	QUIZKING5	  0x40
#define	QUIZKING6	  0x80

#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'

	BUTTON_DEFINITION g_emuButtonDefinitions[] = {
		{ "A", JOY_A },
		{ "B", JOY_B },
		{ "Up", JOY_UP },
		{ "Down", JOY_DOWN },
		{ "Left", JOY_LEFT },
		{ "Right", JOY_RIGHT },
		{ "Start", JOY_START },
		{ "Select", JOY_SELECT },
		{ "Option 1", JOY_OPTION1 },
		{ "Option 2", JOY_OPTION2 },
		{ "Up-Analog", JOY_UP },
		{ "Down-Analog", JOY_DOWN },
		{ "Left-Analog", JOY_LEFT },
		{ "Right-Analog", JOY_RIGHT },
		{ "Nothing", 0 },
		{ "Insert/Eject FDS Disk", INSERT_FDS },
		{ "Select FDS Disk", CHANGE_FDS },
		{ "Insert Coin", VSUNI_COIN },
		{ "Reset", JOY_RESET },
		{ "VSUNI DIP0 Toggle", VSUNIDIP0 },
		{ "VSUNI DIP1 Toggle", VSUNIDIP1 },
		{ "VSUNI DIP2 Toggle", VSUNIDIP2 },
		{ "VSUNI DIP3 Toggle", VSUNIDIP3 },
		{ "VSUNI DIP4 Toggle", VSUNIDIP4 },
		{ "VSUNI DIP5 Toggle", VSUNIDIP5 },
		{ "VSUNI DIP6 Toggle", VSUNIDIP6 },
		{ "VSUNI DIP7 Toggle", VSUNIDIP7 },
		{ "Nothing", 0 },
		{ "PCE Button 3", JOY_3 },
		{ "PCE Button 4", JOY_4 },
		{ "PCE Button 5", JOY_5 },
		{ "PCE Button 6", JOY_6 },
		{ "Nothing", 0 },
		{ "Turn On/Off Rewind", TOGGLE_REWIND },
		{ "Rewind", DOREWIND },
		{ "Nothing", 0 },
		{ "PowerPad #1", POWERPAD1 },
		{ "PowerPad #2", POWERPAD2 },
		{ "PowerPad #3", POWERPAD3 },
		{ "PowerPad #4", POWERPAD4 },
		{ "PowerPad #5", POWERPAD5 },
		{ "PowerPad #6", POWERPAD6 },
		{ "PowerPad #7", POWERPAD7 },
		{ "PowerPad #8", POWERPAD8 },
		{ "PowerPad #9", POWERPAD9 },
		{ "PowerPad #10", POWERPAD10 },
		{ "PowerPad #11", POWERPAD11 },
		{ "PowerPad #12", POWERPAD12 },
		{ "Hypershot #1 - Run", HYPERSHOT1_RUN },
		{ "Hypershot #1 - Jump", HYPERSHOT1_JUMP },
		{ "Hypershot #2 - Run", HYPERSHOT2_RUN },
		{ "Hypershot #2 - Jump", HYPERSHOT2_JUMP },
		{ "Quiz King Buzzer #1", QUIZKING1 } ,
		{ "Quiz King Buzzer #2", QUIZKING2 } ,
		{ "Quiz King Buzzer #3", QUIZKING3 } ,
		{ "Quiz King Buzzer #4", QUIZKING4 } ,
		{ "Quiz King Buzzer #5", QUIZKING5 } ,
		{ "Quiz King Buzzer #6", QUIZKING6 } ,
#ifdef NESFKB
		{ "Space", 0x80000000 | VK_SPACE },
		{ "Enter", 0x80000000 | VK_RETURN },
		{ "Escape", 0x80000000 | VK_ESCAPE },

		{ "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' },

		{ "F1", 0x80000000 | VK_F1 },
		{ "F2", 0x80000000 | VK_F2 },
		{ "F3", 0x80000000 | VK_F3 },
		{ "F4", 0x80000000 | VK_F4 },
		{ "F5", 0x80000000 | VK_F5 },
		{ "F6", 0x80000000 | VK_F6 },
		{ "F7", 0x80000000 | VK_F7 },
		{ "F8", 0x80000000 | VK_F8 },
		{ "Cursor Up", 0x80000000 | VK_UP },
		{ "Cursor Down", 0x80000000 | VK_DOWN },
		{ "Cursor Left", 0x80000000 | VK_LEFT },
		{ "Cursor Right", 0x80000000 | VK_RIGHT },

		{ "Comma", 0x80000000 | VK_OEM_COMMA },
		{ "Period", 0x80000000 | VK_OEM_PERIOD },
		{ "/", 0x80000000 | VK_OEM_2 },
		{ "\\", 0x80000000 | VK_OEM_5 },
		{ "[", 0x80000000 | VK_OEM_4 },
		{ "]", 0x80000000 | VK_OEM_6 },
		{ "SemiColon", 0x80000000 | VK_OEM_1 },  //FKB_SEMICOLON
		{ "'", 0x80000000 | VK_OEM_7 },  //FKB_COLON
		{ "Minus", 0x80000000 | VK_OEM_MINUS },  //FKB_MINUS
		{ "=", 0x80000000 | VK_OEM_PLUS }, //FKB_UNDERSCORE
		{ "Delete", 0x80000000 | VK_DELETE },
		{ "Insert", 0x80000000 | VK_INSERT },
		{ "Left Shift", 0x80000000 | VK_LSHIFT },
		{ "Right Shift", 0x80000000 | VK_RSHIFT },
		{ "Control", 0x80000000 | VK_LCONTROL }, //FKB_CONTROL
		{ "Control", 0x80000000 | VK_RCONTROL }, //FKB_CONTROL

		{ "Caret", 0x80000000 | VK_MULTIPLY },  //FKB_CARET
		{ "Stop", 0x80000000 | VK_ADD }, //FKB_STOP
		{ "At", 0x80000000 | VK_SUBTRACT }, //FKB_AT  
		{ "Kana", 0x80000000 | VK_DECIMAL }, //FKB_KANA
		{ "Graph", 0x80000000 | VK_DIVIDE }, //FKB_GRAPH
		{ "Clear", 0x80000000 | VK_SEPARATOR}, //FKB_CLEAR
#endif
		{ "Nothing", 0 },
	} ;

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


#define DEFAULT_BUTTON1  XBOX_A
#define DEFAULT_BUTTON2  XBOX_X
#define DEFAULT_BUTTON3  XBOX_DPAD_UP
#define DEFAULT_BUTTON4  XBOX_DPAD_DOWN
#define DEFAULT_BUTTON5  XBOX_DPAD_LEFT
#define DEFAULT_BUTTON6  XBOX_DPAD_RIGHT
#define DEFAULT_BUTTON7  XBOX_START
#define DEFAULT_BUTTON8  XBOX_BACK
#define DEFAULT_BUTTON9  XBOX_B
#define DEFAULT_BUTTON10 XBOX_Y
#define DEFAULT_BUTTON11 XBOX_LTHUMB_UP
#define DEFAULT_BUTTON12 XBOX_LTHUMB_DOWN
#define DEFAULT_BUTTON13 XBOX_LTHUMB_LEFT
#define DEFAULT_BUTTON14 XBOX_LTHUMB_RIGHT
#define DEFAULT_BUTTON15 0
#define DEFAULT_BUTTON16 XBOX_WHITE
#define DEFAULT_BUTTON17 XBOX_BLACK
#define DEFAULT_BUTTON18 XBOX_Y
//button19 = reset
#define DEFAULT_BUTTON19 XBOX_LEFT_THUMB+XBOX_BACK
#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
#if MEDNA_TYPE == MEDNA_PCE
#define DEFAULT_BUTTON29 XBOX_B
#define DEFAULT_BUTTON30 XBOX_Y
#define DEFAULT_BUTTON31 XBOX_BLACK
#define DEFAULT_BUTTON32 XBOX_WHITE
#else
#define DEFAULT_BUTTON29 0
#define DEFAULT_BUTTON30 0
#define DEFAULT_BUTTON31 0
#define DEFAULT_BUTTON32 0
#endif

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 ;


//int errno ;

//-----------------------------------------------------------------------------
// 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( ) ;
	virtual int     handleEvents() ;
	virtual void	handleScreenKeyboard( );
	virtual int     init_texture() ;
	virtual BOOL    SetRefreshRate(INT iRefreshRate);
	virtual int		init_white_texture();
	virtual int		render_to_texture( unsigned char *buf, int w, int h, int spitch, int systype, int wx, int wy) ;
	virtual void	FindAvailRoms(char *dir) ;
	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 void    doCodeListMenu() ;
	virtual int     receiveNetworkData( );
	virtual void    xboxStartRecording() ;
	virtual void    xboxStopRecording() ;
	virtual void    xboxStartPlaying() ;
	virtual void    xboxStopPlaying() ;
	virtual void    xboxOptionsMenu() ;
	virtual void    doChangeVideoMode() ;
	virtual void    doSelectTransition() ;
	virtual void    doChangeHWFilter() ;
	virtual void    doChangeSWFilter() ;
	virtual void    doPlaythingClear( );
#ifdef LIGHTGUN
	virtual int     doZapper();
	virtual void    doCalibrateLightgun( bool changeValues) ;
	virtual void	doConfigureLightgun() ;
#endif
	virtual void    saveSettings( char *filename );
	virtual int     loadSettings( char *filename );
	virtual void    doAutofireConfig( int port );
	virtual void    doMainMenu() ;
	void            renderScreenKeyboard( );
	virtual void    getKeyboardString( char *buf, int bufsize ) ;
	void            musicControlMenu( CPanel *panel );
	void            doDefaultDirs();
	virtual void    copyOldSaves();
	virtual int     validateCode( char *code, CHEAT_CODE *ccode, int codetype ) ;
	virtual void    checkGeneralEvents() ;
	virtual void    loadControllerSettings( char *buf ) ;
	virtual void    saveControllerSettings( FILE *outfile ) ;
	virtual void    doManageCheatCode( int selected );
	virtual void	doRumbleConfigSelect( int port );
	virtual void	doRumbleConfig( void *rumble );
	virtual void    doConfigureSkin() ;
	virtual int     addGameGenieCode() ;
	virtual void    applyGameGenie( byte *ROM, unsigned int romsize);
	virtual int     encodeGameGenie( CHEAT_CODE *code ) ;
	virtual int     decodeGameGenie( CHEAT_CODE *code ) ;
	virtual void    doEditGameGenie( int selected ) ;
	virtual void    doBrowseScreenshots( ) ;
	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    doGraphicsFiltering() ;
	virtual void    doSelectColor( DWORD *pColor, MENU_PARAMS *menuParams );
	virtual void    doTransition( CPanel *pnl1, CPanel *pnl2, int speed, int effect ) ;
	virtual void	viewCheatMatches();
	virtual void	viewMemoryDump( unsigned int offset );
	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    doConfigureGame( char *settingsfile, char *keysfile ) ;
	virtual void    SetupPlaything( );
	virtual void    loadCueSheet( char *cuefile ) ;
	virtual void    doSelectBackground( char *bkgfile, CPanel *ppanel ) ;
	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 ) ;
	void            loadMostRecentSaveState( );
	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    updateEmuSpecificCheats() ;
	virtual void    doSavePlaything() ;
	virtual int     setupNetplay() ;
	virtual void    doLoadPlaything() ;
	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    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 ) ;
	virtual void    doAddFoundCodes() ;
	virtual void    doContinueSearchMenu() ;
	virtual void    doCodeListMenu2() ;
	virtual void    selectPerfectCue() ;
	virtual int     pollXBoxControllers( );
	virtual int     pollNetworkControllers( );
	virtual void    doAddFoundCodes2() ;
	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    doFontSize() ;
	virtual void    xboxSaveState() ;
	virtual void    xboxThrottle( int throttle ) ;
	virtual void    xboxLoadState() ;
	virtual void    xboxChangeFilter() ;
	virtual void    xboxScreenshot() ;
	virtual void    xboxChangeState() ;
	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 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 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 void    doLoadNewDisk();
	virtual void    doGraphicsFixes();
	virtual void    doCPUFixes();
	void            ClearScreen() ;
	void            doSelectMemcards();
	virtual void    doCDGame( ) ;
	virtual void    doConfiguration() ;
	virtual void    updateCheats() ;
	virtual void    updateCheats2() ;
	virtual void    processEmu( BOOL render ) ;
	virtual void    fillPresentationParams() ;
	virtual void    ggenie_init() ;
	virtual void    cht_load() ;
	virtual void    cht_save() ;
	virtual void    doUtilities( );
	virtual void    doHelp( );
	virtual void	createLocal( char *filename, char *newfilename, char* zipfilename, int *zipnumber );
	virtual int     handleExtension( char *ext, char *zipfile, char *newfilename, int *zipnumber );
	virtual int		selectFile( char *filename, char *dirname, int canchangedir, int selectdir, int refreshlist, int initlist  );
	virtual void	doSettings2();
	virtual	void	editPlaylist( char *filename );
	virtual void	managePlaylists( );
	virtual void	viewPlaylist( );
	virtual void	applyHardwareFilter( ) ;
	virtual void	viewTextFile( char *filename ) ;
	virtual void    doSettings( );
	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 ) ;
	void			ColorBar( int xpos, int ypos, int xlen, int ylen, DWORD color ) ;

	/*
typedef struct
    {
     unsigned char beg_min;
     unsigned char beg_sec;
     unsigned char beg_fra;

     unsigned char type;

     unsigned int beg_lsn;
     unsigned int length;

     char filename[256];


     } Track;*/
	//Track CD_track[0x100];
	//int   nb_max_track ;
	

	int m_systemCard ;
	int m_forceUS ;
	int m_countryCode ;
	int m_cdMethod ;

	D3DCOLOR			m_color_palette[256];

	DWORD m_xboxControllers[4] ;
	DWORD m_prevEmuControllers[4] ;
	DWORD m_emuControllers[4] ;
	DWORD m_networkEmuControllers[4] ;
	DWORD m_networkStatus ;
	NETPLAY_SERVER m_netplayServers[32] ;
	char m_screenshotDir[MAX_PATH] ;
	int m_defaultScreenshots ;

	int m_changedGenie ;

	D3DXVECTOR2 m_gameVecScale ; 
	D3DXVECTOR2 m_gameVecTranslate ; 
	RECT m_gameRectSource ;

	CRelax m_relaxTracks[102] ;
	SMB m_smb;
	Util m_smbUtil ;
	int m_stateNumber ;
	int  m_smbCdFile ;
	int  m_bUsingSamba ;
	int m_xboxHFilter ;
	int m_xboxSFilter ;
	char m_smbShare[500] ;
	float m_fFrameTime ;
	UINT32 m_numFrames ;
	DWORD m_startTime ;
	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_biosMode ;
	unsigned int m_vandalFix ;
	unsigned int m_psxfix_Xa ;
	unsigned int m_psxfix_Sio ;
	unsigned int m_psxfix_Mdec ;
	unsigned int m_psxfix_Cdda ;
	unsigned int m_psxfix_Cpu ;
	unsigned int m_psxfix_SpuIrq ;
	unsigned int m_psxfix_VSyncWA ;
	CXBSocket m_sockListener ;
	CDebugClient m_sockNetplay;
	int       m_bNetplay ;
	unsigned int m_bNetworkCD ;
	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 ;
	CDDAXbox m_cdda ;
	int m_zapperDat[3] ;

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


	D3DLOCKED_RECT g_d3dlr;    
	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 ;

	CFontHelper m_Font ;

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

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


	FILENAME *files ;
	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 ;
	TOC m_toc;
	unsigned char m_cdbuffer[2352*4] ;
	gzFile m_cdfile ;
	unsigned char m_memcard1[MAX_PATH] ;
	unsigned char m_memcard2[MAX_PATH] ;
	int m_memcardnum1, m_memcardnum2 ;
	unsigned char m_biosfile[100] ;


	LPDIRECT3DTEXTURE8	m_pd3dBackgroundTexture;
	LPDIRECT3DTEXTURE8	Texture;
	LPDIRECT3DTEXTURE8	WhiteTexture;
	LPD3DXSPRITE			Sprite;
	LPD3DXSPRITE			MenuSprite;
	byte*				g_pBlitBuff ;
	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_savedir[500] ;
	char				g_sramfile[500] ;
	char				g_fdsfile[500] ;
	char				g_cuefile[500] ;
	char				g_bramfile[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 ;


};

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_nXOffset = GetIniInt( szbuf, "GENERAL", "TEXT_OFFSET_X", 0 ) ;

}

void CXBoxSample::doSaveEmuSpecificIni( FILE *outfile ) 
{



}


int CXBoxSample::init_texture()
{
	// Release any previous texture
	if (Texture) 
	{ 
		return 1 ;
		Texture->BlockUntilNotBusy() ;
		Texture->Release();
		Texture = NULL;
	}
	
	theWidth = (320+64+40)*2 ;
	theHeight = 256*2 ;

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

	//D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &Texture);
//	D3DXCreateTexture(m_pd3dDevice, theWidth, theHeight, 0, 0, D3DFMT_X1R5G5B5, D3DPOOL_DEFAULT, &Texture);
	
	//Init_2xSaI( 555 ) ;

	//if ( FAILED(m_pnlGameScreen.Create( m_pd3dDevice, Texture ) ) )
	//{
		//sprintfx( "failed create game screen\r\n") ;
	//}
	


	D3DSURFACE_DESC desc;
    Texture->GetLevelDesc(0, &desc);

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


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

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

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



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


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


	m_color_palette[255] = 0xFFFFFFFF ;


	int r, g, b;
	for (int i = 0; i < 255; i++)
	{
		r = (i & 0x1C)  ;
		g = (i & 0xe0) >> 2 ;
		b = (i & 0x03) << 3 ;

		//r = (256*r) / 56 ;
		//g = (256*g) / 56 ;
		//b = (256*b) / 48 ;
		m_color_palette[i] = 	( (r) << 11 ) | ( (g) << 5 ) | (b)  ;
	}

	//m_pd3dPalette->Unlock() ;

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


	return 0;
}


unsigned int xbox_get_freemem()
{
	MEMORYSTATUS stat;

	GlobalMemoryStatus( &stat );
	return stat.dwAvailPhys ;
}

unsigned long TAB_CONST2[256] = {
   0X0,
   0X77073096,
   0XEE0E612C,
   0X990951BA,
   0X76DC419,
   0X706AF48F,
   0XE963A535,
   0X9E6495A3,
   0XEDB8832,
   0X79DCB8A4,
   0XE0D5E91E,
   0X97D2D988,
   0X9B64C2B,
   0X7EB17CBD,
   0XE7B82D07,
   0X90BF1D91,
   0X1DB71064,
   0X6AB020F2,
   0XF3B97148,
   0X84BE41DE,
   0X1ADAD47D,
   0X6DDDE4EB,
   0XF4D4B551,
   0X83D385C7,
   0X136C9856,
   0X646BA8C0,
   0XFD62F97A,
   0X8A65C9EC,
   0X14015C4F,
   0X63066CD9,
   0XFA0F3D63,
   0X8D080DF5,
   0X3B6E20C8,
   0X4C69105E,
   0XD56041E4,
   0XA2677172,
   0X3C03E4D1,
   0X4B04D447,
   0XD20D85FD,
   0XA50AB56B,
   0X35B5A8FA,
   0X42B2986C,
   0XDBBBC9D6,
   0XACBCF940,
   0X32D86CE3,
   0X45DF5C75,
   0XDCD60DCF,
   0XABD13D59,
   0X26D930AC,
   0X51DE003A,
   0XC8D75180,
   0XBFD06116,
   0X21B4F4B5,
   0X56B3C423,
   0XCFBA9599,
   0XB8BDA50F,
   0X2802B89E,
   0X5F058808,
   0XC60CD9B2,
   0XB10BE924,
   0X2F6F7C87,
   0X58684C11,
   0XC1611DAB,
   0XB6662D3D,
   0X76DC4190,
   0X1DB7106,
   0X98D220BC,
   0XEFD5102A,
   0X71B18589,
   0X6B6B51F,
   0X9FBFE4A5,
   0XE8B8D433,
   0X7807C9A2,
   0XF00F934,
   0X9609A88E,
   0XE10E9818,
   0X7F6A0DBB,
   0X86D3D2D,
   0X91646C97,
   0XE6635C01,
   0X6B6B51F4,
   0X1C6C6162,
   0X856530D8,
   0XF262004E,
   0X6C0695ED,
   0X1B01A57B,
   0X8208F4C1,
   0XF50FC457,
   0X65B0D9C6,
   0X12B7E950,
   0X8BBEB8EA,
   0XFCB9887C,
   0X62DD1DDF,
   0X15DA2D49,
   0X8CD37CF3,
   0XFBD44C65,
   0X4DB26158,
   0X3AB551CE,
   0XA3BC0074,
   0XD4BB30E2,
   0X4ADFA541,
   0X3DD895D7,
   0XA4D1C46D,
   0XD3D6F4FB,
   0X4369E96A,
   0X346ED9FC,
   0XAD678846,
   0XDA60B8D0,
   0X44042D73,
   0X33031DE5,
   0XAA0A4C5F,
   0XDD0D7CC9,
   0X5005713C,
   0X270241AA,
   0XBE0B1010,
   0XC90C2086,
   0X5768B525,
   0X206F85B3,
   0XB966D409,
   0XCE61E49F,
   0X5EDEF90E,
   0X29D9C998,
   0XB0D09822,
   0XC7D7A8B4,
   0X59B33D17,
   0X2EB40D81,
   0XB7BD5C3B,
   0XC0BA6CAD,
   0XEDB88320,
   0X9ABFB3B6,
   0X3B6E20C,
   0X74B1D29A,
   0XEAD54739,
   0X9DD277AF,
   0X4DB2615,
   0X73DC1683,
   0XE3630B12,
   0X94643B84,
   0XD6D6A3E,
   0X7A6A5AA8,
   0XE40ECF0B,
   0X9309FF9D,
   0XA00AE27,
   0X7D079EB1,
   0XF00F9344,
   0X8708A3D2,
   0X1E01F268,
   0X6906C2FE,
   0XF762575D,
   0X806567CB,
   0X196C3671,
   0X6E6B06E7,
   0XFED41B76,
   0X89D32BE0,
   0X10DA7A5A,
   0X67DD4ACC,
   0XF9B9DF6F,
   0X8EBEEFF9,
   0X17B7BE43,
   0X60B08ED5,
   0XD6D6A3E8,
   0XA1D1937E,
   0X38D8C2C4,
   0X4FDFF252,
   0XD1BB67F1,
   0XA6BC5767,
   0X3FB506DD,
   0X48B2364B,
   0XD80D2BDA,
   0XAF0A1B4C,
   0X36034AF6,
   0X41047A60,
   0XDF60EFC3,
   0XA867DF55,
   0X316E8EEF,
   0X4669BE79,
   0XCB61B38C,
   0XBC66831A,
   0X256FD2A0,
   0X5268E236,
   0XCC0C7795,
   0XBB0B4703,
   0X220216B9,
   0X5505262F,
   0XC5BA3BBE,
   0XB2BD0B28,
   0X2BB45A92,
   0X5CB36A04,
   0XC2D7FFA7,
   0XB5D0CF31,
   0X2CD99E8B,
   0X5BDEAE1D,
   0X9B64C2B0,
   0XEC63F226,
   0X756AA39C,
   0X26D930A,
   0X9C0906A9,
   0XEB0E363F,
   0X72076785,
   0X5005713,
   0X95BF4A82,
   0XE2B87A14,
   0X7BB12BAE,
   0XCB61B38,
   0X92D28E9B,
   0XE5D5BE0D,
   0X7CDCEFB7,
   0XBDBDF21,
   0X86D3D2D4,
   0XF1D4E242,
   0X68DDB3F8,
   0X1FDA836E,
   0X81BE16CD,
   0XF6B9265B,
   0X6FB077E1,
   0X18B74777,
   0X88085AE6,
   0XFF0F6A70,
   0X66063BCA,
   0X11010B5C,
   0X8F659EFF,
   0XF862AE69,
   0X616BFFD3,
   0X166CCF45,
   0XA00AE278,
   0XD70DD2EE,
   0X4E048354,
   0X3903B3C2,
   0XA7672661,
   0XD06016F7,
   0X4969474D,
   0X3E6E77DB,
   0XAED16A4A,
   0XD9D65ADC,
   0X40DF0B66,
   0X37D83BF0,
   0XA9BCAE53,
   0XDEBB9EC5,
   0X47B2CF7F,
   0X30B5FFE9,
   0XBDBDF21C,
   0XCABAC28A,
   0X53B39330,
   0X24B4A3A6,
   0XBAD03605,
   0XCDD70693,
   0X54DE5729,
   0X23D967BF,
   0XB3667A2E,
   0XC4614AB8,
   0X5D681B02,
   0X2A6F2B94,
   0XB40BBE37,
   0XC30C8EA1,
   0X5A05DF1B,
   0X2D02EF8D
};




void CXBoxSample::doCPUFixes()
{
	int menuChoice = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu) ;

		swprintf( m_menuText[0], L"Set CPU Fixes" );

		swprintf( m_menuText[1], L"Parasite Eve/Vandal Heart fix" ) ; 
		swprintf( m_menuText[3], L"Disable XA sound processing" ) ; 
		swprintf( m_menuText[5], L"Always enable SIO IRQ" ) ; 
		swprintf( m_menuText[7], L"Black and White movies" ) ; 
		swprintf( m_menuText[9], L"Disable CDDA" ) ; 
		swprintf( m_menuText[11], L"Use CPU interpreter" ) ; 
		swprintf( m_menuText[13], L"Always enable SPU IRQ" ) ; 
		swprintf( m_menuText[15], L"InuYasha Sengoku Battle fix" ) ; 

		swprintf( m_menuText[2], ( m_vandalFix ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[4], ( m_psxfix_Xa ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[6], ( m_psxfix_Sio ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[8], ( m_psxfix_Mdec ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[10], ( m_psxfix_Cdda ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[12], ( m_psxfix_Cpu ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[14], ( m_psxfix_SpuIrq ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[16], ( m_psxfix_VSyncWA ) ? L"On" : L"Off" ) ;

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

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

			m_changedSettings = 1 ;

			switch ( menuChoice )
			{
				case 0 : m_vandalFix = !m_vandalFix ; break ;
				case 1 : m_psxfix_Xa = !m_psxfix_Xa  ; break ;
				case 2 : m_psxfix_Sio = !m_psxfix_Sio  ; break ;
				case 3 : m_psxfix_Mdec = !m_psxfix_Mdec  ; break ;
				case 4 : m_psxfix_Cdda = !m_psxfix_Cdda  ; break ;
				case 5 : m_psxfix_Cpu = !m_psxfix_Cpu  ; break ;
				case 6 : m_psxfix_SpuIrq = !m_psxfix_SpuIrq  ; break ;
				case 7 : m_psxfix_VSyncWA = !m_psxfix_VSyncWA  ; break ;
				default : break ;
			}
		}
	}
}

void CXBoxSample::doGraphicsFixes()
{
	int menuChoice = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu) ;

		swprintf( m_menuText[0], L"Set Graphics Fixes" );

		swprintf( m_menuText[1], L"Odd/even bit hack" ) ; 
		swprintf( m_menuText[3], L"Expand screen width" ) ; 
		swprintf( m_menuText[5], L"Ignore black brightness color" ) ; 
		swprintf( m_menuText[7], L"Disable coord check" ) ; 
		swprintf( m_menuText[9], L"Use low-res fps timer" ) ; 
		swprintf( m_menuText[11], L"Use PC fps calculation" ) ; 
		swprintf( m_menuText[13], L"Lazy screen updates" ) ; 
		swprintf( m_menuText[15], L"Use old frame skipping" ) ; 
		swprintf( m_menuText[17], L"Frameskip" ) ; 
		swprintf( m_menuText[19], L"Framelimit" ) ; 
		swprintf( m_menuText[21], L"Bit Depth" ) ; 

		for ( int i = 0 ; i < 8 ; i++ )
		{
			swprintf( m_menuText[(i*2)+2], ( m_graphicsFixes & ( 1 << i ) ) ? L"On" : L"Off" );
		}

		swprintf( m_menuText[18], ( m_frameskip ) ? L"On" : L"Off" ) ;
		swprintf( m_menuText[20], ( m_framelimit ) ? L"On" : L"Off" ) ; 
		swprintf( m_menuText[22], ( m_bitDepth==16 ) ? L"16" : L"32" ) ; 

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

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

			m_changedSettings = 1 ;

			switch ( menuChoice )
			{
				case 8 : m_frameskip = !m_frameskip ; break ;
				case 9 : m_framelimit = !m_framelimit ; break ;
				case 10 : if ( m_bitDepth == 16 ) m_bitDepth = 16 ; else m_bitDepth = 16 ; break ;
				default : 
					{
						if ( m_graphicsFixes & ( 1 << menuChoice ) )
						{
							m_graphicsFixes &= ~( 1 << menuChoice ) ;
						}
						else
						{
							m_graphicsFixes |= ( 1 << menuChoice ) ;
						}
					}
					break ;
			}
		}
	}
}






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


	//doCDGame( ) ;

	throttling = 0 ;

	initConsole( gameSelected, isFavorite, forceConfig ) ;

	if ( g_autoLaunchGame )
	{
		changeMenu( &m_skin.otherMenu, &m_skin.mainMenu ) ;
		//doTransition( &m_pnlBackgroundOther, &m_pnlBackgroundMain, m_skin.fade, 1 ) ;
	}
	else
	{
		changeMenu( &m_skin.otherMenu, &m_skin.gameSelectMenu ) ;
		//doTransition( &m_pnlBackgroundOther, &m_pnlBackgroundSelect, m_skin.fade, 1 ) ;
	}

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

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

}


void CXBoxSample::selectPerfectCue( )
{
	byte c, *data, *header;
	int len = 0, rlen;
	int menuChoice = 0 ;
	int numlines = 0 ;
	int currnum = 0 ;
	char tempdirname[20] ;
	SYSTEMTIME stime ;

	unzFile file = unzOpen("d:\\pcetoc.zip");

    if(file == NULL)
	{
		popupMsg( "ERROR : Missing D:\\PCETOC.ZIP", &m_pnlBackgroundSelect ) ;
		strcpy( g_pce_perfectcue, "Use My Selected CUE File..lsn" )  ;
		return ;
	}

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

	lines[0] = (WCHAR*)malloc( sizeof(WCHAR) * 40 ) ;

	swprintf( lines[numlines++], L"Select Perfect CD Cue Sheet" ) ;

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

		if ( strrchr(name, '.' ) )
			*strrchr(name,'.') = 0 ;

		lines[numlines] = (WCHAR*)malloc( sizeof(WCHAR) * ( strlen( name ) + 2 ) ) ;
		swprintf( lines[numlines++], L"%S", name ) ;

		port = unzGoToNextFile(file);
    }

	lines[numlines] = (WCHAR*)malloc( sizeof(WCHAR) * ( 40 ) ) ;
	swprintf( lines[numlines++], L"%S", "Use My Selected CUE File." ) ;

    if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) )
    {
		unzClose(file) ;
		popupMsg( "ERROR : Corrupt D:\\PCETOC.ZIP file", &m_pnlBackgroundSelect ) ;

		for ( int i = 0 ; i < numlines ; i++ )
		{
			free( lines[i] ) ;
		}

		strcpy( g_pce_perfectcue, "Use My Selected CUE File..lsn" )  ;
		return ;
    }

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


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


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


	}

	sprintf( g_pce_perfectcue, "%S.lsn", lines[menuChoice+1] ) ;
	strcpy( filename, g_pce_perfectcue ) ;

	for ( int i = 0 ; i < numlines ; i++ )
	{
		free( lines[i] ) ;
	}

    unzLocateFile(file,filename,1);
    unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0);
    
	g_numPerfectTracks = 0 ;

	if( unzOpenCurrentFile(file) != UNZ_OK )
    {
		unzClose(file);

		if ( strcmp( filename, "Use My Selected CUE File..lsn" )  )
			popupMsg( "ERROR : Could not open selected CUE file", &m_pnlBackgroundSelect ) ;
		return ;
    }

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

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

	memset( data, 0, info.uncompressed_size+5 ) ;

	int l = unzReadCurrentFile(file,data,info.uncompressed_size );

	unzCloseCurrentFile(file) ;
    unzClose(file);

	char *line = strtok( (char*)data, "\r\n" ) ;
	unsigned int dummy, min, sec, frame ;

	while ( line && ( strlen(line) > 20 ) )
	{
		sscanf( line, "%d %d %d:%d:%d %d %d", &dummy, &(g_perfectTracks[g_numPerfectTracks].isdata),
			&min, &sec, &frame, &(g_perfectTracks[g_numPerfectTracks].lsn), &(g_perfectTracks[g_numPerfectTracks].pregap) ) ;

		g_perfectTracks[g_numPerfectTracks].msf = (min * 60 * 75 ) + ( sec * 75 ) + frame ;

		g_numPerfectTracks++ ;

		line = strtok( NULL, "\r\n" ) ;
	}


	free(data) ;


	return ;


}


#if MEDNA_TYPE == MEDNA_NES

void CXBoxSample::doConfigureGame( char *settingsname, char *keysname )
{
	int menuChoice ;
	char *countries[] = { "Auto-detect", "Japan", "USA", "Europe", "Other" } ;
	char *controllers[5]={"None","Gamepad","Zapper","Powerpad","Arkanoid"};
	char *expport[11]={"None","Arkanoid","Shadow","4Player","FKB","Hypershot",
                        "Mahjong","QuizKing","FTrainerA","FTrainerB","OekaKids"};
	char *mirrors[4] = { "Horizontal", "Vertical", "One-Screen", "Four-Screen" } ;

	//g_nes_no8lim ;
	//g_nes_pal ;
	//g_nes_clipsides ;
	//g_nes_nofs ;
	//g_nes_slstart ;
	//g_nes_slend ;
	//g_nes_slstartp ;
	//g_nes_slendp ;
	//g_nes_ntsccol ;
	//g_nes_ntsctint ;
	//g_nes_ntschue ;

	g_nes_input1 = 1 ;
	g_nes_input2 = 1 ;
	g_nes_inputfc = 0 ;
	g_nes_mapper = -1 ;
	g_nes_mirror = -1 ;

	menuChoice = 0 ;

	loadSettings( settingsname ) ;
	loadKeys( keysname ) ;


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

	
		swprintf( m_menuText[0], L"Game Configuration" );
		swprintf( m_menuText[1], L"Controller 1 : %S", controllers[g_nes_input1] ) ;
		swprintf( m_menuText[2], L"Controller 2 : %S", controllers[g_nes_input2] ) ;
		swprintf( m_menuText[3], L"Expansion Port Device : %S", expport[g_nes_inputfc] ) ;
		swprintf( m_menuText[4], L"Clip Sides : %S", g_nes_clipsides ? "Yes" : "No" ) ;
		swprintf( m_menuText[5], L"Impose 8 sprites per line limit : %S", g_nes_no8lim ? "No" : "Yes" ) ;
		swprintf( m_menuText[6], L"Video Type : %S", g_nes_pal ? "PAL" : "NTSC"  );
		swprintf( m_menuText[7], L"Hack Fix : %S", g_nes_hackfix ? "Enabled" : "Disabled"  );

		if ( g_nes_mapper < 0 )
			swprintf( m_menuText[8], L"Mapper - AutoDetect");
		else
			swprintf( m_menuText[8], L"Mapper - %u", g_nes_mapper );

		if ( g_nes_mirror < 0 )
			swprintf( m_menuText[9], L"Mirroring - AutoDetect");
		else
			swprintf( m_menuText[9], L"Mirroring - %S", mirrors[g_nes_mirror] );

		swprintf( m_menuText[10], L"Autogenerate NTSC Palette : %S", g_nes_ntsccol ? "Yes" : "No"  );
		swprintf( m_menuText[11], L"Autogenerated NTSC Palette Tint : %u", g_nes_ntsctint  );
		swprintf( m_menuText[12], L"Autogenerated NTSC Palette Hue : %u", g_nes_ntschue  );
		swprintf( m_menuText[131], L"Custom Palette : %S", strrchr( g_nes_custom_palette, '\\' ) ? strrchr( g_nes_custom_palette, '\\' )+1 : "None"  );
		swprintf( m_menuText[14], L"Disable Four-Score Emulation : %S", g_nes_nofs ? "Yes" : "No"  );
		swprintf( m_menuText[15], L"Starting Scanline NTSC : %u", g_nes_slstart  );
		swprintf( m_menuText[16], L"Ending Scanline NTSC : %u", g_nes_slend  );
		swprintf( m_menuText[17], L"Starting Scanline PAL : %u", g_nes_slstartp  );
		swprintf( m_menuText[18], L"Ending Scanline PAL : %u", g_nes_slendp  );
		swprintf( m_menuText[19], L"Change Graphics Filter"  );
		swprintf( m_menuText[20], L"Configure Controllers"  );
		
		
		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 21, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

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

				case 0   : g_nes_input1 = ( g_nes_input1 + 1 )%5 ; break ;
				case 1   : g_nes_input2 = ( g_nes_input2 + 1 )%5 ; break ;
				case 2   : g_nes_inputfc = ( g_nes_inputfc + 1 )%11 ; break ;
				case 3   : g_nes_clipsides = ! g_nes_clipsides ; break ;
				case 4   : g_nes_no8lim = ! g_nes_no8lim ; break ;
				case 5   : g_nes_pal = ! g_nes_pal ; break ;
				case 6   : g_nes_hackfix = ! g_nes_hackfix ; break ;
				case 7   : 
				{
					if ( ( g_nes_mapper >= 0 ) && ( yesNoMenu( "Do you wish to reset to AutoSelect?", &m_pnlBackgroundOther ) == 0 ) )
					{
						g_nes_mapper = -1 ;
					}
					else
					{

						int newval = getValuePopup( "Select Mapper Number", g_nes_mapper<0 ? 0 : g_nes_mapper, 0, 255, &m_pnlBackgroundOther ) ; 
						if ( newval == g_nes_mapper )
							g_nes_mapper = -1 ;
						else
							g_nes_mapper = newval ;
					}
					break ;
				}
				case 8   : 
				{
					switch ( g_nes_mirror )
					{
						case 3 : g_nes_mirror = -1 ; break ;
						default : g_nes_mirror = (g_nes_mirror+1)%4 ; break ;
					}
					break ;
				}
				case 9   : g_nes_ntsccol = ! g_nes_ntsccol ; break ;
				case 10   : g_nes_ntsctint = getValuePopup( "Select NTSC Tint Value", g_nes_ntsctint, 0, 128, &m_pnlBackgroundOther ) ; break ;
				case 11   : g_nes_ntschue = getValuePopup( "Select NTSC Hue Value", g_nes_ntschue, 0, 128, &m_pnlBackgroundOther ) ; break ;
				case 12  : selectFile( g_nes_custom_palette, "", 1, 0, 0, 0 ) ;
				case 13  : g_nes_nofs = ! g_nes_nofs ; break ;
				case 14  : g_nes_slstart = getValuePopup( "NTSC Starting Scanline", g_nes_slstart, 0, 239, &m_pnlBackgroundOther ) ; break ;
				case 15  : g_nes_slend = getValuePopup( "NTSC Ending Scanline", g_nes_slend, 0, 239, &m_pnlBackgroundOther ) ; break ;
				case 16  : g_nes_slstartp = getValuePopup( "PAL Starting Scanline", g_nes_slstartp, 0, 239, &m_pnlBackgroundOther ) ; break ;
				case 17  : g_nes_slendp = getValuePopup( "PAL Ending Scanline", g_nes_slendp, 0, 239, &m_pnlBackgroundOther ) ; break ;
				case 18  : doChangeSWFilter() ; break ;
				case 19  : doConfigureControllers() ; break ;
				default  : break ;
			}
		}


	}

	saveSettings( settingsname ) ;
	saveKeys( keysname ) ;

}

#elif MEDNA_TYPE == MEDNA_PCE

void CXBoxSample::doConfigureGame( char *settingsname, char *keysname )
{
	int menuChoice ;
	char *controllers[] = { "2 Button Pad", "6 Button Pad", "Mouse" } ;

//g_pce_forceus
//g_pce_forcesgx
//g_pce_systemcard
//g_pce_nospritelimit
//g_pce_ocmultiplier

  //{ "pce.forcesgx", "Force SuperGrafx emulation.", MDFNST_BOOL, "0" },
  //{ "pce.ocmultiplier", "CPU overclock multiplier.", MDFNST_UINT, "1", "1", "50"},
  //{ "pce.nospritelimit", "No 16-sprites-per-scanline limit option.", MDFNST_BOOL, "0" },

	menuChoice = 0 ;

	loadSettings( settingsname ) ;
	loadKeys( keysname ) ;

	if ( loaded_cue == 1 )
	{
		if ( g_pce_perfectcue[0] == 0 )
			selectPerfectCue() ;
	}


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

	
		swprintf( m_menuText[0], L"Game Configuration" );
		swprintf( m_menuText[1], L"Force US Mode? : %S", g_pce_forceus ? "Yes" : "No"    );
		swprintf( m_menuText[2], L"Force SuperGrafx Mode? : %S", g_pce_forcesgx ? "Yes" : "No"    );
		swprintf( m_menuText[3], L"Use System Card : %u", g_pce_systemcard ? 3 : 1 ) ;
		swprintf( m_menuText[4], L"Impose 16 sprite per line limit : %S", g_pce_nospritelimit ? "No" : "Yes") ;
		swprintf( m_menuText[5], L"CPU Overclock Multiplier : %u", g_pce_ocmultiplier ) ;
		swprintf( m_menuText[6], L"Perfect CUE : %S", g_pce_perfectcue ) ;
		swprintf( m_menuText[7], L"Controller Type : %S", controllers[g_pce_controller] ) ;
		swprintf( m_menuText[8], L"Sherlock Holmes 1/2 Hack? : %S", g_pce_sherlockhack ? "Yes" : "No"    );
		swprintf( m_menuText[9], L"Change Graphics Filter"  );
		swprintf( m_menuText[10], L"Configure Controllers"  );
		
		
		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 11, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
	        XBInput_GetInput();
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			break ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
			switch ( menuChoice )
			{
				case 0 : g_pce_forceus = ! g_pce_forceus ; break ; 
				case 1 : g_pce_forcesgx = ! g_pce_forcesgx ; break ;
				case 2 : g_pce_systemcard = ! g_pce_systemcard ; break ;
				case 3 : g_pce_nospritelimit = ! g_pce_nospritelimit ; break ;
				case 4 : g_pce_ocmultiplier = getValuePopup( "Overclock Multiplier", g_pce_ocmultiplier, 1, 50, &m_pnlBackgroundOther ) ; break ;
				case 5 : selectPerfectCue() ; break ; 
				case 6 : g_pce_controller = (g_pce_controller+1)%3 ; break ; 
				case 7 : g_pce_sherlockhack = ! g_pce_sherlockhack ; break ;
				case 8 : doChangeSWFilter() ; break ;
				case 9 : doConfigureControllers() ; break ;
				default : break ;
			}
		}


	}

	saveSettings( settingsname ) ;
	saveKeys( keysname ) ;

}

#elif MEDNA_TYPE == MEDNA_LYNX

void CXBoxSample::doConfigureGame( char *settingsname, char *keysname )
{
	char *rotations[] = { "None", "Left", "Right" } ;
	int menuChoice ;

	menuChoice = 0 ;

	loadSettings( settingsname ) ;
	loadKeys( keysname ) ;


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

	
		swprintf( m_menuText[0], L"Game Configuration" );
		swprintf( m_menuText[1], L"Rotation : %S", rotations[g_lynx_rotation] );
		swprintf( m_menuText[2], L"Change Graphics Filter"  );
		swprintf( m_menuText[3], L"Configure Controllers"  );
		
		
		menuChoice = renderMenuTextWrapper( 1, menuChoice, m_menuText, 4, 0, &m_pnlBackgroundOther, menuChoice, 0, 0 ) ;
		

		if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_B])
		{
	        XBInput_GetInput();
			m_sfxMenuCancel.Play( DSBPLAY_FROMSTART ) ;
			break ;
		}
		else if(g_Gamepads[0].hDevice && g_Gamepads[0].bPressedAnalogButtons[XINPUT_GAMEPAD_A])
		{
			m_sfxMenuSelect.Play( DSBPLAY_FROMSTART ) ;
			switch ( menuChoice )
			{
				case 0 : g_lynx_rotation = (g_lynx_rotation+1)%3 ; break ;
				case 1 : doChangeSWFilter() ; break ;
				case 2 : doConfigureControllers() ; break ;
				default : break ;
			}
		}


	}

	saveSettings( settingsname ) ;
	saveKeys( keysname ) ;

}

#else

#error no medna_type defined

#endif






void CXBoxSample::doLoadNewDisk()
{
}




void CXBoxSample::saveSettings( char *filename )
{
	FILE *setfile ;

	m_changedSettings = 0 ;

	setfile = fopen( filename, "wb" ) ;

	if ( !setfile )
		return ;

	fwrite( &g_nes_no8lim , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_pal , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_clipsides , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_nofs , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_slstart , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_slend , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_slstartp , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_slendp , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_ntsccol , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_ntsctint, sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_ntschue , sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_forceus, sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_forcesgx, sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_systemcard, sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_nospritelimit, sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_ocmultiplier, sizeof(int), 1, setfile ) ;
	fwrite( g_pce_perfectcue, sizeof(g_pce_perfectcue), 1, setfile ) ;
	fwrite( g_perfectTracks, sizeof(g_perfectTracks), 1, setfile ) ;
	fwrite( &g_numPerfectTracks, sizeof(DWORD), 1, setfile ) ;

	fwrite( &m_xboxSFilter, sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_input1 , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_input2 , sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_inputfc , sizeof(int), 1, setfile ) ;
	fwrite( &g_lynx_rotation, sizeof(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( &g_pce_controller, sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_hackfix , sizeof(int), 1, setfile ) ;
	fwrite( g_nes_custom_palette, MAX_PATH, 1, setfile ) ;
	fwrite( &g_nes_mapper, sizeof(int), 1, setfile ) ;
	fwrite( &g_nes_mirror, sizeof(int), 1, setfile ) ;
	fwrite( &g_pce_sherlockhack, sizeof(int), 1, setfile ) ;

	fclose( setfile ) ;

}

int CXBoxSample::loadSettings( char *filename )
{
	FILE *setfile ;

	m_changedSettings = 0 ;

	setfile = fopen( filename, "rb" ) ;

	g_nes_nofs = 0 ;
	g_pce_forceus = 0 ;
	g_pce_sherlockhack = 0 ;
	g_pce_controller = 0 ;
	g_pce_forcesgx = 0 ;
	g_pce_systemcard = 3 ;
	g_pce_perfectcue[0] = 0 ;
	g_nes_input1 = 1 ;
	g_nes_input2 = 1 ;
	g_nes_inputfc = 0 ;
	g_lynx_rotation = 0 ;

	if ( !setfile )
	{

		saveSettings( filename ) ;
		return 1 ;
	}


	fread( &g_nes_no8lim , sizeof(int), 1, setfile ) ;
	fread( &g_nes_pal , sizeof(int), 1, setfile ) ;
	fread( &g_nes_clipsides , sizeof(int), 1, setfile ) ;
	fread( &g_nes_nofs , sizeof(int), 1, setfile ) ;
	fread( &g_nes_slstart , sizeof(int), 1, setfile ) ;
	fread( &g_nes_slend , sizeof(int), 1, setfile ) ;
	fread( &g_nes_slstartp , sizeof(int), 1, setfile ) ;
	fread( &g_nes_slendp , sizeof(int), 1, setfile ) ;
	fread( &g_nes_ntsccol , sizeof(int), 1, setfile ) ;
	fread( &g_nes_ntsctint, sizeof(int), 1, setfile ) ;
	fread( &g_nes_ntschue , sizeof(int), 1, setfile ) ;
	fread( &g_pce_forceus, sizeof(int), 1, setfile ) ;
	fread( &g_pce_forcesgx, sizeof(int), 1, setfile ) ;
	fread( &g_pce_systemcard, sizeof(int), 1, setfile ) ;
	fread( &g_pce_nospritelimit, sizeof(int), 1, setfile ) ;
	fread( &g_pce_ocmultiplier, sizeof(int), 1, setfile ) ;
	fread( g_pce_perfectcue, sizeof(g_pce_perfectcue), 1, setfile ) ;
	fread( g_perfectTracks, sizeof(g_perfectTracks), 1, setfile ) ;
	fread( &g_numPerfectTracks, sizeof(DWORD), 1, setfile ) ;
	fread( &m_xboxSFilter, sizeof(int), 1, setfile ) ;
	fread( &g_nes_input1 , sizeof(int), 1, setfile ) ;
	fread( &g_nes_input2 , sizeof(int), 1, setfile ) ;
	fread( &g_nes_inputfc , sizeof(int), 1, setfile ) ;
	fread( &g_lynx_rotation, sizeof(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( &g_pce_controller, sizeof(int), 1, setfile ) ;
	if ( fread( &g_nes_hackfix , sizeof(int), 1, setfile ) <= 0 )
	{
		g_nes_hackfix = 0 ;
	}
	fread( g_nes_custom_palette, MAX_PATH, 1, setfile ) ;
	if ( fread( &g_nes_mapper, sizeof(int), 1, setfile ) <= 0 )
	{
		g_nes_mapper = -1 ;
	}
	if ( fread( &g_nes_mirror, sizeof(int), 1, setfile ) <= 0 )
	{
		g_nes_mirror = -1 ;
	}
	if ( fread( &g_pce_sherlockhack, sizeof(int), 1, setfile ) <= 0 )
	{
		g_pce_sherlockhack = 0 ;
	}


	fclose( setfile ) ;

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

	}

	return 0 ;
}


void xbox_set_ROM( byte *ROM, unsigned int romsize)
{
	g_ROM = ROM ;
	g_ROMsize = romsize ;
	g_app->applyGameGenie( ROM, romsize ) ;
}

int xbox_feed_cdda_stream( unsigned char *buf, unsigned int bufsize ) 
{
	g_app->m_cdda.pause( FALSE ) ;
	g_app->m_cdda.m_bDone = g_app->m_cdda.m_bPaused = FALSE ;

	return ( sounddanger = g_app->m_cdda.process_bytes( buf, bufsize, throttling ) ) ;
}

void CXBoxSample::doCDGame( )
{
	int fResult ;
	TOC toc;
	char xmsg[100] ;
	char systemcard[200] ;
	int sectorA, sectorB ;
	int menuChoice = 0 ;
	int  whichCard ;
	int bdone ;
	int country ; 
	int whichCD ;
	int realCD ;
	WCHAR linemsg[200] ;
	int isSelectMenu = 1 ;
	char *countries[] = { "Auto-detect", "USA", "Japan", "Europe", "Other" } ;
	char tmpfilename[500] ;


	initConsole( 0xFFFFFFFF, 0, 1 ) ;
	return ;

	throttling = 0;

	//country = 0 ;
	//whichCD = 0 ;
	realCD = 1 ;
	bdone = 1 ;
	throttle = 0 ;
	m_currentStartSector = 9999999 ;




	ANSI_STRING filename;
	OBJECT_ATTRIBUTES attributes;
	IO_STATUS_BLOCK status;
	HANDLE hDevice;
	NTSTATUS error;
	DWORD dummy;
	DWORD byteCount ;

	RtlInitAnsiString(&filename, "\\Device\\Cdrom0" );

	InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL);

	if (NT_SUCCESS(error = NtCreateFile(&m_hCdrom, GENERIC_READ |
		SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0,
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN,
		FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT)))
	{
	}
	else
	{
		popupMsg( "Could not access CD - aborting", &m_pnlBackgroundSelect ) ;
		return ;
	}



	if ( m_hCdrom == INVALID_HANDLE_VALUE )
	{
		popupMsg( "Could not access CD - aborting", &m_pnlBackgroundSelect ) ;
		return ;
	}

	if ( ! DeviceIoControl(m_hCdrom, IOCTL_CDROM_READ_TOC, NULL, 0,	&toc, sizeof(TOC), &byteCount, NULL ) )
	{
		CloseHandle( m_hCdrom ) ;
		popupMsg( "Could not read TOC from CD - aborting", &m_pnlBackgroundSelect ) ;
		return  ;
	}

//	memset( CD_track, 0, sizeof(CD_track) ) ;




	unsigned char numTracks = toc.lastTrack - toc.firstTrack + 1;
	TOCTRACK *t;


	for ( int i = toc.firstTrack; i <= toc.lastTrack; i++)
	{
		int val = 	( toc.tracks[i-1].addr[1] * 60 * 75 ) + 
					( toc.tracks[i-1].addr[2] * 75 ) +
					( toc.tracks[i-1].addr[3]  ) ;
		int frms, mins, secs ;

		mins = toc.tracks[i-1].addr[1] ;
		secs = toc.tracks[i-1].addr[2] ;
		frms = toc.tracks[i-1].addr[3] ;

		/*
		if ( secs < 2 )  //account for standard gap that seems to appear on all cue sheets
		{
			secs = 60 - secs ;
			mins-- ;
		}
		else
		{
			secs -= 2 ;
		}
*/





	}






	unsigned char tmp_data[2048*2] ;
	unsigned int CRC ;

	CRC = -1 ;


	m_io.ReadSector( m_hCdrom, sectorA+1, (LPSTR)tmp_data ) ;

	for (int index = 0; index < 2048; index++)
	{
		tmp_data[index] ^= CRC;
		CRC >>= 8;
		CRC ^= TAB_CONST2[tmp_data[index]];
	}
	CRC = ~CRC;


	
	m_state = IN_GAME ;

	

	





	char cd_filename[500] ;

	global_error_message[0] = 0 ;

	m_droppedFrames = 0 ;


//	sleepamount = 0 ;
	throttle = 0 ;
//	blittermode = 1 ;



	memset( m_memMatches, 1, CONSOLE_MEMORY_SIZE ) ;
	m_currentMemMatches = CONSOLE_MEMORY_SIZE ;
	m_numCheats = 0 ;

	writexbox( "init1" ) ;

	sprintf( cd_filename, "D:\\PCEROMS\\%02.2X%02.2X%02.2X%02.2X.IMG", (CRC>>24)&0xFF, (CRC>>16)&0xFF, (CRC>>8)&0xFF, CRC&0xFF ) ;
	//strcpy( cd_filename, "D:\\PCEROMS\\RAWCD.IMG" ) ;


	
	//strcpy((char*)filename, "D:\\sgenroms\\" ) ;
	//strcpy((char*)cd_filename, m_szCurrentDir ) ;
	//wcsrtombs( (char*)gfilename, (const wchar_t**)(&(files[idx].name)), 100, NULL ) ;
	//strcat( (char*)cd_filename, (const char*)files[idx].filename ) ;


	loaded_cue = 0 ;


	char *p;


	//writexbox( "init1" ) ;

	strcpy( g_saveprefix, g_savePath ) ;
	strcat( g_saveprefix, "\\" ) ;
	strcat( g_saveprefix, strrchr( cd_filename, '\\' )+1 ) ;
	//sprintf(saveprefix, "%s\\%s", savedir, (const char*)files[idx].filename);
	p = strrchr(g_saveprefix, '.');
	if (p) *p = 0;

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

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

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

	strcpy(g_fdsfile, g_saveprefix);
	strcat(g_fdsfile, ".fds");

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

	sprintf( g_statefile, "%s.sta", g_saveprefix ) ;

	changeMenu( &m_skin.mainMenu, &m_skin.otherMenu ) ;
	doConfigureGame( g_settingsfile, g_keysfile ) ;
	isSelectMenu = 0 ;

	if ( m_bNetplay )
	{
		if ( setupNetplay() )
			return ;
	}

	if ( g_autoLaunchGame )
	{
		m_pnlSplashGame.Render() ;
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
	}
	else
	{
		if ( isSelectMenu )
		{
			doTransition( &m_pnlBackgroundMain, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
		else
		{
			doTransition( &m_pnlBackgroundOther, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
	}
//	nonoise = 0 ;

	
	switch ( m_systemCard )
	{
		case 1 : strcpy( systemcard, "X:\\SYSCARD3.PCE" ) ; break ; 
	//	case 2 : strcpy( systemcard, "D:\\PCEROMS\\ARCADECARD.PCE" ) ; break ; 
		default : strcpy( systemcard, "X:\\SYSCARD1.PCE" ) ; break ; 
	}


	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;
	if ( !m_bBgmInGame )
	{
		m_mp3player.pause( TRUE ) ;
	}

	m_sound.init() ;
	m_cdda.init() ;
	m_mp3player_cdda.init() ;

	//m_mp3player.init() ;

	//writexbox( "init1" ) ;
	cht_load() ;

	// Create our texture
	init_texture();


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





	m_fAppTime = 0.0f ;

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

	m_steps = 0 ;

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

	m_numFrames = 0 ;
	m_startTime = GetTickCount() ;

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

	QueryPerformanceCounter((union _LARGE_INTEGER *) m_performancePrev);

	//m_plaything.FreeSprites() ;

	sprintf( tmpfilename, "%s\\%s\\SPRITES\\*", m_szSkinDir, m_szSkin) ;

//	hugomain( cd_filename, g_sramfile, g_saveprefix, systemcard, 1, 0 ) ;


	//m_plaything.LoadSprites( tmpfilename ) ;

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

	m_state=MAIN_MENU ;
	saveKeys( g_keysfile ) ;
	saveSettings( g_settingsfile ) ;

	cleanupConsole() ;






	//last thing after finishing game
	CloseHandle( m_hCdrom ) ;
	m_hCdrom = INVALID_HANDLE_VALUE ;






	


}








void CXBoxSample::ggenie_init()
{



}






int CXBoxSample::addEmuSpecificOptions( int start )
{
#if MEDNA_TYPE == MEDNA_NES
	swprintf( m_menuText[start], L"Reset Game");
	swprintf( m_menuText[start+1], L"Toggle Rewind");
	swprintf( m_menuText[start+2], L"Insert/Eject FDS Disk");
	swprintf( m_menuText[start+3], L"Select FDS Disk");
	swprintf( m_menuText[start+4], L"Insert Coin");
	swprintf( m_menuText[start+5], L"Toggle DIP #0");
	swprintf( m_menuText[start+6], L"Toggle DIP #1");
	swprintf( m_menuText[start+7], L"Toggle DIP #2");
	swprintf( m_menuText[start+8], L"Toggle DIP #3");
	swprintf( m_menuText[start+9], L"Toggle DIP #4");
	swprintf( m_menuText[start+10], L"Toggle DIP #5");
	swprintf( m_menuText[start+11], L"Toggle DIP #6");
	swprintf( m_menuText[start+12], L"Toggle DIP #7");

	return start+13 ;
#elif MEDNA_TYPE == MEDNA_PCE
	swprintf( m_menuText[start], L"Reset Game");
	swprintf( m_menuText[start+1], L"Toggle Rewind");
	return start+2 ;
#else
	swprintf( m_menuText[start], L"Reset Game");
	swprintf( m_menuText[start+1], L"Toggle Rewind");
	return start+2 ;
#endif

		//return start+1 ;

}

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

}

void CXBoxSample::performEmuSpecificOption( int start, int menuChoice ) 
{
#if MEDNA_TYPE == MEDNA_NES

	unsigned int systype = getSystemType() ;

		if ( menuChoice == start )
		{
			MDFNI_Reset() ;
			popupMsg( "Game Reset", &m_pnlBackgroundOther ) ;
		}
		else if ( menuChoice == ( start +1 ) )
		{
			g_rewind_enabled = !g_rewind_enabled ;
			MDFNI_EnableStateRewind( g_rewind_enabled ) ;
			if ( g_rewind_enabled )
				popupMsg( "Rewind Enabled", &m_pnlBackgroundOther ) ;
			else
				popupMsg( "Rewind Disabled", &m_pnlBackgroundOther ) ;
		}
		else if ( menuChoice ==  start+2 )
		{
			if ( systype == GIT_FDS )
				MDFNI_FDSInsert(0) ;
		}
		else if ( menuChoice == start+3 )
		{
			if ( systype == GIT_FDS )
				MDFNI_FDSSelect() ;
		}
		else if ( menuChoice == start+4 )
		{
			if ( systype == GIT_VSUNI )
				MDFNI_VSUniCoin() ;
		}
		else if ( ( menuChoice >= start+5 ) && ( menuChoice <= start+12 ) )
		{
			if ( systype == GIT_VSUNI )
				MDFNI_VSUniToggleDIP( menuChoice - (start+4) ) ;
		}

#elif MEDNA_TYPE == MEDNA_PCE
	if ( menuChoice == start )
	{
		MDFNI_Reset() ;
		popupMsg( "Game Reset", &m_pnlBackgroundOther ) ;
	}
	else if ( menuChoice == ( start +1 ) )
	{
		g_rewind_enabled = !g_rewind_enabled ;
		MDFNI_EnableStateRewind( g_rewind_enabled ) ;
		if ( g_rewind_enabled )
			popupMsg( "Rewind Enabled", &m_pnlBackgroundOther ) ;
		else
			popupMsg( "Rewind Disabled", &m_pnlBackgroundOther ) ;
	}
#else
	if ( menuChoice == start )
	{
		MDFNI_Reset() ;
		popupMsg( "Game Reset", &m_pnlBackgroundOther ) ;
	}
	else if ( menuChoice == ( start +1 ) )
	{
		g_rewind_enabled = !g_rewind_enabled ;
		MDFNI_EnableStateRewind( g_rewind_enabled ) ;
		if ( g_rewind_enabled )
			popupMsg( "Rewind Enabled", &m_pnlBackgroundOther ) ;
		else
			popupMsg( "Rewind Disabled", &m_pnlBackgroundOther ) ;
	}
#endif
	/*
	if ( menuChoice == start )
	{
		doLoadNewDisk() ;
	}
	*/
}

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





void CXBoxSample::doSelectMemcards()
{

	int menuChoice = 0 ;


	while ( 1 )
	{

		pmenuParams = &(m_skin.otherMenu) ;

		swprintf( m_menuText[0], L"Set Memory Card Slots" );
		swprintf( m_menuText[1], L"Memory Card 1" );
		swprintf( m_menuText[2], L"%u", m_memcardnum1 );
		swprintf( m_menuText[3], L"Memory Card 2" );
		swprintf( m_menuText[4], L"%u", m_memcardnum2 );

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

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

			if ( menuChoice == 0 )
			{
				m_memcardnum1 = getValuePopup( "Memory Card Slot 1", m_memcardnum1, 0, 9, &m_pnlBackgroundOther ) ; 
			}
			else
			{
				m_memcardnum2 = getValuePopup( "Memory Card Slot 2", m_memcardnum2, 0, 9, &m_pnlBackgroundOther ) ; 
			}
		}

	}
}




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

	InitializeWithScreen() ;

    return S_OK;
}


int CXBoxSample::render_to_texture( unsigned char *buf, int w, int h, int spitch, int systype, int wx, int wy)
{

	//DOXXX
	RECT dst;
	byte *curr1, *curr2, *src ;
	unsigned short *wptr ;
	unsigned int *pix32 ;
	int Dep ;
	unsigned int color ;
	unsigned char r,g,b ;
	
	// Get a description of our level 0 texture so we can figure
	// out the pitch of the texture
	//D3DSURFACE_DESC desc;
    //Texture->GetLevelDesc(0, &desc);
	

	//sprintfx( "render w=%u\r\n", w ) ;

	// Allocate a buffer to blit our frames to

#if MEDNA_TYPE == MEDNA_PCE
	// Figure out how big of a rect to lock in our texture
	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	//rectSource.bottom = (VDP_Num_Vis_Lines<<BLITTERS[blittermode].multiplier)  - 1 ;
	//rectSource.right  = ((320-Dep) << BLITTERS[blittermode].multiplier ) - 1 ;
	rectSource.bottom = theHeight - 1 ;
	rectSource.right  = theWidth  - 1;

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

	if ( m_xboxSFilter )
		curr1 = g_pBlitBuff ;
	else
		curr1 = (byte*)g_d3dlr.pBits ;

	if ( systype == 4 )
	{
		for ( int y = 0 ; y < h ; y++ )
		{
			pix32 = ((unsigned int*)(buf + ( spitch*y))) ;
			wptr = (unsigned short*)curr1 + ( m_pitch*y/2) ;
//			memcpy( curr2, curr1, w*2 ) ;
	
			for ( int x = 0 ; x < w ; x++ )
			{
				color = *pix32++ ;
				r = (color >> 16)>>3 ;
				g = (color >> 8)>>2 ;
				b = (color)>>3 ;
				*wptr++ = ( r << 11 ) | ( g << 5 ) | b  ;
				//*wptr++ = ( ( color >> 8 ) & 0xF800 ) | ( ( color >> 5 ) & 0x7E0 ) | ( ( color >> 3 ) & 0x1F ) ;
			}
		}
	}
#endif
#if MEDNA_TYPE == MEDNA_NES
		//if ( g_nes_clipsides )
			//w -= 8 ;
#endif
#if 0
	else
	{
		if ( g_nes_clipsides )
			w -= 16 ;

		for ( int y = 0 ; y < h ; y++ )
		{
			src = (buf + ( spitch*y)) ;
			curr2 = (unsigned char*)curr1 + ( m_pitch*y) ;
			memcpy( curr2, src, w*2 ) ;
	/*
			for ( int x = 0 ; x < w ; x++ )
			{
				*wptr++ = (*pix32++) ;
			}*/
		}
	}
#endif


	float mx, my ;

	if ( m_xboxSFilter )
	{

#if MEDNA_TYPE == MEDNA_PCE
		SOFTWARE_FILTERS[m_xboxSFilter].blitfunc(g_pBlitBuff+m_pitch, m_pitch, g_pDeltaBuff+m_pitch, (unsigned char*)g_d3dlr.pBits, m_pitch, w, h, 0 ) ;
#else
		SOFTWARE_FILTERS[m_xboxSFilter].blitfunc(g_pBlitBuff+((wy+1)*m_pitch)+(wx*2), m_pitch, g_pDeltaBuff+m_pitch, (unsigned char*)g_d3dlr.pBits, m_pitch, w, h, 0 ) ;
#endif
		Texture->UnlockRect(0);
		g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);
		//g_pd3dDevice->BeginScene();

		//memcpy( g_pDeltaBuff, ((unsigned char*)MD_Screen)+16, spitch*VDP_Num_Vis_Lines ) ;
		mx = (float)m_nScreenMaxX / ((float)(w)*2.0f) ;
		my = (float)m_nScreenMaxY / ((float)h*2.0f);

		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = h*2 ;
		m_gameRectSource.right  = w*2;
	}
	else
	{
		Texture->UnlockRect(0);
		g_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L);

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

#if MEDNA_TYPE != MEDNA_PCE
		m_gameRectSource.top = wy;
		m_gameRectSource.left = wx;
		m_gameRectSource.bottom = h  ;
		m_gameRectSource.right  = w ;
#else
		m_gameRectSource.top = 0;
		m_gameRectSource.left = 0;
		m_gameRectSource.bottom = h  ;
		m_gameRectSource.right  = w ;
#endif
	}



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

	if ( g_lynx_rotation )
	{
		if ( g_lynx_rotation == 1 )
			m_pnlGameScreen.RenderRotated(m_gameRectSource.left,m_gameRectSource.top,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY, 90) ;
		else
			m_pnlGameScreen.RenderRotated(m_gameRectSource.left,m_gameRectSource.top,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY, 270) ;
	}
	else
	{
		m_pnlGameScreen.RenderRotated(m_gameRectSource.left,m_gameRectSource.top,m_gameRectSource.right,m_gameRectSource.bottom,m_nScreenX ,m_nScreenY, m_nScreenMaxX, m_nScreenMaxY, 0) ;
	}

	m_numFrames++ ;

#ifdef LIGHTGUN
	if ( ( ( g_nes_input1 == 2 ) || ( g_nes_input2 == 2 ) ) && m_lightgunTarget )
	{
		if ( m_lightgun.m_port >= 0 )
		{
			if ( m_lightgun.wButtons & XINPUT_LIGHTGUN_ONSCREEN  )
			{
				FLOAT fWidth = 640.0f *VIDEOMODES[m_xboxVidmode].multx;
				FLOAT fHeight = 480.0f *VIDEOMODES[m_xboxVidmode].multy;
				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-1, fThumbLY-8, 2, 16, m_lightgunTargetColor);
				ColorBar( fThumbLX-8, fThumbLY-1, 16, 2, m_lightgunTargetColor);
			}
		}
		else
		{
			if ( m_lightgun.wButtons & XINPUT_LIGHTGUN_ONSCREEN  )
			{
				FLOAT fThumbLX = ((m_zapperDat[0]*m_nScreenMaxX)/256) + m_nScreenX ;
				FLOAT fThumbLY = ((m_zapperDat[1]*m_nScreenMaxY)/240) + m_nScreenY ;

				fThumbLX -= 8*VIDEOMODES[m_xboxVidmode].multx ;
				ColorBar( fThumbLX-1, fThumbLY-8, 2, 16, m_lightgunTargetColor);
				ColorBar( fThumbLX-8, fThumbLY-1, 16, 2, m_lightgunTargetColor);
			}
		}
	}
#endif

	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   ) ;
		}
	}
*/
	// End the scene.
	//g_pd3dDevice->EndScene();

	//if ( !throttle )
		//g_pd3dDevice->BlockUntilVerticalBlank() ;
#ifdef NESFKB
	renderScreenKeyboard() ;
#endif

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

	/*
	float FPS, desiredFPS ;

	desiredFPS = m_d3dpp.FullScreen_RefreshRateInHz  ;

	if ( 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\r\n", FPS);
		}
		else
		{
			FPS = 100.0f ;
			//sprintf( global_error_message, "fps=too much...\r\n");
		}

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

	m_performancePrev[0] = m_performanceCurr[0];
*/

	return 1;
}

void CXBoxSample::InitializeEmuSpecific()
{
	m_changedSettings = 0 ;

	sprintfx( "initemuspec\r\n") ;
	m_cdda.dsound = m_sound.dsound ;
	m_cdda.dsound_init( ) ;
	m_mp3player_cdda.dsound = m_sound.dsound ;
	m_mp3player_cdda.dsound_init() ;

	sprintfx( "initemuspec\r\n") ;
	m_cdda.m_fps = m_d3dpp.FullScreen_RefreshRateInHz ;
	g_cdda = &m_cdda ;

	sprintfx( "initemuspec\r\n") ;
	for ( int i = 0 ; i < 102 ; i++ )
	{
		if ( ! m_relaxTracks[i].Initialize( m_rlxShare ) )
		{
			//sprintfx( "no init main relax\r\n") ;
		}
	}
	sprintfx( "initemuspec\r\n") ;

	m_cdDataBuffer = (unsigned char*)malloc( CD_DATA_BUFFER_SIZE ) ;
	sprintfx( "initemuspec\r\n") ;

	memset( g_perfectTracks, 0, sizeof( g_perfectTracks ) ) ;
	g_numPerfectTracks  = sizeof( g_perfectTracks )  ;
	g_numPerfectTracks  = 0 ;

	g_nes_no8lim = 0 ;
	g_nes_pal = 0 ;
	g_nes_input1 = 1 ;
	g_nes_input2 = 1 ;
	g_nes_inputfc = 0 ;
	g_nes_clipsides = 0 ;
	g_nes_nofs = 0 ;
	g_nes_slstart = 8;
	g_nes_slend = 231 ;
	g_nes_slstartp = 0 ;
	g_nes_slendp  = 239 ;
	g_nes_ntsccol = 0 ;
	g_nes_hackfix = 0 ;
	g_nes_mapper = -1 ;
	g_nes_mirror = -1 ;
	g_nes_custom_palette[0] = 0 ;
	g_nes_ntsctint = 56 ;
	g_nes_ntschue = 72 ;
	g_pce_forceus = 0 ;
	g_pce_sherlockhack = 0 ;
	g_pce_controller = 0 ;
	g_pce_forcesgx = 0 ;
	g_pce_systemcard = 1;
	g_pce_nospritelimit = 0 ;
	g_pce_ocmultiplier = 1;
	g_pce_perfectcue[0] = 0  ;
	g_lynx_rotation = 0 ;

	for ( int i = 0 ; i < 256 ; i++ )
	{
		vkey_to_fkb[i] = -1 ;
	}
#include "nes/input/fkb.h"

	vkey_to_fkb[VK_A] = FKB_A  ;
	vkey_to_fkb[VK_B] = FKB_B  ;
	vkey_to_fkb[VK_C] = FKB_C  ;
	vkey_to_fkb[VK_D] = FKB_D  ;
	vkey_to_fkb[VK_E] = FKB_E  ;
	vkey_to_fkb[VK_F] = FKB_F  ;
	vkey_to_fkb[VK_G] = FKB_G  ;
	vkey_to_fkb[VK_H] = FKB_H  ;
	vkey_to_fkb[VK_I] = FKB_I  ;
	vkey_to_fkb[VK_J] = FKB_J  ;
	vkey_to_fkb[VK_K] = FKB_K  ;
	vkey_to_fkb[VK_L] = FKB_L  ;
	vkey_to_fkb[VK_M] = FKB_M  ;
	vkey_to_fkb[VK_N] = FKB_N  ;
	vkey_to_fkb[VK_O] = FKB_O  ;
	vkey_to_fkb[VK_P] = FKB_P  ;
	vkey_to_fkb[VK_Q] = FKB_Q  ;
	vkey_to_fkb[VK_R] = FKB_R  ;
	vkey_to_fkb[VK_S] = FKB_S  ;
	vkey_to_fkb[VK_T] = FKB_T  ;
	vkey_to_fkb[VK_U] = FKB_U  ;
	vkey_to_fkb[VK_V] = FKB_V  ;
	vkey_to_fkb[VK_W] = FKB_W  ;
	vkey_to_fkb[VK_X] = FKB_X  ;
	vkey_to_fkb[VK_Y] = FKB_Y  ;
	vkey_to_fkb[VK_Z] = FKB_Z  ;
	vkey_to_fkb[VK_0] = FKB_0  ;
	vkey_to_fkb[VK_1] = FKB_1  ;
	vkey_to_fkb[VK_2] = FKB_2  ;
	vkey_to_fkb[VK_3] = FKB_3  ;
	vkey_to_fkb[VK_4] = FKB_4  ;
	vkey_to_fkb[VK_5] = FKB_5  ;
	vkey_to_fkb[VK_6] = FKB_6  ;
	vkey_to_fkb[VK_7] = FKB_7  ;
	vkey_to_fkb[VK_8] = FKB_8  ;
	vkey_to_fkb[VK_9] = FKB_9  ;
	vkey_to_fkb[VK_F1] = FKB_F1  ;
	vkey_to_fkb[VK_F2] = FKB_F2  ;
	vkey_to_fkb[VK_F3] = FKB_F3  ;
	vkey_to_fkb[VK_F4] = FKB_F4  ;
	vkey_to_fkb[VK_F5] = FKB_F5  ;
	vkey_to_fkb[VK_F6] = FKB_F6  ;
	vkey_to_fkb[VK_F7] = FKB_F7  ;
	vkey_to_fkb[VK_F8] = FKB_F8  ;

	vkey_to_fkb[VK_SPACE] = FKB_SPACE  ;
	vkey_to_fkb[VK_RETURN] = FKB_RETURN  ;
	vkey_to_fkb[VK_ESCAPE] = FKB_ESCAPE  ;

	vkey_to_fkb[VK_UP] = FKB_UP  ;
	vkey_to_fkb[VK_DOWN] = FKB_DOWN  ;
	vkey_to_fkb[VK_LEFT] = FKB_LEFT  ;
	vkey_to_fkb[VK_RIGHT] = FKB_RIGHT  ;

	vkey_to_fkb[VK_OEM_COMMA] = FKB_COMMA  ;
	vkey_to_fkb[VK_OEM_PERIOD] = FKB_PERIOD  ;

	vkey_to_fkb[VK_OEM_2] = FKB_SLASH  ;
	vkey_to_fkb[VK_OEM_5] = FKB_BACKSLASH  ;
	vkey_to_fkb[VK_OEM_4] = FKB_BRACKETLEFT  ;
	vkey_to_fkb[VK_OEM_6] = FKB_BRACKETRIGHT  ;
	vkey_to_fkb[VK_OEM_1] = FKB_SEMICOLON  ;
	vkey_to_fkb[VK_OEM_7] = FKB_COLON  ;
	vkey_to_fkb[VK_OEM_MINUS] = FKB_MINUS  ;
	vkey_to_fkb[VK_OEM_PLUS] = FKB_UNDERSCORE  ;
	vkey_to_fkb[VK_DELETE] = FKB_DELETE  ;
	vkey_to_fkb[VK_INSERT] = FKB_INSERT  ;
	vkey_to_fkb[VK_LSHIFT] = FKB_LEFTSHIFT  ;
	vkey_to_fkb[VK_RSHIFT] = FKB_RIGHTSHIFT  ;
	vkey_to_fkb[VK_LCONTROL] = FKB_CONTROL  ;
	vkey_to_fkb[VK_RCONTROL] = FKB_CONTROL  ;
	vkey_to_fkb[VK_MULTIPLY] = FKB_CARET  ;
	vkey_to_fkb[VK_ADD] = FKB_STOP  ;
	vkey_to_fkb[VK_SUBTRACT] = FKB_AT  ;
	vkey_to_fkb[VK_DECIMAL] = FKB_KANA  ;
	vkey_to_fkb[VK_DIVIDE] = FKB_GRAPH  ;
	vkey_to_fkb[VK_SEPARATOR] = FKB_CLEAR  ;


#if 0
		vkey_to_fkb[VK_A] = FKB_A - 1 ;
	vkey_to_fkb[VK_B] = FKB_B - 1 ;
	vkey_to_fkb[VK_C] = FKB_C - 1 ;
	vkey_to_fkb[VK_D] = FKB_D - 1 ;
	vkey_to_fkb[VK_E] = FKB_E - 1 ;
	vkey_to_fkb[VK_F] = FKB_F - 1 ;
	vkey_to_fkb[VK_G] = FKB_G - 1 ;
	vkey_to_fkb[VK_H] = FKB_H - 1 ;
	vkey_to_fkb[VK_I] = FKB_I - 1 ;
	vkey_to_fkb[VK_J] = FKB_J - 1 ;
	vkey_to_fkb[VK_K] = FKB_K - 1 ;
	vkey_to_fkb[VK_L] = FKB_L - 1 ;
	vkey_to_fkb[VK_M] = FKB_M - 1 ;
	vkey_to_fkb[VK_N] = FKB_N - 1 ;
	vkey_to_fkb[VK_O] = FKB_O - 1 ;
	vkey_to_fkb[VK_P] = FKB_P - 1 ;
	vkey_to_fkb[VK_Q] = FKB_Q - 1 ;
	vkey_to_fkb[VK_R] = FKB_R - 1 ;
	vkey_to_fkb[VK_S] = FKB_S - 1 ;
	vkey_to_fkb[VK_T] = FKB_T - 1 ;
	vkey_to_fkb[VK_U] = FKB_U - 1 ;
	vkey_to_fkb[VK_V] = FKB_V - 1 ;
	vkey_to_fkb[VK_W] = FKB_W - 1 ;
	vkey_to_fkb[VK_X] = FKB_X - 1 ;
	vkey_to_fkb[VK_Y] = FKB_Y - 1 ;
	vkey_to_fkb[VK_Z] = FKB_Z - 1 ;
	vkey_to_fkb[VK_0] = FKB_0 - 1 ;
	vkey_to_fkb[VK_1] = FKB_1 - 1 ;
	vkey_to_fkb[VK_2] = FKB_2 - 1 ;
	vkey_to_fkb[VK_3] = FKB_3 - 1 ;
	vkey_to_fkb[VK_4] = FKB_4 - 1 ;
	vkey_to_fkb[VK_5] = FKB_5 - 1 ;
	vkey_to_fkb[VK_6] = FKB_6 - 1 ;
	vkey_to_fkb[VK_7] = FKB_7 - 1 ;
	vkey_to_fkb[VK_8] = FKB_8 - 1 ;
	vkey_to_fkb[VK_9] = FKB_9 - 1 ;
	vkey_to_fkb[VK_F1] = FKB_F1 - 1 ;
	vkey_to_fkb[VK_F2] = FKB_F2 - 1 ;
	vkey_to_fkb[VK_F3] = FKB_F3 - 1 ;
	vkey_to_fkb[VK_F4] = FKB_F4 - 1 ;
	vkey_to_fkb[VK_F5] = FKB_F5 - 1 ;
	vkey_to_fkb[VK_F6] = FKB_F6 - 1 ;
	vkey_to_fkb[VK_F7] = FKB_F7 - 1 ;
	vkey_to_fkb[VK_F8] = FKB_F8 - 1 ;

	vkey_to_fkb[VK_SPACE] = FKB_SPACE - 1 ;
	vkey_to_fkb[VK_RETURN] = FKB_RETURN - 1 ;
	vkey_to_fkb[VK_ESCAPE] = FKB_ESCAPE - 1 ;

	vkey_to_fkb[VK_UP] = FKB_UP - 1 ;
	vkey_to_fkb[VK_DOWN] = FKB_DOWN - 1 ;
	vkey_to_fkb[VK_LEFT] = FKB_LEFT - 1 ;
	vkey_to_fkb[VK_RIGHT] = FKB_RIGHT - 1 ;

	vkey_to_fkb[VK_OEM_COMMA] = FKB_COMMA - 1 ;
	vkey_to_fkb[VK_OEM_PERIOD] = FKB_PERIOD - 1 ;

	vkey_to_fkb[VK_OEM_2] = FKB_SLASH - 1 ;
	vkey_to_fkb[VK_OEM_5] = FKB_BACKSLASH - 1 ;
	vkey_to_fkb[VK_OEM_4] = FKB_BRACKETLEFT - 1 ;
	vkey_to_fkb[VK_OEM_6] = FKB_BRACKETRIGHT - 1 ;
	vkey_to_fkb[VK_OEM_1] = FKB_SEMICOLON - 1 ;
	vkey_to_fkb[VK_OEM_7] = FKB_COLON - 1 ;
	vkey_to_fkb[VK_OEM_MINUS] = FKB_MINUS - 1 ;
	vkey_to_fkb[VK_OEM_PLUS] = FKB_UNDERSCORE - 1 ;
	vkey_to_fkb[VK_DELETE] = FKB_DELETE - 1 ;
	vkey_to_fkb[VK_INSERT] = FKB_INSERT - 1 ;
	vkey_to_fkb[VK_LSHIFT] = FKB_LEFTSHIFT - 1 ;
	vkey_to_fkb[VK_RSHIFT] = FKB_RIGHTSHIFT - 1 ;
	vkey_to_fkb[VK_LCONTROL] = FKB_CONTROL - 1 ;
	vkey_to_fkb[VK_RCONTROL] = FKB_CONTROL - 1 ;
	vkey_to_fkb[VK_MULTIPLY] = FKB_CARET - 1 ;
	vkey_to_fkb[VK_ADD] = FKB_STOP - 1 ;
	vkey_to_fkb[VK_SUBTRACT] = FKB_AT - 1 ;
	vkey_to_fkb[VK_DECIMAL] = FKB_KANA - 1 ;
	vkey_to_fkb[VK_DIVIDE] = FKB_GRAPH - 1 ;
	vkey_to_fkb[VK_SEPARATOR] = FKB_CLEAR - 1 ;
#endif

}


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



    return S_OK;
}



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 ) ) ;
			g_rumbleCodes = (RUMBLE_CODE*)realloc( g_rumbleCodes, sizeof(RUMBLE_CODE) * ( m_numCheats  + 1 ) ) ;

			memcpy( &(m_cheatCodes[m_numCheats]),&code, sizeof(CHEAT_CODE) ) ;
			memset( &(g_rumbleCodes[m_numCheats]),0, sizeof(RUMBLE_CODE) ) ;
			m_numCheats++ ;

			g_app->applyGameGenie( g_ROM, g_ROMsize ) ;
			return 0 ;
		}
	}

	g_app->applyGameGenie( g_ROM, g_ROMsize ) ;

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

	g_app->applyGameGenie( g_ROM, g_ROMsize ) ;

}

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

	}
}


void CXBoxSample::updateEmuSpecificCheats( ) 
{
}


#ifdef LIGHTGUN

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

	//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 *VIDEOMODES[m_xboxVidmode].multx;
	FLOAT fHeight = 480.0f *VIDEOMODES[m_xboxVidmode].multy;
    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 ;
	}

	return 1 ;
}

#endif

void kbd_handle_keyup( unsigned int vcode, unsigned int vcode2 )
{
	if ( vkey_to_fkb[vcode] >= 0 )
		fkbkeys[vkey_to_fkb[vcode]] = 0 ;
}
void kbd_handle_keydown( unsigned int vcode, unsigned int vcode2 )
{
	if ( vkey_to_fkb[vcode] >= 0 )
		fkbkeys[vkey_to_fkb[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 ;
	unsigned int systype ;
	static int doInsert[4] = {0,0,0,0} ;
	static int doChange[4] = {0,0,0,0} ;
	static int doCoin[4] = {0,0,0,0} ;
	static int doDip[4] = {0,0,0,0} ;
	static int doReset[4] = {0,0,0,0} ;
	static int doRewind[4] = {0,0,0,0} ;
	int rewind = 0 ;
	DWORD vcode ;
	byte held_keys[256] ;

	updateCheats2() ;

#ifdef NESFKB

#if MEDNA_TYPE == MEDNA_NES
	memset( held_keys, 0, 256 ) ;
	memset( fkbkeys, 0, 48 ) ;

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

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

	if ( sleepamount )
		sleepamount-- ;

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

	}

	systype = getSystemType() ;

	for ( int i = 0 ; i < 4 ; i++ )
	{
		if ( g_app->m_emuControllers[i] & TOGGLE_REWIND )
		{
			if ( ! doRewind[i] )
			{
				g_rewind_enabled = !g_rewind_enabled ;
				MDFNI_EnableStateRewind( g_rewind_enabled ) ;
				sprintf( global_error_message, "Rewinding is %s", g_rewind_enabled ? "Enabled" : "Disabled" ) ;
				m_msgDelay = 120 ;
				doRewind[i] = 1 ;
			}
		}
		else
		{
			doRewind[i] = 0 ;
		}

		if ( g_app->m_emuControllers[i] & DOREWIND )
		{
			if ( sleepamount == 0 )
				rewind |= 1 ;
		}

		if ( g_app->m_emuControllers[i] & JOY_RESET )
		{
			if ( ! doInsert[i] )
			{
				MDFNI_Reset() ;
				doReset[i] = 1 ;
			}
		}
		else
		{
			doReset[i] = 0 ;
		}

#ifdef NESFKB
#if MEDNA_TYPE == MEDNA_NES

		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 ( vkey_to_fkb[vcode] >= 0 )
					fkbkeys[vkey_to_fkb[vcode]] = 1 ;
				if ( keyboard_keystate[vcode]==0 )
				{
					//if ( vkey_to_amiga[vcode] )
						//handle_input_event( vkey_to_fkb[vcode], 1, 1, 0 ) ;
					keyboard_keystate[vcode] = 1 ;
				}
			}
			else
			{
				break ;
			}
		}
#endif
#endif
		if ( systype == GIT_FDS )
		{
			if ( g_app->m_emuControllers[i] & INSERT_FDS )
			{
				if ( ! doInsert[i] )
				{
					MDFNI_FDSInsert(0) ;
					doInsert[i] = 1 ;
				}
			}
			else
			{
				doInsert[i] = 0 ;
			}

			if ( g_app->m_emuControllers[i] & CHANGE_FDS ) 
			{
				if ( ! doChange[i] )
				{
					MDFNI_FDSSelect() ;
					//FDSControl(FDS_SELECT);
					doChange[i] = 1 ;
				}
			}
			else
			{
				doChange[i] = 0 ;
			}
		}
		else if ( systype == GIT_VSUNI )
		{
			if ( g_app->m_emuControllers[i] & VSUNI_COIN )
			{
				if ( ! doCoin[i] )
				{
					MDFNI_VSUniCoin() ;
					doCoin[i] = 1 ;
				}
			}
			else
			{
				doCoin[i] = 0 ;
			}
			if ( g_app->m_emuControllers[i] & 0xFF0000 )
			{
				if ( ! doDip[i] )
				{
					unsigned char dipmask = ( g_app->m_emuControllers[i] & 0xFF0000 ) >> 16 ;

					for ( int d = 0 ; d < 8 ; d++ )
					{
						if ( dipmask & 0x01 )
						{
							MDFNI_VSUniToggleDIP( d ) ;
						}
						dipmask = dipmask >> 1 ;
					}

					doDip[i] = 1 ;
				}
			}
			else
			{
				doDip[i] = 0 ;
			}

		}
	}


	if ( rewind )
		MDFNI_DoRewind() ;

#ifdef NESFKB
#if MEDNA_TYPE == MEDNA_NES

		while ( Keyboard_GetVKInput() )
	{
		if ( g_keyboardStroke.Flags & XINPUT_DEBUG_KEYSTROKE_FLAG_KEYUP )
		{
			if ( vkey_to_fkb[g_keyboardStroke.VirtualKey] >= 0 )
				fkbkeys[vkey_to_fkb[g_keyboardStroke.VirtualKey]] = 0 ;
			//if ( vkey_to_amiga[g_keyboardStroke.VirtualKey] )
				//handle_input_event( vkey_to_amiga[g_keyboardStroke.VirtualKey], 0, 1, 0 ) ;
			keyboard_keystate[g_keyboardStroke.VirtualKey] = 0 ;
			held_keys[g_keyboardStroke.VirtualKey] = 0 ;

		}
		else
		{
			if ( g_keyboardStroke.Flags & XINPUT_DEBUG_KEYSTROKE_FLAG_REPEAT )
			{
			}
			else
			{
				if ( vkey_to_fkb[g_keyboardStroke.VirtualKey] >= 0 )
					fkbkeys[vkey_to_fkb[g_keyboardStroke.VirtualKey]] = 1 ;
				//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 ;
			}
		}
	}

	for ( int j = 0 ; j < 256 ; j++ )
	{
		if ( ( keyboard_keystate[j] == 1 ) && ( held_keys[j] == 0 ) )
		{
			if ( vkey_to_fkb[j] >= 0 )
				fkbkeys[vkey_to_fkb[j]] = 0 ;
			//if ( vkey_to_amiga[j] )
				//handle_input_event( vkey_to_amiga[j], 0, 1, 0 ) ;
			keyboard_keystate[j] = 0 ;
		}

	}
#endif
#endif

#ifdef LIGHTGUN

	m_zapperDat[2] = 0 ;

	DWORD mmoved = XBInput_GetMouseInput();
	int clearzapper = 0 ;

	if ( ( g_nes_input1 == 2 ) ||  ( g_nes_input2 == 2 )  )
	{
		if ( doZapper() == 0 )
		{
			for ( int i = 0 ; i < 4 ; i++ )
			{
				if ( g_hMouseDevice[i] )
				{
					if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_LEFT_BUTTON )
					{
						m_zapperDat[2] = 1 ;
					}

					if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_RIGHT_BUTTON )
					{
						m_zapperDat[2] = 1 ;
						clearzapper = 1 ;
					}

					if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_MIDDLE_BUTTON )
					{
						m_zapperDat[2] = 1 ;
					}

					if ( mmoved & ( 1 << i ) )
					{
						m_zapperDat[0] += (g_MouseState[i].DebugMouse.cMickeysX/2)  ;
						m_zapperDat[1] += (g_MouseState[i].DebugMouse.cMickeysY/2)  ;
					}
				}

			}

			if ( g_nes_input1 == 2 )
			{
				if (g_Gamepads[0].hDevice)
				{
					if ( abs(g_Gamepads[0].sThumbLX) > 6000 )
						m_zapperDat[0] += (( (g_Gamepads[0].sThumbLX-6000)/7000.0f));
					if ( abs(g_Gamepads[0].sThumbLY) > 6000 )
						m_zapperDat[1] -= (( (g_Gamepads[0].sThumbLY-6000)/7000.0f));

				}
				if ( g_app->m_emuControllers[0] & JOY_A )
					m_zapperDat[2] = 1 ;
				if ( g_app->m_emuControllers[0] & JOY_B ) 
				{
					m_zapperDat[2] = 1 ;
					clearzapper = 1 ;
				}

				//else
					//m_zapperDat[2] = 0 ;
			}
			else
			{
				if (g_Gamepads[0].hDevice)
				{
					if ( abs(g_Gamepads[0].sThumbLX) > 6000 )
						m_zapperDat[0] += (( (g_Gamepads[0].sThumbLX-6000)/7000.0f));
					if ( abs(g_Gamepads[0].sThumbLY) > 6000 )
						m_zapperDat[1] -= (( (g_Gamepads[0].sThumbLY-6000)/7000.0f));


				}
				if ( g_app->m_emuControllers[0] & JOY_A )
					m_zapperDat[2] = 1 ;
				if ( g_app->m_emuControllers[0] & JOY_B ) 
				{
					m_zapperDat[2] = 1 ;
					clearzapper = 1 ;
				}
			}
			if ( clearzapper )
			{
				m_zapperDat[0] = m_zapperDat[1] = 0 ;
			}
			else
			{
				if ( m_zapperDat[0] < 0 )
					m_zapperDat[0] = 0 ;
				if ( m_zapperDat[0] > 256 )
					m_zapperDat[0] = 260 ;
				if ( m_zapperDat[1] < 0 )
					m_zapperDat[1] = 0 ;
				if ( m_zapperDat[1] > 240 )
					m_zapperDat[1] = 243 ;
			}

			if ( ( m_zapperDat[0] > 0 ) && ( m_zapperDat[0] < 256 ) && ( m_zapperDat[1] > 0 ) && ( m_zapperDat[1] < 240 ) )
			{
				m_lightgun.wButtons |= XINPUT_LIGHTGUN_ONSCREEN ;
			}
			else
			{
				m_lightgun.wButtons = 0;
			}

			FLOAT fWidth = 640.0f *VIDEOMODES[m_xboxVidmode].multx;
			FLOAT fHeight = 480.0f *VIDEOMODES[m_xboxVidmode].multy;
			FLOAT fThumbLX ;
			FLOAT fThumbLY ;

			fThumbLX = (((float)m_zapperDat[0]*(float)m_nScreenMaxX)/256.0)+m_nScreenX   ;
			fThumbLY = (((float)m_zapperDat[1]*(float)m_nScreenMaxY)/240.0)+m_nScreenY   ;

			m_lightgun.sThumbLX = ((( fThumbLX - (fWidth/2))*32767.5f)/(fWidth/2)) - 0.5f ;
			m_lightgun.sThumbLY = ((( (fHeight/2) - fThumbLY)*32767.5f)/(fHeight/2)) - 0.5f ;
		}
	}

	for ( int i = 0 ; i < 2 ; i++ )
	{
		
		if ( ( ( i==0 ) && ( g_nes_input1 == 4 ) && g_hMouseDevice[i]) ||
			 ( ( i==1 ) && ( g_nes_input2 == 4 ) && g_hMouseDevice[i]) )
		{
			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_LEFT_BUTTON )
			{
				m_zapperDat[2] = 1 ;
			}

			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_RIGHT_BUTTON )
			{
				m_zapperDat[2] = 1 ;
			}

			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_MIDDLE_BUTTON )
			{
				m_zapperDat[2] = 1 ;
			}

			if ( mmoved & ( 1 << i ) )
			{
				m_mouseX += g_MouseState[i].DebugMouse.cMickeysX  ;
				m_mouseY += g_MouseState[i].DebugMouse.cMickeysY  ;
			}
		}

		if ( ( ( i==0 ) && ( g_nes_input1 == 4 ) && g_Gamepads[i].hDevice) ||
			 ( ( i==1 ) && ( g_nes_input2 == 4 ) && g_Gamepads[i].hDevice) )
		{
					if ( abs(g_Gamepads[i].sThumbLX) > 6000 )
					{
						m_mouseX += (( g_Gamepads[i].sThumbLX/6000.0f));
					}
					if ( abs(g_Gamepads[i].sThumbLY) > 6000 )
					{
						m_mouseY -= (( g_Gamepads[i].sThumbLY/6000.0f));
					}
		}
		
	}

	if ( m_mouseX < 0  )
		m_mouseX = 0 ;
	if ( m_mouseX > 255 )
		m_mouseX = 255 ;
	if ( m_mouseY < 0 )
		m_mouseY = 0 ;
	if ( m_mouseY > 239 )
		m_mouseY = 239 ;

	if ( ( g_nes_input1 == 4 ) || ( g_nes_input2 == 4 ) ) 
	{
		m_zapperDat[0] = m_mouseX ;
		m_zapperDat[1] = m_mouseY ;
	}
#endif

#if MEDNA_TYPE == MEDNA_PCE
	m_pcemouseX = 0 ;
	m_pcemouseY = 0 ;
	DWORD mmoved = XBInput_GetMouseInput();
	for ( int i = 0 ; i < 4 ; i++ )
	{
		if ( g_hMouseDevice[i] )
		{
			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_LEFT_BUTTON )
			{
				g_app->m_emuControllers[0] |=  JOY_A ;
			}
			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_RIGHT_BUTTON )
			{
				g_app->m_emuControllers[0] |=  JOY_B ;
			}
			if ( g_MouseState[i].DebugMouse.bButtons & XINPUT_DEBUG_MOUSE_MIDDLE_BUTTON )
			{
				g_app->m_emuControllers[0] |=  JOY_START ;
			}
			if ( mmoved & ( 1 << i ) )
			{
				m_pcemouseX = (-g_MouseState[i].DebugMouse.cMickeysX)/2  ;
				m_pcemouseY = (-g_MouseState[i].DebugMouse.cMickeysY)/2  ;
			}
		}
		else if ( ( g_pce_controller == 2 ) && ( g_Gamepads[i].hDevice ) )
		{
					if ( abs(g_Gamepads[i].sThumbLX) > 6000 )
					{
						m_pcemouseX = -(( g_Gamepads[i].sThumbLX>>8));
					}
					if ( abs(g_Gamepads[i].sThumbLY) > 6000 )
					{
						m_pcemouseY = (( g_Gamepads[i].sThumbLY>>8));
					}
					m_pcemouseX /= 8 ;
					m_pcemouseY /= 8 ;
		}
		
	}

	if ( m_pcemouseX > 32 )
		m_pcemouseX = 32 ;
	if ( m_pcemouseX < -31 )
		m_pcemouseX = -31 ;
	if ( m_pcemouseY > 32 )
		m_pcemouseY = 32 ;
	if ( m_pcemouseY < -31 )
		m_pcemouseY = -31 ;


#endif
	return 0 ;
}


void CXBoxSample::xboxSaveState() 
{
	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 ;

		if ( m_bScreenshotSavestate )
		{
			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' ;
		}
		MD_SaveState( g_statefile ) ;

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

void CXBoxSample::xboxLoadState() 
{
	char szholder[500] ;

	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 ;

		MD_LoadState( g_statefile ) ;
		sleepamount = 60 ;
		g_app->applyGameGenie( g_ROM, g_ROMsize ) ;

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

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

	memset( g_pDeltaBuff, 0xFF, m_pitch*480 ) ;

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

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 ( strrchr( scr_filename, '.' ) == NULL )
				continue ;

			*(strrchr( 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;


	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 += xbox_get_pitch();
			
	
			
		if( writepng_encode_row(&wpng_info) != 0)
		{
			writepng_cleanup(&wpng_info);
			free(wpng_info.image_data) ;
			fclose( wpng_info.outfile )  ;
			return ; 

/*			fprintf(stderr, "WritePNG:  libpng problem (longjmp) while writing row %ld\n",
			wpng_info.height-j);
			++error;
			break;*/
		}
	}
		
		/*
	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 ;
}

void CXBoxSample::xboxThrottle( int xthrottle ) 
{

	throttling = xthrottle ;

	if ( xthrottle )
	{
		if ( throttle <= 0 )
			throttle = m_throttleSpeed ;
	}
	else
		throttle = 0 ;
	

}

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();
	g_app->doCheatMenu() ;
	g_app->applyGameGenie( g_ROM, g_ROMsize ) ;

	//m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	//m_pd3dDevice->Reset( &m_d3dpp ) ;
	m_numFrames = 0 ;
	m_startTime = GetTickCount() ;
}

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

	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) ;
		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 ;
}
/*
void CXBoxSample::checkGeneralEvents( )
{

	static int did_save_state[4] = { 0, 0, 0, 0} ;
	static int did_load_state[4] = { 0, 0, 0, 0} ;
	static int did_change_state[4] = { 0, 0, 0, 0} ;
	static int did_screenshot[4] = { 0, 0, 0, 0} ;
	static int did_change_gfx[4] = { 0, 0, 0, 0} ;
	static int did_toggle_bgm[4] = { 0, 0, 0, 0} ;

	int throttle ;

	throttle = 0 ;


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

		for ( int j = 0 ; j < 10 ; j++ )
		{
			if ( ( m_mappings[i].combos[j].mapping ) && ( ( m_xboxControllers[i] & m_mappings[i].combos[j].mapping ) == m_mappings[i].combos[j].mapping ) )
			{
				if ( m_mappings[i].combos[j].currmove == 0 )
				{
					m_mappings[i].combos[j].currmove = 1 ;
					m_mappings[i].combos[j].currdelay = m_mappings[i].combos[j].delay ;
				}
			}
			if ( m_mappings[i].combos[j].currmove )
			{
				if ( m_mappings[i].combos[j].currdelay )
				{
					m_mappings[i].combos[j].currdelay-- ;
					m_emuControllers[i] = m_mappings[i].combos[j].moves[ m_mappings[i].combos[j].currmove - 1] ;
				}
				else
				{
					m_mappings[i].combos[j].currmove++ ;
					if ( m_mappings[i].combos[j].currmove == m_mappings[i].combos[j].endmove + 1 )
					{
						m_mappings[i].combos[j].currmove = 0 ;
					}
					else
					{
						m_mappings[i].combos[j].currdelay = m_mappings[i].combos[j].delay ;
						m_emuControllers[i] = m_mappings[i].combos[j].moves[ m_mappings[i].combos[j].currmove - 1] ;
					}
				}
			}
		}

		if ( ( m_mappings[i].options_menu ) && ( ( m_xboxControllers[i] & m_mappings[i].options_menu ) == m_mappings[i].options_menu ) )
		{
			xboxOptionsMenu() ;
		}

		if ( ( m_mappings[i].save_state ) && ( ( m_xboxControllers[i] & m_mappings[i].save_state ) == m_mappings[i].save_state ) )
		{
			if ( ! did_save_state[i] )
			{
				xboxSaveState() ;
			}
			did_save_state[i] = 1 ;
		}
		else
		{
			did_save_state[i] = 0 ;
		}

		if ( ( m_mappings[i].load_state ) && ( ( m_xboxControllers[i] & m_mappings[i].load_state ) == m_mappings[i].load_state ) )
		{
			if ( ! did_load_state[i] )
			{
				xboxLoadState() ;
			}
			did_load_state[i] = 1 ;
		}
		else
		{
			did_load_state[i] = 0 ;
		}

		if ( ( m_mappings[i].change_save_slot ) && ( ( m_xboxControllers[i] & m_mappings[i].change_save_slot ) == m_mappings[i].change_save_slot ) )
		{
			if ( ! did_change_state[i] )
			{
				xboxChangeState() ;
			}
			did_change_state[i] = 1 ;
		}
		else
		{
			did_change_state[i] = 0 ;
		}


		if ( ( m_mappings[i].screenshot ) && ( ( m_xboxControllers[i] & m_mappings[i].screenshot ) == m_mappings[i].screenshot ) )
		{
			if ( ! did_screenshot[i] )
			{
				xboxScreenshot() ;
			}
			did_screenshot[i] = 1 ;
		}
		else
		{
			did_screenshot[i] = 0 ;
		}

		if ( ( m_mappings[i].change_gfx_filter ) && ( ( m_xboxControllers[i] & m_mappings[i].change_gfx_filter ) == m_mappings[i].change_gfx_filter ) )
		{
			if ( ! did_change_gfx[i] )
			{
				xboxChangeFilter() ;
			}
			did_change_gfx[i] = 1 ;
		}
		else
		{
			did_change_gfx[i] = 0 ;
		}

		if ( ( m_mappings[i].toggle_bgm ) && ( ( m_xboxControllers[i] & m_mappings[i].toggle_bgm ) == m_mappings[i].toggle_bgm ) )
		{
			if ( ! did_toggle_bgm[i] )
			{
				m_mp3player.pause( ! m_mp3player.m_bPaused ) ;
			}
			did_toggle_bgm[i] = 1 ;
		}
		else
		{
			did_toggle_bgm[i] = 0 ;
		}


		if ( ( m_mappings[i].sfx_vol_up ) && ( ( m_xboxControllers[i] & m_mappings[i].sfx_vol_up ) == m_mappings[i].sfx_vol_up ) )
		{
			m_sound.adjust_volume( 5 ) ;
		}
		if ( ( m_mappings[i].sfx_vol_down ) && ( ( m_xboxControllers[i] & m_mappings[i].sfx_vol_down ) == m_mappings[i].sfx_vol_down ) )
		{
			m_sound.adjust_volume( -5 ) ;
		}
		if ( ( m_mappings[i].bgm_vol_up ) && ( ( m_xboxControllers[i] & m_mappings[i].bgm_vol_up ) == m_mappings[i].bgm_vol_up ) )
		{
			m_mp3player.adjust_volume( 5 ) ;
		}
		if ( ( m_mappings[i].bgm_vol_down ) && ( ( m_xboxControllers[i] & m_mappings[i].bgm_vol_down ) == m_mappings[i].bgm_vol_down ) )
		{
			m_mp3player.adjust_volume( -5 ) ;
		}

		if ( ( m_mappings[i].throttle ) && ( ( m_xboxControllers[i] & m_mappings[i].throttle ) == m_mappings[i].throttle ) )
			throttle = 1 ;

	
	
	}

	xboxThrottle( throttle ) ;
}
*/

int ReadJoypad( int port )
{

	unsigned int value ;
	char xmsg[100] ;


	value = 0xFFFF ;

	g_app->updateCheats2() ;
	if ( g_app->pollXBoxControllers() )
	{
		//Running = 0 ;
		g_app->m_state = MAIN_MENU ;
		return value ;
	}


	g_app->checkGeneralEvents() ;	

	if ( g_app->m_bNetplay )
	{
		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] ;
		}
	}

	value = ( ~(g_app->m_emuControllers[port] ) ) & 0xFFFF ;

	if ( g_app->m_state == MAIN_MENU )
	{
		value |= 0x10000 ;
		//Running = 0 ;
	}
/*	
	
	XBInput_GetInput();

	if ( g_Gamepads[port].hDevice )
	{

		if(g_Gamepads[port].wButtons & XINPUT_GAMEPAD_LEFT_THUMB )
		{
			g_app->m_state = IN_GAME_PAUSED ;
			g_app->m_sound.pause( TRUE ) ;
			g_app->m_cdda.pause(TRUE) ;
			g_app->m_mp3player.pause( TRUE ) ;
			g_app->m_dwStartPause = GetTickCount();
			g_app->doCheatMenu() ;

			if ( g_app->m_state == MAIN_MENU )
			{
				value |= 0x10000 ;
				Running = 0 ;
			}
		}
		if(g_Gamepads[port].wPressedButtons & XINPUT_GAMEPAD_RIGHT_THUMB )
		{
			if ( g_app->m_bitDepth == 16 )
				g_app->m_xboxSFilter = (g_app->m_xboxSFilter+1)%NUM_SOFTWARE_FILTERS ;
			else
				g_app->m_xboxSFilter = 0 ;
		}

		if ( g_app->getButtonState( port, g_app->m_bMappingCross ) )
			value &= ~JOY_CROSS ;
		if ( g_app->getButtonState( port, g_app->m_bMappingSquare ) )
			value &= ~JOY_SQUARE ;
		if ( g_app->getButtonState( port, g_app->m_bMappingTriangle ) )
			value &= ~JOY_TRIANGLE ;
		if ( g_app->getButtonState( port, g_app->m_bMappingCircle ) )
			value &= ~JOY_CIRCLE ;
		if ( g_Gamepads[port].wButtons & XINPUT_GAMEPAD_DPAD_LEFT )
			value &= ~JOY_LEFT ;
		if ( g_Gamepads[port].wButtons & XINPUT_GAMEPAD_DPAD_UP )
			value &= ~JOY_UP ;
		if ( g_Gamepads[port].wButtons & XINPUT_GAMEPAD_DPAD_RIGHT )
			value &= ~JOY_RIGHT ;
		if ( g_Gamepads[port].wButtons & XINPUT_GAMEPAD_DPAD_DOWN )
			value &= ~JOY_DOWN ;
		if ( g_app->getButtonState( port, g_app->m_bMappingStart ) )
			value &= ~JOY_START ;
		if ( g_app->getButtonState( port, g_app->m_bMappingSelect ) )
			value &= ~JOY_SELECT ;

		if ( g_app->getButtonState( port, g_app->m_bMappingR1 ) )
			value &= ~JOY_R1 ;
		if ( g_app->getButtonState( port, g_app->m_bMappingL1 ) )
			value &= ~JOY_L1 ;
		if ( g_app->getButtonState( port, g_app->m_bMappingR2 ) )
			value &= ~JOY_R2 ;
		if ( g_app->getButtonState( port, g_app->m_bMappingL2 ) )
			value &= ~JOY_L2 ;

		
		if ( ( g_Gamepads[port].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) && 
			 (g_Gamepads[port].bPressedAnalogButtons[XINPUT_GAMEPAD_WHITE]) )
		{
			LoadState( g_app->g_statefile ) ;
		}
		else if ( ( g_Gamepads[port].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) && 
			 (g_Gamepads[port].bPressedAnalogButtons[XINPUT_GAMEPAD_BLACK]) )
		{
			SaveState( g_app->g_statefile ) ;
		}

		//sprintf( xmsg, "x=%d,y=%d,x=%d,y=%d\r\n", g_Gamepads[port].sThumbRX, g_Gamepads[port].sThumbRX, g_Gamepads[port].fX2, g_Gamepads[port].fY2 ) ;

		if ( fabs(g_Gamepads[port].fX2) > 0.10f )
		{
			g_app->m_sound.adjust_volume( (int) ( g_Gamepads[port].fX2 * 25.0 ) ) ;
		}
		if ( fabs( g_Gamepads[port].fY2 ) > 0.10f )
		{
			g_app->m_cdda.adjust_volume( (int) ( g_Gamepads[port].fY2 * 25.0 ) ) ;
			g_app->m_mp3player.adjust_volume( (int) ( g_Gamepads[port].fY2 * 25.0 ) ) ;
		}

		if ( g_Gamepads[port].fX1 > 0.05f )
			value &= ~JOY_RIGHT ;

		if ( g_Gamepads[port].fX1 < -0.05f )
			value &= ~JOY_LEFT ;

		if ( g_Gamepads[port].fY1 > 0.05f)
			value &= ~JOY_UP ;
		
		if ( g_Gamepads[port].fY1 < -0.05f)
			value &= ~JOY_DOWN ;

	}

	if ( g_app->getButtonState( 0, g_app->m_bMappingThrottle ) > 200 )
	{
		iFastFwd = 1 ;
	}
	else
	{
		iFastFwd = 0 ;
	}
*/

	value = ((value>>8)&0xFF) | ( (value<<8) & 0xFF00 );
	return value ;
}






#define CD_SECS 60
#define CD_FRAMES 75

void CXBoxSample::loadCueSheet( char *cuefile ) 
{
	FILE  *infile ;
	char  *cuedata ;
	unsigned int filesize ;
	char  *line ;
	char  *rpos ;
	char  *npos ;
	char  *msf ;
	char  *stringpos ;
	byte  mins, secs, frms, track, tracktype ;
	char  trackfilename[256] ;
	char  *tok ;
	int   sectorA, sectorB ;
	char  *lastslashA ;
	char  *lastslashB ;
	//char  xmsg[100] ;
	int   totalsectors ;
	int smbfile ;
	int dosamba = 0 ;

	memset( trackfilename, 0, 256 ) ;

	track = mins = secs = frms = 0 ;

	writexbox( "about to open cue\r\n" ) ;



	dosamba = ( ( strncmp( cuefile, "SMB:", 4 ) == 0 ) || ( strncmp( cuefile, "smb:", 4 ) == 0 ) ) ;

	if ( dosamba ) 
	{
		char smbfilename[1024] ;
		char *smbp ;
		FILE *outfile ;
		char *buf ;

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

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

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

		if ( smbfile <= 0  )
		{
			return ;
		}

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

		cuedata = (char*)malloc( filesize+1 ) ;
		memset( cuedata, 0, filesize+1 ) ;

		m_smb.read( smbfile, cuedata, filesize ) ;

		m_smb.close( smbfile ) ;
	}
	else if ( m_bUsingRelax )
	{
		if ( m_relax.Open( cuefile ) )
		{
			filesize = m_relax.GetLength() ;

			cuedata = (char*)malloc( filesize+1 ) ;

			if ( !cuedata )
			{
				m_relax.Close() ;
				return ;
			}

			memset( cuedata, 0, filesize+1 ) ;

			if ( ! m_relax.ReadAll( cuedata, filesize ) )
			{
				free(cuedata) ;
				m_relax.Close() ;
				return ;
			}

			m_relax.Close() ;

		}
		else
		{
			return ;
		}
	}
	else
	{

		infile = fopen( cuefile, "rb" ) ;

		if ( !infile )
		{
			return ;
		}

		fseek( infile, 0, SEEK_END ) ;
		filesize = ftell( infile ) ;
		fseek( infile, 0, SEEK_SET ) ;

		//sprintf( xmsg, "cuesize=%u\r\n", filesize ) ;
		//writexbox( xmsg ) ;

		cuedata = (char*)malloc( filesize+1 ) ;
		memset( cuedata, 0, filesize+1 ) ;

		fread( cuedata, sizeof(char), filesize, infile ) ;

		fclose( infile ) ;
	}

	writexbox( "allocated and closed file\r\n" ) ;

	line = cuedata ;


	while ( *line )
	{
		writexbox( "top loop\r\n" ) ;

		rpos = strchr( line, '\r' ) ;
		npos = strchr( line, '\n' ) ;

		if ( npos > rpos )
			rpos = npos ;

		if ( rpos )
			*rpos = 0 ;

		//writexbox( "removed trailing line\r\n" ) ;

		strupr( line ) ;

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

		if ( stringpos = strstr( line, "TRACK " ) )
		{
			//writexbox( "gottrack\r\n" ) ;
			if ( strstr( line, "AUDIO" ) )
				tracktype = 0 ;
			else
				tracktype = 4 ;

			tok = strtok( stringpos+5, " \t\r\n" ) ;


			track = atoi( tok ) ;


			if ( ( track < 0 ) || ( track > 255 ) )
			{
				track = 255 ;
			}


		}
		else if ( ( stringpos = strstr( line, "INDEX 1 " ) ) || ( stringpos = strstr( line, "INDEX 01 " ) ) )
		{
			//writexbox( "gotindex\r\n" ) ;
			msf = strtok( stringpos+8, " \t\r\n" ) ;
			if ( strlen(msf) >= 8 )
			{
				*(msf+2) = 0 ;
				*(msf+5) = 0 ;
				*(msf+8) = 0 ;

				mins = atoi( msf ) ;
				secs = atoi( msf+3 ) ;
				frms = atoi( msf+6 ) ;

				if ( secs > 57 )  //account for standard gap that seems to appear on all cue sheets
				{
					secs = secs + 2 - 60 ;
					mins++ ;
				}
				else
				{
					secs += 2 ;
				}
			}




			if ( dosamba && tracktype)
			{
				char holder[500] ;
				char *smbp ;

				strcpy(holder, cuefile ) ;

				*strrchr( holder, '\\' ) = 0 ;

				strlwr(trackfilename) ;

			}
			else if ( dosamba )
			{
				strlwr(trackfilename) ;
			}
		}
		else if ( stringpos = strstr( line, "FILE " ) )
		{
			//writexbox( "gotfile\r\n" ) ;
			tok = strtok( stringpos+4, " \r\n\t\"" ) ;

			lastslashA = strrchr( tok, '/' ) ;
			lastslashB = strrchr( tok, '\\' ) ;

			if ( lastslashB > lastslashA )
				lastslashA = lastslashB ;

			if ( lastslashB )
			{
				*lastslashB = 0 ;
				tok = lastslashB + 1 ;
			}
			
			if ( dosamba )
			{
				strcpy( trackfilename, tok ) ;
			}
			else
			{
				strcpy( trackfilename, m_szCurrentDir ) ;
				strcat( trackfilename, tok ) ;

				sprintfx( trackfilename ) ;
			}

		}

		line = rpos + 1 ;

		if ( line - cuedata >= filesize )
			break ;

	}

	totalsectors = 0 ;


/*


  CD_track[1].beg_min = binbcd[00];
  CD_track[1].beg_sec = binbcd[02];
  CD_track[1].beg_fra = binbcd[00];

  CD_track[1].type = 0;
  CD_track[1].beg_lsn = 0;	// Number of sector since the
  // beginning of track 1

  CD_track[1].length = 47 * CD_FRAMES + 65;	// Most common

  // CD_track[0x01].length=53 * CD_FRAMES + 65;

  // CD_track[0x01].length=0 * CD_FRAMES + 16;


// Fra = CD_track[0x01].length % CD_FRAMES;
// Sec = (CD_track[0x01].length) % (CD_FRAMES * CD_SECS) / CD_SECS;
// Min = (CD_track[0x01].length) (CD_FRAMES * CD_SECS);

// Second track is the main code track
  unsigned char Min, Sec, Fra ;
  nb_sect2msf (CD_track[1].length, &Min, &Sec, &Fra);

  CD_track[2].beg_min = binbcd[bcdbin[CD_track[1].beg_min] + Min];
  CD_track[2].beg_sec = binbcd[bcdbin[CD_track[1].beg_sec] + Sec];
  CD_track[2].beg_fra = binbcd[bcdbin[CD_track[1].beg_fra] + Fra];

  CD_track[2].type = 4;
  CD_track[2].beg_lsn =
    msf2nb_sect (bcdbin[CD_track[2].beg_min] - bcdbin[CD_track[1].beg_min],
		 bcdbin[CD_track[2].beg_sec] - bcdbin[CD_track[1].beg_sec],
		 bcdbin[CD_track[2].beg_fra] - bcdbin[CD_track[1].beg_fra]);

for ( int i = 1 ; i < 4 ; i++ )
{
		sprintfx("trk=%u,type=%u,min=%u,sec=%u,fra=%u,lsn=%u,length=%ufilename=%s\r\n", i, CD_track[i].type, 
			bcdbin[CD_track[i].beg_min], bcdbin[CD_track[i].beg_sec], bcdbin[CD_track[i].beg_fra], 
			CD_track[i].beg_lsn, CD_track[i].length, CD_track[i].filename ) ;
}
*/
	free (cuedata) ;

	writexbox( "returning from cue\r\n" ) ;

}

void xbox_errormessage( const char *s) 
{
	g_app->popupMsg( (char*)s, &(g_app->m_pnlGameScreen) ) ;
}


void CXBoxSample::initConsole( UINT32 idx, int isFavorite, int forceConfig )
{
	char                filename[500] ;
	char                caseval[500] ;
	char systemcard[200] ;
	int isSelectMenu = 1 ;
	int copySamba = 1 ;
	char tmpfilename[500] ;
	char shortpath[100] ;
	int isoOrBin = 0 ;

	global_error_message[0] = 0 ;

	sleepamount = 0 ;

	m_numFrames = 0 ;
	m_startTime = GetTickCount() ;
	m_droppedFrames = 0 ;
	m_currentStartSector = 9999999 ;
	g_currentTrack = 0 ;

	g_cdr_readmethod = 0 ;

	g_rewind_enabled = 0 ;

	MDFNI_EnableStateRewind( g_rewind_enabled ) ;

//	soundChannels = 0xFF ;
//	bkgHalt = 0 ;


	throttle = 0 ;
	blittermode = 1 ;

	memset( m_memMatches, 1, CONSOLE_MEMORY_SIZE ) ;
	m_currentMemMatches = CONSOLE_MEMORY_SIZE ;
	m_numCheats = 0 ;


	if ( idx == 0xFFFFFFFF ) //launch cd
	{
		CdIo *p_cdio;
		int numtracks ;
		int firsttrack ;
		unsigned int firstlsn ;
		int numsectors ;
		unsigned int CRC ;

		CRC = -1 ;

		p_cdio = cdio_open_cd(NULL);

		if(!p_cdio) 
		{
			popupMsg( "Could not open CD - aborting", &m_pnlBackgroundSelect ) ;
			return ;
		}

		numtracks = cdio_get_num_tracks(p_cdio);
		firsttrack = cdio_get_first_track_num(p_cdio) ;
		unsigned char buf[17*2352] ;

		for ( int i = firsttrack ; i < firsttrack+numtracks-1 ; i++ )
		{
			if ( cdio_get_track_format(p_cdio, i) == TRACK_FORMAT_DATA )
			{
				firstlsn =  cdio_get_track_lsn( p_cdio, i );
				numsectors = cdio_get_track_sec_count( p_cdio, i );

				for ( int s = 0 ; s < 128 ; s += 16 )
				{
					if ( cdio_read_mode1_sectors( p_cdio, buf, firstlsn+s, false, 16) != 0 )
						break ;

					for (int index = 0; index < 16*2048; index++)
					{
						buf[index] ^= CRC;
						CRC >>= 8;
						CRC ^= TAB_CONST2[buf[index]];
					}

				}

				CRC = ~CRC;

				sprintf( filename, "D:\\CDROM_%02.2X%02.2X%02.2X%02.2X", (CRC>>24)&0xFF, (CRC>>16)&0xFF, (CRC>>8)&0xFF, (CRC)&0xFF ) ;
				break ;
			}
		}
/*
				firstlsn =  cdio_get_track_lsn( p_cdio, firsttrack+1 );
				numsectors = cdio_get_track_sec_count( p_cdio, firsttrack+1 );
				int csum = 0 ;

				while ( numsectors >= 16 )
				{
					if ( cdio_read_mode2_sectors( p_cdio, buf, firstlsn, false, 16) != 0 )
					{
						firstlsn = firstlsn ;
					}
					else
					{
						firstlsn = firstlsn ;
					}
					firstlsn += 16 ;
					numsectors -= 16 ;

					csum = 0 ;

					for ( int p = 0 ; p < 12000 ; p++ )
					{
						csum += buf[p] ;
					}

					if ( csum > 0 )
					{
						csum = csum ;
					}
				}
*/
		/*
  discmode_t cdio_get_discmode (CdIo_t *p_cdio);
  lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track);
  lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track);
  unsigned int cdio_get_track_sec_count(const CdIo_t *p_cdio, track_t i_track);

  driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio, 
						void *p_buf, lsn_t i_lsn, 
						bool b_form2, 
						unsigned int i_sectors);

  driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio, 
						void *p_buf, lsn_t i_lsn, 
						bool b_form2, 
						unsigned int i_sectors);
  driver_return_code_t cdio_eject_media (CdIo_t **p_cdio);
  void cdio_destroy (CdIo_t *p_cdio);
  
  return(cdio_get_track_lsn(p_cdrfile->p_cdio, i_track));
		track_format_t   return(cdio_get_track_format(p_cdrfile->p_cdio, i_track));
		while(0 != cdio_read_mode1_sectors(p_cdrfile->p_cdio, buf, lsn, b_form2, i_sectors))
		return(cdio_stat_size(p_cdrfile->p_cdio));
*/
		cdio_destroy( p_cdio ) ;

		loaded_cue = 2 ;
	}
	else
	{
	
		if ( isFavorite )
		{
			strcpy( (char*)filename, m_filesFavorites[idx].filename ) ;
		}
		else
		{
			if ( g_autoLaunchGame )
			{
				strcpy( (char*)filename, g_launchData.szFilename ) ;
			}
			else
			{
				strcpy((char*)filename, m_szCurrentDir ) ;
				strcat( (char*)filename, (const char*)files[idx].filename ) ;
			}
		}

		loaded_cue = 0 ;
	}	
	

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




	strcpy( g_cuefile, "" ) ;


	char *p;

	xbox_compatible_name( filename, shortpath ) ;

	//writexbox( "init1" ) ;

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

	strcpy( g_savedir, g_saveprefix ) ;
	CreateDirectory( g_saveprefix, NULL ) ;

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

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

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

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

	strcpy(g_fdsfile, g_saveprefix);
	strcat(g_fdsfile, ".fds");

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

	sprintf( g_statefile, "%s.sta", g_saveprefix ) ;


	sprintfx( "initconsole\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 ) ;
			}
		}
	}


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

	if (strstr (strupr(filename), ".MP3"))
	{
		if ( m_mp3player.loadFile( caseval, 1, 0, 70*60*75 ) )
		{
			popupMsg( "Could not load MP3 file", &m_pnlBackgroundSelect ) ;
			return ;
		}
		else
		{
			m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}
	else if ( (strstr (filename, ".M3U")) || (strstr (filename, ".m3u")) )
	{
		if ( m_mp3player.loadPlaylist( caseval ) )
		{
			popupMsg( "Could not load M3U playlist", &m_pnlBackgroundSelect ) ;
			//writexbox( "nonomp3\r\n") ;
			return ;
		}
		else
		{
			//m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}
	else if (strstr (strupr(filename), ".CUE"))
	{
		writexbox( "processing cue\r\n" ) ;

		strcpy( g_cuefile, caseval ) ;
		//loadCueSheet( g_cuefile ) ;
		//filename[0] = 0 ;


		//sprintf( xmsg, "filename fom cue=%s", filename ) ;
		//writexbox( xmsg ) ;

		loaded_cue = 1 ;
		copySamba = 0 ;


	}
	else if ( strstr( filename, ".ISO" ) )
	{
		popupMsg( "Select the CUE sheet file instead.", &m_pnlBackgroundSelect ) ;
		return ;
	}
	else if ( strstr( filename, ".BIN" ) )
	{
		popupMsg( "Select the CUE sheet file instead.", &m_pnlBackgroundSelect ) ;
		return ;
	}





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


	if ( forceConfig || loadSettings( g_settingsfile ) )
	{
		changeMenu( &m_skin.gameSelectMenu, &m_skin.otherMenu ) ;
		doConfigureGame( g_settingsfile, g_keysfile ) ;
		isSelectMenu = 0 ;
	}
	else
	{
		loadKeys( g_keysfile ) ;
	}

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



	if ( m_bNetplay )
	{
		if ( setupNetplay() )
			return ;
	}

	if ( g_autoLaunchGame )
	{
		m_pnlSplashGame.Render() ;
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
	}
	else
	{
		if ( isSelectMenu )
		{
			doTransition( &m_pnlBackgroundSelect, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
		else
		{
			doTransition( &m_pnlBackgroundOther, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
	}

	if ( !m_bBgmInGame )
	{
		m_mp3player.pause( TRUE ) ;
	}
	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;

	sprintfx("initconsole\r\n") ;


	//m_plaything.FreeSprites() ;

	sprintf( tmpfilename, "%s\\%s\\SPRITES\\*", m_szSkinDir, m_szSkin) ;



	if ( m_bUsingSamba && !loaded_cue)
	{
		char smbfilename[1024] ;
		char *smbp ;
		FILE *outfile ;
		char *buf ;

		strcpy( filename, caseval) ;

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

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

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


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


		strcpy( filename, smbfilename ) ;

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

		if ( copySamba )
		{

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

			if ( m_smbCdFile <= 0 )
			{
				popupMsg( "Could not open SMB file", &m_pnlBackgroundSelect ) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

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

			sprintfx( "copy samba\r\n") ;

			sprintf( filename, "X:\\%s", shortpath ) ;

			sprintfx( "copy samba %s %d\r\n", filename, filesize ) ;

			outfile = fopen( filename, "wb") ;

			sprintfx( "copy samba\r\n") ;
			if ( outfile == NULL )
			{
				m_smb.close( m_smbCdFile ) ;
				popupMsg( "Could not open X:\\ file for writing - perhaps X: is full?", &m_pnlBackgroundSelect ) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

			xbox_print_memory() ;

			buf = (char*) malloc(filesize) ;

			if ( buf == NULL )
			{
				popupMsg( "Could not allocate memory for copy samba", &m_pnlBackgroundSelect) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

			m_smb.read(m_smbCdFile,buf, filesize) ;

			sprintfx( "copy samba\r\n") ;

			fwrite( buf, 1, filesize, outfile ) ;
			fclose( outfile) ;
			m_smb.close( m_smbCdFile ) ;

			sprintfx( "copy samba\r\n") ;

			free(buf) ;
		}

	}
	else if ( m_bUsingRelax && !loaded_cue )
	{
		char rlxfilename[1024] ;
		FILE *outfile ;
		int filesize ;
		char *fbuf ;

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


				sprintf( rlxfilename, "X:\\%s", shortpath ) ;
				strcpy(filename, rlxfilename) ;

				outfile = fopen(filename, "wb") ;

				if ( outfile == NULL )
				{
					m_relax.Close( ) ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}


				fbuf = (char*) malloc( filesize ) ;

				if ( !fbuf )
				{
					m_relax.Close() ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}

				if ( ! m_relax.ReadAll( fbuf, filesize ) )
				{
					free(fbuf) ;
					m_relax.Close() ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}

				m_relax.Close() ;

				fwrite( fbuf, 1, filesize, outfile ) ;
				fclose( outfile ) ;
				free(fbuf) ;
			}
			else
			{
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}
		}

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

		strcpy( filename, caseval) ;

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


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

			outfile = fopen(filename, "wb") ;

			if ( outfile == NULL )
			{
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}


			fbuf = (char*) malloc( filesize ) ;

			if ( !fbuf )
			{
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			if ( ! m_iso9660.ReadFile( isofd, (byte*)fbuf, filesize ) )
			{
				free(fbuf) ;
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			m_iso9660.CloseFile(isofd) ;

			fwrite( fbuf, 1, filesize, outfile ) ;
			fclose( outfile ) ;
			free(fbuf) ;
		}
		else
		{
			m_plaything.LoadSprites( tmpfilename ) ;
			return ;
		}
	}


//	nonoise = 0 ;
	

	m_sound.init() ;
	m_cdda.init() ;
	m_mp3player_cdda.init() ;
	//m_mp3player.init() ;

	//writexbox( "init1" ) ;
	cht_load() ;

	// Create our texture
	init_texture();


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





	m_fAppTime = 0.0f ;

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

	m_steps = 0 ;

	//writexbox( "init4" ) ;
	//Then start it up

	//m_sound.insertSilence( 22050 ) ;
	m_sound.pause( FALSE ) ;
	m_cdda.pause( FALSE ) ;
	m_mp3player_cdda.pause(FALSE) ;
	//m_mp3player.insertSilence( 22050 ) ;
	//m_mp3player.pause( FALSE ) ;


	xbox_set_refreshrate( g_nes_pal ? 50 : 60 ) ;

	sprintfx("initconsole\r\n") ;

	m_state = IN_GAME ;

	//if ( VIDEOMODES[m_xboxVidmode].width > 720 )
	{
		m_plaything.FreeSprites() ;
		freeTextures() ;

		memcpy( &m_ptConfig, &(m_skin.otherMenu.ptConfig), sizeof(m_ptConfig) ) ;
		SetupPlaything() ;
	}

	QueryPerformanceCounter((union _LARGE_INTEGER *) m_performancePrev);

	applyHardwareFilter() ;

	m_mouseX = 100 ; 
	m_mouseY = 100 ;

	sprintfx( "initconsole %s %s %s\r\n", filename, g_sramfile, g_saveprefix ) ;

	if ( loaded_cue ==2 )
		mednafen_main( NULL, loaded_cue ) ;
	else
		mednafen_main( filename, loaded_cue ) ;
	//hugomain( filename, g_sramfile, g_saveprefix, systemcard, 0, m_forceUS ) ;

	g_app->m_mp3player_cdda.stop() ;


	//if ( VIDEOMODES[m_xboxVidmode].width > 720 )
	{
		m_plaything.FreeSprites() ;
		sprintf( tmpfilename, "%s\\%s\\SPRITES\\*", m_szSkinDir, m_szSkin) ;
		m_plaything.LoadSprites( tmpfilename ) ;
	}

	writexbox( "initout" ) ;
	m_state=MAIN_MENU ;
	saveKeys( g_keysfile ) ;
	writexbox( "initout" ) ;
	saveSettings( g_settingsfile ) ;
	writexbox( "initout" ) ;
	cleanupConsole() ;
	writexbox( "initout" ) ;

	throttle = 0 ;
	throttling = 0 ;

	//put 3 frames of data in the audio buffer
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;


}
#if 0
void CXBoxSample::doCDGame2()
{
	char                filename[500] ;
	char                caseval[500] ;
	char systemcard[200] ;
	int isSelectMenu = 1 ;
	int copySamba = 1 ;
	char tmpfilename[500] ;
	char shortpath[100] ;
	int isoOrBin = 0 ;

	global_error_message[0] = 0 ;

	sleepamount = 0 ;

	m_numFrames = 0 ;
	m_startTime = GetTickCount() ;
	m_droppedFrames = 0 ;
	m_currentStartSector = 9999999 ;

//	soundChannels = 0xFF ;
//	bkgHalt = 0 ;


	throttle = 0 ;
	blittermode = 1 ;

	memset( m_memMatches, 1, CONSOLE_MEMORY_SIZE ) ;
	m_currentMemMatches = CONSOLE_MEMORY_SIZE ;
	m_numCheats = 0 ;


	
	if ( isFavorite )
	{
		strcpy( (char*)filename, m_filesFavorites[idx].filename ) ;
	}
	else
	{
		if ( g_autoLaunchGame )
		{
			strcpy( (char*)filename, g_launchData.szFilename ) ;
		}
		else
		{
			strcpy((char*)filename, m_szCurrentDir ) ;
			strcat( (char*)filename, (const char*)files[idx].filename ) ;
		}
	}

	
	

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

	loaded_cue = 0 ;



	strcpy( g_cuefile, "" ) ;


	char *p;

	xbox_compatible_name( filename, shortpath ) ;

	//writexbox( "init1" ) ;

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

	strcpy( g_savedir, g_saveprefix ) ;
	CreateDirectory( g_saveprefix, NULL ) ;

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

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

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

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

	strcpy(g_fdsfile, g_saveprefix);
	strcat(g_fdsfile, ".fds");

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

	sprintf( g_statefile, "%s.sta", g_saveprefix ) ;


	sprintfx( "initconsole\r\n") ;


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

	if (strstr (strupr(filename), ".MP3"))
	{
		if ( m_mp3player.loadFile( caseval, 1, 0, 70*60*75 ) )
		{
			popupMsg( "Could not load MP3 file", &m_pnlBackgroundSelect ) ;
			return ;
		}
		else
		{
			m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}
	else if ( (strstr (filename, ".M3U")) || (strstr (filename, ".m3u")) )
	{
		if ( m_mp3player.loadPlaylist( caseval ) )
		{
			popupMsg( "Could not load M3U playlist", &m_pnlBackgroundSelect ) ;
			//writexbox( "nonomp3\r\n") ;
			return ;
		}
		else
		{
			//m_mp3player.insertSilence( 22050 ) ;
			m_mp3player.pause( FALSE ) ;
			m_state = MAIN_MENU ;
			return  ;
		}
	}
	else if (strstr (strupr(filename), ".CUE"))
	{
		writexbox( "processing cue\r\n" ) ;

		strcpy( g_cuefile, caseval ) ;
		loadCueSheet( g_cuefile ) ;
		filename[0] = 0 ;


		//sprintf( xmsg, "filename fom cue=%s", filename ) ;
		//writexbox( xmsg ) ;

		if ( filename[0] == 0 )
		{
			m_state = MAIN_MENU ;
			return ;
		}

		sprintfx( "cue isofile = %s\r\n", filename ) ;

		loaded_cue = 1 ;
		copySamba = 0 ;

		if ( ( strstr( filename, ".ISO" ) ) || ( strstr( filename, ".iso" ) ) )
		{
			copySamba = 0 ;
			isoOrBin = 1 ;
		}
		else if ( ( strstr( filename, ".BIN" ) ) || ( strstr( filename, ".bin" ) ) )
		{
			copySamba = 0 ;
			isoOrBin = 2 ;
		}

	}
	else if ( strstr( filename, ".ISO" ) )
	{
		copySamba = 0 ;
		isoOrBin = 1 ;
	}
	else if ( strstr( filename, ".BIN" ) )
	{
		copySamba = 0 ;
		isoOrBin = 2 ;
	}





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


	if ( forceConfig || loadSettings( g_settingsfile ) )
	{
		changeMenu( &m_skin.gameSelectMenu, &m_skin.otherMenu ) ;
		doConfigureGame( g_settingsfile, g_keysfile ) ;
		isSelectMenu = 0 ;
	}
	else
	{
		loadKeys( g_keysfile ) ;
	}

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



	switch ( m_systemCard )
	{
		case 1 : strcpy( systemcard, "X:\\SYSCARD3.PCE" ) ; break ; 
	//	case 2 : strcpy( systemcard, "D:\\PCEROMS\\ARCADECARD.PCE" ) ; break ; 
		default : strcpy( systemcard, "X:\\SYSCARD1.PCE" ) ; break ; 
	}

	sprintfx( "initconsole\r\n") ;

	if ( m_bNetplay )
	{
		if ( setupNetplay() )
			return ;
	}

	if ( g_autoLaunchGame )
	{
		m_pnlSplashGame.Render() ;
		m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
	}
	else
	{
		if ( isSelectMenu )
		{
			doTransition( &m_pnlBackgroundSelect, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
		else
		{
			doTransition( &m_pnlBackgroundOther, &m_pnlSplashGame, m_skin.fade, 1 ) ;
		}
	}

	if ( !m_bBgmInGame )
	{
		m_mp3player.pause( TRUE ) ;
	}
	memset( m_mp3player.m_pSoundBufferData, 0, m_mp3player.stream_buffer_size) ;

	sprintfx("initconsole\r\n") ;


	//m_plaything.FreeSprites() ;

	sprintf( tmpfilename, "%s\\%s\\SPRITES\\*", m_szSkinDir, m_szSkin) ;



	if ( m_bUsingSamba && !loaded_cue)
	{
		char smbfilename[1024] ;
		char *smbp ;
		FILE *outfile ;
		char *buf ;

		strcpy( filename, caseval) ;

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

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

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


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


		strcpy( filename, smbfilename ) ;

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

		if ( copySamba )
		{

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

			if ( m_smbCdFile <= 0 )
			{
				popupMsg( "Could not open SMB file", &m_pnlBackgroundSelect ) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

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

			sprintfx( "copy samba\r\n") ;

			sprintf( filename, "X:\\%s", shortpath ) ;

			sprintfx( "copy samba %s %d\r\n", filename, filesize ) ;

			outfile = fopen( filename, "wb") ;

			sprintfx( "copy samba\r\n") ;
			if ( outfile == NULL )
			{
				m_smb.close( m_smbCdFile ) ;
				popupMsg( "Could not open X:\\ file for writing - perhaps X: is full?", &m_pnlBackgroundSelect ) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

			xbox_print_memory() ;

			buf = (char*) malloc(filesize) ;

			if ( buf == NULL )
			{
				popupMsg( "Could not allocate memory for copy samba", &m_pnlBackgroundSelect) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			sprintfx( "copy samba\r\n") ;

			m_smb.read(m_smbCdFile,buf, filesize) ;

			sprintfx( "copy samba\r\n") ;

			fwrite( buf, 1, filesize, outfile ) ;
			fclose( outfile) ;
			m_smb.close( m_smbCdFile ) ;

			sprintfx( "copy samba\r\n") ;

			free(buf) ;
		}

	}
	else if ( m_bUsingRelax && !loaded_cue )
	{
		char rlxfilename[1024] ;
		FILE *outfile ;
		int filesize ;
		char *fbuf ;

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


				sprintf( rlxfilename, "X:\\%s", shortpath ) ;
				strcpy(filename, rlxfilename) ;

				outfile = fopen(filename, "wb") ;

				if ( outfile == NULL )
				{
					m_relax.Close( ) ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}


				fbuf = (char*) malloc( filesize ) ;

				if ( !fbuf )
				{
					m_relax.Close() ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}

				if ( ! m_relax.ReadAll( fbuf, filesize ) )
				{
					free(fbuf) ;
					m_relax.Close() ;
					m_plaything.LoadSprites( tmpfilename ) ;
					return ;
				}

				m_relax.Close() ;

				fwrite( fbuf, 1, filesize, outfile ) ;
				fclose( outfile ) ;
				free(fbuf) ;
			}
			else
			{
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}
		}

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

		strcpy( filename, caseval) ;

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


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

			outfile = fopen(filename, "wb") ;

			if ( outfile == NULL )
			{
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}


			fbuf = (char*) malloc( filesize ) ;

			if ( !fbuf )
			{
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			if ( ! m_iso9660.ReadFile( isofd, (byte*)fbuf, filesize ) )
			{
				free(fbuf) ;
				m_iso9660.CloseFile(isofd) ;
				m_plaything.LoadSprites( tmpfilename ) ;
				return ;
			}

			m_iso9660.CloseFile(isofd) ;

			fwrite( fbuf, 1, filesize, outfile ) ;
			fclose( outfile ) ;
			free(fbuf) ;
		}
		else
		{
			m_plaything.LoadSprites( tmpfilename ) ;
			return ;
		}
	}


//	nonoise = 0 ;
	

	m_sound.init() ;
	m_cdda.init() ;
	m_mp3player_cdda.init() ;
	//m_mp3player.init() ;

	//writexbox( "init1" ) ;
	cht_load() ;

	// Create our texture
	init_texture();


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





	m_fAppTime = 0.0f ;

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

	m_steps = 0 ;

	//writexbox( "init4" ) ;
	//Then start it up

	//m_sound.insertSilence( 22050 ) ;
	m_sound.pause( FALSE ) ;
	m_cdda.pause( FALSE ) ;
	m_mp3player_cdda.pause(FALSE) ;
	//m_mp3player.insertSilence( 22050 ) ;
	//m_mp3player.pause( FALSE ) ;


	sprintfx("initconsole\r\n") ;

	m_state = IN_GAME ;

	QueryPerformanceCounter((union _LARGE_INTEGER *) m_performancePrev);

	applyHardwareFilter() ;

	sprintfx( "initconsole %s %s %s\r\n", filename, g_sramfile, g_saveprefix ) ;
	mednafen_main( filename ) ;
	//hugomain( filename, g_sramfile, g_saveprefix, systemcard, 0, m_forceUS ) ;

	//m_plaything.LoadSprites( tmpfilename ) ;
	writexbox( "initout" ) ;
	m_state=MAIN_MENU ;
	saveKeys( g_keysfile ) ;
	writexbox( "initout" ) ;
	saveSettings( g_settingsfile ) ;
	writexbox( "initout" ) ;
	cleanupConsole() ;
	writexbox( "initout" ) ;

	//put 3 frames of data in the audio buffer
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;
	//processEmu(FALSE) ;


}

#endif

int CXBoxSample::handleExtension( char *ext, char *zipfile, char *newfilename, int *zipnumber )
{
	return 0 ;
}

void CXBoxSample::cleanupConsole( )
{
	//sram_save();
	//rtc_save();
	writexbox( "cleanout" ) ;
	cht_save() ;

	writexbox( "cleanout" ) ;

	if (m_cheatCodes != NULL)
	{
		free(m_cheatCodes);
		m_cheatCodes = NULL;
	}

	if ( g_rumbleCodes != NULL )
	{
		free( g_rumbleCodes ) ;
		g_rumbleCodes = NULL ;
	}

}


void xbox_read_mp3_sector( FILE *fp, unsigned char *buf, unsigned int lsn, unsigned int numframes, unsigned int currentsector  ) 
{
	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 ) ;
}
void xbox_play_special_sectors( int tracknum, unsigned int lsn, unsigned int numframes   ) 
{

	if ( ( g_currentTrack != tracknum ) || (  g_cdda->m_sectorFrom != lsn ) || ( g_cdda->m_bDone ) )
		g_cdda->play_sectors_file_pce( lsn, lsn+numframes, 1 ) ;

	g_currentTrack = tracknum ;
}

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


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


/*
long xbox_play_cdda( unsigned char *msf )
{
	unsigned long sector = ( msf[0] * 75 * 60 ) + ( msf[1] * 75 ) + msf[2];
	unsigned long sectorEnd ;
	unsigned long sectorTest ;
	unsigned int whichTrack ;

	whichTrack = 99 ;

	for ( int i = 0 ; i < g_app->m_numtracks ; i++ )
	{
		sectorTest = ( g_app->m_toc.tracks[i].addr[1] * 60 * 75 ) + 
					( g_app->m_toc.tracks[i].addr[2] * 75 ) +
					( g_app->m_toc.tracks[i].addr[3]  )  ;

		if ( sector < sectorTest )
		{
			whichTrack = i ;
			break ;
		}
	}

	if ( whichTrack == 99 )
	{
		sectorEnd = 999999 ;
	}
	else
	{
		sectorEnd = ( g_app->m_toc.tracks[whichTrack].addr[1] * 60 * 75 ) + 
					( g_app->m_toc.tracks[whichTrack].addr[2] * 75 ) +
					( g_app->m_toc.tracks[whichTrack].addr[3]  )  ;
	}

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

	g_app->m_cdda.play_sectors_file( sector, 999999, 1 ) ;

	return 0 ;
}
*/
long xbox_stop_cdda() 
{
	//writexbox("stop cdda\r\n") ;
	g_app->m_cdda.stop() ;
	return 0 ;
}

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

DWORD xbox_get_bit_depth() 
{
	return g_app->m_bitDepth ;

}

void xbox_set_memory_ptr( unsigned char *ptr )
{
}

void xbox_set_RAM_location() 
{
	//m_memory_locations[0] = hard_pce->RAM ;
	//m_memory_locations[1] = cd_extra_mem ;
	//m_memory_locations[2] = cd_extra_super_mem ;

	m_memory_locations[3] = getLynxRAM() ;
	m_memory_locations[4] = getNESWRAM() ;

	m_memory_sizes[4] = getNESWRAMSize() ;

	if ( m_memory_locations[4] )
	{
		g_num_memory_locations = 5 ;
		//g_console_memory_size = 0x58800 + m_memory_sizes[4] ;
	}
	else
	{
		g_num_memory_locations = 4 ;
		//g_console_memory_size = 0x58800 ;
	}


}

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

	return g_app->m_graphicsFixes ;
}

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

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

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

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

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

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

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

unsigned char *xbox_cdbuffer() 
{
	return g_app->m_cdbuffer+12 ;
}

void xbox_get_td(unsigned char track, unsigned char *buffer) 
{
	unsigned int lu ;
	int whichTrack ;
	unsigned char b ;

	if ( track==0 )
		whichTrack = g_app->m_toc.lastTrack-1 ;
	else
		whichTrack = track-1 ;

	int val = 	( g_app->m_toc.tracks[whichTrack].addr[1] * 60 * 75 ) + 
				( g_app->m_toc.tracks[whichTrack].addr[2] * 75 ) +
				( g_app->m_toc.tracks[whichTrack].addr[3]  )  ;

/*
	if ( track == 0 )
	{
		val = ( ( 50*60 + 53 )*75 ) + 45 + 150 ;
	}
	else if ( track == 1 )
	{
		val = 150 ;
	}
	else if ( track == 2 )
	{
		val = ( ( 50*60 + 53 )*75 ) + 45 + 150 ;
	}
*/

	buffer[2] = (unsigned char)(val%75);
	val/=75;
	buffer[1]=(unsigned char)(val%60);
	buffer[0]=(unsigned char)(val/60);

	b=buffer[0];                                          // swap infos (psemu pro/epsxe)
	buffer[0]=buffer[2];
	buffer[2]=b;


}

void xbox_get_tn(unsigned char *ptr) 
{
	ptr[0]=1 ;
	ptr[1]=g_app->m_numtracks ;

}
void xbox_feed_stream(unsigned char* pSound,long lBytes) 
{
	sounddanger =  g_app->m_sound.process(pSound, lBytes )  ;

	g_mp3player->process() ;
	//g_app->m_mp3player.process() ;
	//g_app->m_cdda.process() ;
}

int xbox_read_sector_type( unsigned int sector, unsigned int sector_type ) 
{
	unsigned char szbuf[6] ;
	DWORD numread ;
	//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  ) ;

	if ( ( sector < g_app->m_currentStartSector ) || ( sector >= g_app->m_currentStartSector + CD_BUF_SECTORS ) )
	{
		if ( g_app->m_bRealCD )
		{
			memset( g_app->m_cdDataBuffer,0,2352) ;
			//for ( int i = 0 ; i < CD_BUF_SECTORS ; i++ )
				//g_app->m_io.ReadXASector( g_app->m_hCdrom, sector, CD_BUF_SECTORS, g_app->m_cdDataBuffer ) ;
				g_app->m_io.ReadXASector2( sector, CD_BUF_SECTORS, g_app->m_cdDataBuffer ) ;

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

		}
		else
		{
			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 ) ;
				}
			}
		}


		g_app->m_currentStartSector = sector ;
	}
	else
	{
		//cacheiters++ ;
		//sprintfx("read sector %u from cache\r\n", sector  ) ;
	}
/*
	if ( sector==16 ) 
	{
		unsigned char dumpsec[200] ;

		for ( int i = 0 ; i < 16 ; i++ )
		{
			for ( int j = 0 ; j < 16 ; j++ )
			{
				sprintf( (char*)(dumpsec+3*j), "%2.2X ", *(g_app->m_cdDataBuffer+(i*16)+j) ) ;
			}
			dumpsec[48] = 0 ;
			sprintfx( "%s \r\n",dumpsec ) ;
		}
	}
*/
	g_app->m_ptrCdBuf = g_app->m_cdDataBuffer + ((sector-g_app->m_currentStartSector)*2352) ;

/*
	for ( int ii = 0 ; ii < 16 ; ii++ )
	{
		char msg[100] ;

		sprintf(msg, "%02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X \r\n",
			g_app->m_ptrCdBuf[(ii*16)+0], g_app->m_ptrCdBuf[(ii*16)+1], g_app->m_ptrCdBuf[(ii*16)+2], g_app->m_ptrCdBuf[(ii*16)+3], g_app->m_ptrCdBuf[(ii*16)+4], 
			g_app->m_ptrCdBuf[(ii*16)+5], g_app->m_ptrCdBuf[(ii*16)+6], g_app->m_ptrCdBuf[(ii*16)+7], g_app->m_ptrCdBuf[(ii*16)+8], g_app->m_ptrCdBuf[(ii*16)+9], 
			g_app->m_ptrCdBuf[(ii*16)+10], g_app->m_ptrCdBuf[(ii*16)+11], g_app->m_ptrCdBuf[(ii*16)+12], g_app->m_ptrCdBuf[(ii*16)+13], g_app->m_ptrCdBuf[(ii*16)+14], g_app->m_ptrCdBuf[(ii*16)+15] ) ;
		writexbox(msg) ;
	}
*/
	/*
	for ( unsigned int i = 0 ; i < 60000 ; i++ )
	{
		numread = (5+numread) * (numread+1) ;
		avg = (avg+4.234) / ( avg+1.23) ;
	}

	iters++ ;
	endtime = GetTickCount() ;

	totaltime += (endtime - begintime ) ;

	avg = (float)totaltime / (float)iters ; 

	if ( ( begintime%1000 >= 0 ) && ( begintime%1000 < 10 ) )
		sprintfx( "avgreadtime = %f, citer/iter = %u/%u %f\r\n", avg, cacheiters, iters, (float)cacheiters/(float)iters ) ;
*/
	return 0 ;
	//memset(g_app->m_cdbuffer, 0, 2352) ;

	//return ( g_app->m_io.ReadSectorMode2( g_app->m_hCdrom, sector, (LPSTR)g_app->m_cdbuffer ) == -1 ) ;
}


int xbox_read_sector_cdda( unsigned int sector ) 
{
	return cdrfile_read_xbox_audio_sector( g_currentTrack, sector, xbox_cdbuffer()-12 ) ;
}

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_read_input(int port) 
{
	return 0;
}

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

}


void xbox_dovolume( int vol )
{
	if ( vol )
		g_app->m_sound.max_volume() ;
	else
		g_app->m_sound.min_volume() ;
}

void xbox_stop_audio( ) 
{
	g_mp3player->stop( ) ;
	g_cdda->stop( ) ;
	g_app->m_sound.min_volume() ;
}
void xbox_play_track( unsigned  char track, unsigned char repeat ) 
{

	//if ( ! g_mp3player->loadFile( CD_track[track].filename, repeat, 0, 75*60*70 ) )
	//{
		//g_mp3player->insertSilence( 22050 ) ;
		//g_mp3player->pause( 0 ) ;
	//}

}

void xbox_play_track_range( unsigned char  track, unsigned char repeat, unsigned int frame_offset, unsigned int numframes ) 
{
	//sprintfx( "inside xbox playtrackrng %u %s\r\n", track, CD_track[track].filename ) ;

	//if ( ! g_mp3player->loadFile( CD_track[track].filename, repeat, frame_offset, numframes ) )
	//{
		//g_mp3player->insertSilence( 22050 ) ;
		//g_mp3player->pause( 0 ) ;
	//}
}


int xbox_got_cue()
{
	return ( ( g_app->g_cuefile ) && ( g_app->g_cuefile[0] ) ) ;
}

void xbox_stop_cd()
{
	g_cdda->stop() ;

}
void xbox_read_cd_sector( unsigned char *p, unsigned int sector ) 
{
	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) ;


}
void xbox_play_cdda( unsigned int sectorFrom, unsigned int sectorTo, unsigned char repeat ) 
{

	g_cdda->play_sectors( sectorFrom, sectorTo, repeat, g_app->m_hCdrom ) ;
}

/*
char* xbox_get_track_name( int tnum ) 
{
	if ( tnum > g_app->nb_max_track )
		return "xxxx" ;
	else
		return g_app->CD_track[tnum].filename ;
}

int xbox_get_track_length( int tnum ) 
{
	if ( tnum > g_app->nb_max_track )
		return 0 ;
	else
		return g_app->CD_track[tnum].length ;
}
*/

char* xbox_get_fdsfile()
{
	return g_app->g_fdsfile ;
}

char* xbox_get_savepath()
{
	return g_app->g_savePath ;
}

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

char *xbox_savedir ()
{
	return g_app->g_savedir ;
}
int xbox_itell( int fd)
{
	return m_iso9660.GetFilePosition( fd) ;
}


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_orig, char *mode, int tracknum )
{
	char filename[1024] ;

	strcpy( filename, filename_orig ) ;

	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 = '/' ;

		strcpy( filename, smbfilename ) ;

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

		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 :
		{
			return fseek( f, offset, origin ) ;
			break ;
		}
		default : 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 :
		{
			return fread( buffer, size, count, f ) ;
			break ;
		}
		default : 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 :
		{
			return fclose( f ) ;
			break ;
		}
		default : 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 :
		{
			return fstat( fileno(f), buffer ) ;
			break ;
		}
		default : 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_check_events()
{
	//writexbox( "before events") ;
	return g_app->handleEvents() ;
	//writexbox( "after events") ;
	//return 0 ;
}


void xbox_pause_audio_hugo( int state ) 
{
	g_mp3player->pause( state ) ;
	g_cdda->pause( state ) ;
}

char * xbox_get_sram()
{
	return g_app->g_sramfile ;
}
void xbox_process_audio()
{
	//g_sound->process() ;
	g_cdda->process() ;
	g_mp3player->process() ;
}
DWORD xbox_lightgun_y()
{
	return g_app->m_zapperDat[1] ;
}

DWORD xbox_lightgun_x()
{
	return g_app->m_zapperDat[0] ;
}
DWORD xbox_lightgun_trigger()
{
	return g_app->m_zapperDat[2] ;
}

DWORD xbox_get_lightgun( int *x, int *y )
{
	*x = g_app->m_zapperDat[0] ;
	*y = g_app->m_zapperDat[1] ;
	return g_app->m_zapperDat[2] ;
}

unsigned char * xbox_getvidbuffer()
{
	RECT rectSource;
	rectSource.top = 0;
	rectSource.left = 0;
	//rectSource.bottom = (VDP_Num_Vis_Lines<<BLITTERS[blittermode].multiplier)  - 1 ;
	//rectSource.right  = ((320-Dep) << BLITTERS[blittermode].multiplier ) - 1 ;
	rectSource.bottom = g_app->theHeight - 1 ;
	rectSource.right  = g_app->theWidth  - 1;

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

	if ( g_app->m_xboxSFilter )
		return g_app->g_pBlitBuff ;
	else
		return (unsigned char*)g_app->g_d3dlr.pBits ;
}

void xbox_put_image(unsigned char *buf, int w, int h, int spitch, int systype, int wx, int wy)
{
	//writexbox( "before render") ;
	//g_sound->process() ;
	//g_cdda->process() ;

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

	}

	g_app->m_mp3player_cdda.processReal() ;
	g_cdda->process_gens() ;

	if ( throttle )
		throttle-- ;

	if ( throttle == 0 )
		g_app->render_to_texture( buf, w,h, spitch, systype, wx, wy) ;
	//writexbox( "after render") ;
}

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

void cpp_Sleep_hugo( DWORD amt )
{

	//Sleep(amt) ;
}

void xbox_set_messagedelay( unsigned int length )
{
	g_app->m_msgDelay = length ;
}

void xbox_open_zip( char *hugozipfile )
{
	//writexbox( "before zip") ;
	g_app->rom_load_zip( hugozipfile ) ;
	//writexbox( "after zip") ;
}
unsigned int xbox_canwrite( ) 
{
	return g_sound->canwrite( ) ;

}

#ifdef __cplusplus
}
#endif

void CXBoxSample::processEmu( BOOL render )
{
			
			handleEvents();
			updateCheats() ;


//			doneFrame = 0 ;

			//m_nbytes = update_sound_main() ;



			if ( render )
			{
				//render_to_texture();
				m_numFrames++ ;
			}


//			m_droppedFrames += m_sound.process( (byte**)sbuf, m_nbytes, soundChannels ) ;

			while ( m_sound.m_bDanger )
			{
				handleEvents();
				updateCheats() ;
//				doneFrame = 0 ;
				//m_nbytes = update_sound_main() ;


				//m_droppedFrames += m_sound.process( (byte**)sbuf, m_nbytes, soundChannels ) ;
			}



}


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

