#include <sdl.h>

void __cdecl nnx(int,struct SDL_Surface *,struct SDL_Rect *,struct SDL_Surface *,struct SDL_Rect *) {}
void __cdecl ClearGLSurfaces(struct SDL_Surface *)  {}
int __cdecl InitOpenGL(int,int,struct SDL_Surface *)  { return 0 ;}
void __cdecl nnyx(int,struct SDL_Surface *,struct SDL_Rect *,struct SDL_Surface *,struct SDL_Rect *)  {}
void __cdecl BlitOpenGL(struct SDL_Surface *,struct SDL_Rect const *,struct SDL_Rect const *,struct SDL_Rect const *)  {}
int __cdecl NetplayEventHook(SDL_Event const *)  { return 0 ;}

void __cdecl FlipOpenGL(void)  {}
void __cdecl BlitOpenGLOSD(unsigned int *)  {}
void __cdecl hq4x_32(unsigned char *,unsigned char *,int,int,int,int)  {}
void __cdecl hq3x_32(unsigned char *,unsigned char *,int,int,int,int)  {}
void __cdecl hq2x_32(unsigned char *,unsigned char *,int,int,int,int)  {}
void __cdecl NetplayText_InMainThread(unsigned char *)  {}
void __cdecl Netplay_ToggleTextView(void)  {}
void MDFND_NetworkClose(void) {}
void  MDFND_NetworkConnect(void) { }//return 0 ;}
void  KillOpenGL(void)  {}
int __cdecl Netplay_GetTextView(void) { return 0 ;}

#ifdef  __cplusplus
extern "C" {
#endif

unsigned char *xbox_get_screen_buffer() ;
unsigned int xbox_get_pitch();
unsigned int xbox_get_lightgun( int *x, int * y ) ;

void scale(unsigned scale2, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height) {}

#ifdef  __cplusplus
}
#endif

#include <sdl_thread.h>
#include "mednafen.h"
#include "settings-driver.h"
#include <xtl.h>
#include "git.h"

char *XBOX_HOME = "D:\\" ;
char *SDL_MSG = "SDLMSG" ;

char *xbox_savedir() ;

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

void PCEINPUT_SetInputType( int type) ;

void xbox_setgamesettings()
{
	char strval[30] ;
	MDFNI_SetSetting("soundvol", "150" ) ;
	MDFNI_SetSetting("fs", "1" ) ;
	MDFNI_SetSetting("vdriver", "1" ) ;
	MDFNI_SetSetting("soundrate", "44100" ) ;
	MDFNI_SetSetting("nes.fnscan", "0" ) ;
	MDFNI_SetSetting("nes.ntsccol", "0" ) ;

	MDFNI_SetSetting("nes.nofs", g_nes_nofs ) ;
	MDFNI_SetSetting("nes.no8lim", g_nes_no8lim ) ;
	MDFNI_SetSetting("nes.pal", g_nes_pal ) ;
	MDFNI_SetSetting("nes.clipsides", g_nes_clipsides ) ;
	MDFNI_SetSetting("nes.slstart", g_nes_slstart,1 ) ;
	MDFNI_SetSetting("nes.slend", g_nes_slend,1 ) ;
	MDFNI_SetSetting("nes.slstartp", g_nes_slstartp,1 ) ;
	MDFNI_SetSetting("nes.slendp", g_nes_slendp,1 ) ;
	MDFNI_SetSetting("nes.cpalette", g_nes_custom_palette ) ;
	MDFNI_SetSetting("nes.ntsccol", g_nes_ntsccol,1 ) ;
	MDFNI_SetSetting("nes.ntsctint", g_nes_ntsctint,1 ) ;
	MDFNI_SetSetting("nes.ntschue", g_nes_ntschue,1 ) ;
	MDFNI_SetSetting("nes.hackfix", g_nes_hackfix ) ;

	MDFNI_SetSetting("pce.forcesgx", g_pce_forcesgx ) ;
	MDFNI_SetSetting("pce.ocmultiplier", g_pce_ocmultiplier,1 ) ;
	MDFNI_SetSetting("pce.nospritelimit", g_pce_nospritelimit ) ;
	MDFNI_SetSetting("pce.forceus", g_pce_forceus ) ;
	MDFNI_SetSetting("pce.systemcard", g_pce_systemcard ) ;


	switch( g_nes_input1 )
	{
		case 0 : MDFNI_SetSetting("nes.input1", "none" ) ; break ;
		case 2 : MDFNI_SetSetting("nes.input1", "zapper" ) ; break ;
		case 3 : MDFNI_SetSetting("nes.input1", "powerpada" ) ; break ;
		case 4 : MDFNI_SetSetting("nes.input1", "arkanoid" ) ; break ;
		case 1 : 
		default : MDFNI_SetSetting("nes.input1", "gamepad" ) ; break ;
	}
	switch( g_nes_input2 )
	{
		case 0 : MDFNI_SetSetting("nes.input2", "none" ) ; break ;
		case 2 : MDFNI_SetSetting("nes.input2", "zapper" ) ; break ;
		case 3 : MDFNI_SetSetting("nes.input2", "powerpadb" ) ; break ;
		case 4 : MDFNI_SetSetting("nes.input2", "arkanoid" ) ; break ;
		case 1 : 
		default : MDFNI_SetSetting("nes.input2", "gamepad" ) ; break ;
	}
	switch( g_nes_inputfc )
	{
		case 1  : MDFNI_SetSetting("nes.fcexp", "arkanoid" ) ; break ;
		case 2  : MDFNI_SetSetting("nes.fcexp", "shadow" ) ; break ;
		case 3  : MDFNI_SetSetting("nes.fcexp", "4player" ) ; break ;
		case 4  : MDFNI_SetSetting("nes.fcexp", "fkb" ) ; break ;
		case 5  : MDFNI_SetSetting("nes.fcexp", "hypershot" ) ; break ;
		case 6  : MDFNI_SetSetting("nes.fcexp", "mahjong" ) ; break ;
		case 7  : MDFNI_SetSetting("nes.fcexp", "quizking" ) ; break ;
		case 8  : MDFNI_SetSetting("nes.fcexp", "ftrainera" ) ; break ;
		case 9  : MDFNI_SetSetting("nes.fcexp", "ftrainerb" ) ; break ;
		case 10 : MDFNI_SetSetting("nes.fcexp", "oekakids" ) ; break ;
		case 0  : 
		default : MDFNI_SetSetting("nes.fcexp", "none" ) ; break ;
	}

	PCEINPUT_SetInputType( g_pce_controller ) ;

}

#include "nes/nes.h"
#include "nes/cart.h"

extern CartInfo iNESCart;
unsigned char *getVSWRAM();

unsigned char *getNESWRAM()
{
	switch ( MDFNGameInfo->nes.type )
	{
		case GIT_FDS:
		{
			return GameMemBlock ;
			break ;
		}
		case GIT_VSUNI:
		{
			return getVSWRAM() ;
			break ;
		}
		case GIT_NSF:
		{
			return NULL ;
			break ;
		}
		case GIT_CART:
		default:
		{
			return iNESCart.SaveGame[0] ;
			break ;
		}

	}
}

unsigned int getNESWRAMSize()
{
	switch ( MDFNGameInfo->nes.type )
	{
		case GIT_FDS:
		{
			return 32768;
			break ;
		}
		case GIT_VSUNI:
		{
			return 8192 ;
			break ;
		}
		case GIT_NSF:
		{
			return 0 ;
			break ;
		}
		case GIT_CART:
		default:
		{
			return iNESCart.SaveGameLen[0] ;
			break ;
		}

	}
}

#define DECLSPECC

SDL_PixelFormat vpf = { NULL, 16, 2, 0, 0, 0, 0, 11, 5, 0, 0, 0x1F, 0x3F, 0x1F, 0x00, 0, 0 } ;

SDL_VideoInfo vinf = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64*1024, &vpf } ;
SDL_Surface gscreen = { 0, &vpf, 640, 480, 0, NULL, 0, NULL, { 0,0,640,480 }, 0, 0, NULL, 0, 0 } ;

int SDLCALL SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) { memcpy( obtained, desired, sizeof(SDL_AudioSpec) ) ; obtained->format = AUDIO_S16LSB ; obtained->freq = 44100 ; obtained->channels = 2 ; return 0 ;}
DECLSPECC void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon) {}
DECLSPECC SDL_Surface * SDLCALL SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { gscreen.pitch = xbox_get_pitch() ; gscreen.pixels = xbox_get_screen_buffer() ; return &gscreen ;}
DECLSPECC char * SDLCALL SDL_GetError(void) { return SDL_MSG ;}
DECLSPECC Uint32 SDLCALL SDL_WasInit(Uint32 flags) { return 0 ;}
DECLSPECC void SDLCALL SDL_Delay(Uint32 ms) {}
DECLSPECC void SDLCALL SDL_PumpEvents(void) {}
DECLSPECC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter) {}
DECLSPECC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y) { return xbox_get_lightgun( x, y ) ;}
DECLSPECC int SDLCALL SDL_PushEvent(SDL_Event *event) { return 0 ;}
DECLSPECC Uint8 * SDLCALL SDL_GetKeyState(int *numkeys) { return NULL ;}
DECLSPECC void SDLCALL SDL_JoystickUpdate(void) {}
DECLSPECC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode) { return (SDL_GrabMode)0 ;}
DECLSPECC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick) { return 0 ;}
DECLSPECC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick) { return 0 ;}
DECLSPECC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick) { return 0 ;}
DECLSPECC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick) { return 0 ;}
DECLSPECC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, int button) { return 0 ;}
DECLSPECC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, int hat) { return 0 ;}
DECLSPECC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis) { return 0 ;}
DECLSPECC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick) {}
DECLSPECC const char * SDLCALL SDL_JoystickName(int device_index) { return SDL_MSG ;}
DECLSPECC SDL_Joystick * SDLCALL SDL_JoystickOpen(int device_index) { return NULL ;}
DECLSPECC int SDLCALL SDL_JoystickOpened(int device_index) { return 0 ;}
DECLSPECC int SDLCALL SDL_NumJoysticks(void) { return 0 ;}
DECLSPECC Uint32 SDLCALL SDL_ThreadID(void) { return 1 ;}
DECLSPECC SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data) { return NULL ;}
DECLSPECC int SDLCALL SDL_mutexV(SDL_mutex *mutex) { return 0 ;}
DECLSPECC int SDLCALL SDL_mutexP(SDL_mutex *mutex) { return 0 ;}
DECLSPECC void SDLCALL SDL_WaitThread(SDL_Thread *thread, int *status) {}
DECLSPECC int SDLCALL SDL_ShowCursor(int toggle) {return 0 ;}
DECLSPECC int SDLCALL SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 mask) { return 1 ;}
DECLSPECC int SDLCALL SDL_PollEvent(SDL_Event *event) { return 0 ;}
DECLSPECC void SDLCALL SDL_Quit(void) {}
DECLSPECC void SDLCALL SDL_QuitSubSystem(Uint32 flags) {}
DECLSPECC void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex) {}
DECLSPECC int SDLCALL SDL_JoystickEventState(int state) { return 0 ;}
DECLSPECC SDL_mutex * SDLCALL SDL_CreateMutex(void) { return NULL ;}
DECLSPECC int SDLCALL SDL_EnableUNICODE(int enable) { return 0 ;}
DECLSPECC int SDLCALL SDL_Init(Uint32 flags) { return 0 ;}
DECLSPECC int SDLCALL SDL_InitSubSystem(Uint32 flags) { return 0 ; }
DECLSPECC void SDLCALL SDL_InitQuickDraw(struct QDGlobals *the_qd) {}
DECLSPECC Uint32 SDLCALL SDL_GetTicks(void) { return GetTickCount() ;}
DECLSPECC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface) { }
DECLSPECC int SDLCALL SDL_LockSurface(SDL_Surface *surface) { return 0 ;}
DECLSPECC int SDLCALL SDL_UpperBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) { return 0 ;}
DECLSPECC void SDLCALL SDL_PauseAudio(int pause_on) {}
DECLSPECC void SDLCALL SDL_UnlockAudio(void) {}
DECLSPECC void SDLCALL SDL_LockAudio(void) {}
DECLSPECC void SDLCALL SDL_CloseAudio(void) {}
DECLSPECC int SDLCALL SDL_Flip(SDL_Surface *screen) { return 0 ;}
DECLSPECC void SDLCALL SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {}
DECLSPECC void SDLCALL SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) {}
DECLSPECC void SDLCALL SDL_FreeSurface(SDL_Surface *surface) {}
DECLSPECC void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) {}
DECLSPECC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value) { return 0 ;}
DECLSPECC const SDL_VideoInfo * SDLCALL SDL_GetVideoInfo(void) { return &vinf ;}
DECLSPECC int SDLCALL SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha) { return 0 ;}
DECLSPECC int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key) { return 0 ;}
DECLSPECC SDL_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { return NULL ;}
DECLSPECC SDL_Surface * SDLCALL SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { return NULL ;}




void __cdecl MDFNI_NetplayText(unsigned char const *) {}
int MDFNDnetplay ;

MDFNGI EmulatedGB =
{
 GISYS_GB,
 "gb",
 NULL,
 NULL,
 NULL,
 NULL,
 "Background\0Sprites\0Window\0",
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL, // No netplay yet.
 NULL,
 (uint32)((double)4194304 / 70224 * 65536 * 256),
 NULL,
 160,
 144,
 160,
 256 * sizeof(uint32),
 {0, 0, 160, 144},
};

MDFNGI EmulatedGBA =
{
 GISYS_GBA,
 "gba",
 NULL,
 NULL,
 NULL,
 NULL,
 "BG0\0BG1\0BG2\0BG3\0OBJ\0WIN 0\0WIN 1\0OBJ WIN\0",
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL, // No netplay yet.
 NULL,
 (uint32)((double)4194304 / 70224 * 65536 * 256),
 NULL,
 240,
 160,
 240,
 256 * sizeof(uint32),
 { 0, 0, 240, 160 },
};

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

extern TRACKINFO g_perfectTracks[100] ;
extern DWORD g_numPerfectTracks ;

#include <cdio/cdio.h>
#include <vorbis/vorbisfile.h>
#include <sndfile.h>
#include "cdromfile.h"

void xbox_fixup_cue( CDRFile *ret ) 
{
	unsigned int running_pregap ;
	if ( g_numPerfectTracks == 0 )
		return ;

	running_pregap = 0 ;

	ret->FirstTrack = 1 ;
	ret->NumTracks = g_numPerfectTracks-1 ;
	ret->total_sectors = g_perfectTracks[g_numPerfectTracks-1].lsn ;

	for ( int i = 0 ; i < g_numPerfectTracks-1 ; i++ )
	{
		ret->Tracks[i+1].LSN = g_perfectTracks[i].lsn ;
		ret->Tracks[i+1].pregap = g_perfectTracks[i].pregap ;

		running_pregap += g_perfectTracks[i].pregap ;

		if ( ret->Tracks[i+1].FirstFileInstance )
			ret->Tracks[i+1].index = 0 ;
		else
			ret->Tracks[i+1].index = g_perfectTracks[i].lsn - running_pregap ;

		ret->Tracks[i+1].sectors = ( g_perfectTracks[i+1].lsn - g_perfectTracks[i].lsn ) - g_perfectTracks[i+1].pregap ;


	}
}





