diff --git a/stella/src/emucore/TrackBall22.cxx b/stella/src/emucore/TrackBall22.cxx index 607a23c1d..64dd119a5 100644 --- a/stella/src/emucore/TrackBall22.cxx +++ b/stella/src/emucore/TrackBall22.cxx @@ -1,86 +1,86 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: TrackBall22.cxx,v 1.3 2008-02-06 13:45:22 stephena Exp $ -//============================================================================ - -#include "Event.hxx" -#include "TrackBall22.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TrackBall22::TrackBall22(Jack jack, const Event& event) - : Controller(jack, event, Controller::TrackBall22), - myHCounter(0), - myVCounter(0) -{ - if(myJack == Left) - { - myUpEvent = Event::JoystickZeroUp; - myDownEvent = Event::JoystickZeroDown; - myLeftEvent = Event::JoystickZeroLeft; - myRightEvent = Event::JoystickZeroRight; - myFireEvent = Event::JoystickZeroFire1; - } - else - { - myUpEvent = Event::JoystickOneUp; - myDownEvent = Event::JoystickOneDown; - myLeftEvent = Event::JoystickOneLeft; - myRightEvent = Event::JoystickOneRight; - myFireEvent = Event::JoystickOneFire1; - } - - // Analog pins are never used by the CX-22 - myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TrackBall22::~TrackBall22() -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TrackBall22::update() -{ -//db TrakBallTableTB_V[2][2] = {{0x00, 0x10},{0x20, 0x30}}; /* CX-22 */ -//db TrakBallTableTB_H[2][2] = {{0x40, 0x00},{0xc0, 0x80}}; /* CX-22 */ - - - // Gray codes for rotation - static const uInt8 graytable[] = { 0x00, 0x10, 0x20, 0x30 }; - - // Determine which gray code we're at - if(myEvent.get(myLeftEvent) != 0) -{ - myHCounter--; -cerr << "left\n"; -} - else if(myEvent.get(myRightEvent) != 0) -{ - myHCounter++; -cerr << "right\n"; -} - // Only consider the lower-most bits (corresponding to pins 1 & 2) - myHCounter &= 0x0f; - uInt8 gray = graytable[myHCounter >> 2]; - - // Determine which bits are set - myDigitalPinState[One] = (gray & 0x1) != 0; - myDigitalPinState[Two] = (gray & 0x2) != 0; - myDigitalPinState[Three] = (gray & 0x1) != 0; - myDigitalPinState[Four] = (gray & 0x2) != 0; - - myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0); -} +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: TrackBall22.cxx,v 1.4 2008-03-08 23:34:23 stephena Exp $ +//============================================================================ + +#include "Event.hxx" +#include "TrackBall22.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TrackBall22::TrackBall22(Jack jack, const Event& event) + : Controller(jack, event, Controller::TrackBall22), + myHCounter(0), + myVCounter(0) +{ + if(myJack == Left) + { + myUpEvent = Event::JoystickZeroUp; + myDownEvent = Event::JoystickZeroDown; + myLeftEvent = Event::JoystickZeroLeft; + myRightEvent = Event::JoystickZeroRight; + myFireEvent = Event::JoystickZeroFire1; + } + else + { + myUpEvent = Event::JoystickOneUp; + myDownEvent = Event::JoystickOneDown; + myLeftEvent = Event::JoystickOneLeft; + myRightEvent = Event::JoystickOneRight; + myFireEvent = Event::JoystickOneFire1; + } + + // Analog pins are never used by the CX-22 + myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TrackBall22::~TrackBall22() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TrackBall22::update() +{ +//db TrakBallTableTB_V[2][2] = {{0x00, 0x10},{0x20, 0x30}}; /* CX-22 */ +//db TrakBallTableTB_H[2][2] = {{0x40, 0x00},{0xc0, 0x80}}; /* CX-22 */ + + + // Gray codes for rotation + static const uInt8 graytable[] = { 0x00, 0x10, 0x20, 0x30 }; + + // Determine which gray code we're at + if(myEvent.get(myLeftEvent) != 0) +{ + myHCounter--; +cerr << "left\n"; +} + else if(myEvent.get(myRightEvent) != 0) +{ + myHCounter++; +cerr << "right\n"; +} + // Only consider the lower-most bits (corresponding to pins 1 & 2) + myHCounter &= 0x0f; + uInt8 gray = graytable[myHCounter >> 2]; + + // Determine which bits are set + myDigitalPinState[One] = (gray & 0x1) != 0; + myDigitalPinState[Two] = (gray & 0x2) != 0; + myDigitalPinState[Three] = (gray & 0x1) != 0; + myDigitalPinState[Four] = (gray & 0x2) != 0; + + myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0); +} diff --git a/stella/src/win32/SDL_win32_main.c b/stella/src/win32/SDL_win32_main.c new file mode 100644 index 000000000..30a13a848 --- /dev/null +++ b/stella/src/win32/SDL_win32_main.c @@ -0,0 +1,386 @@ +/* + SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 + + The WinMain function -- calls your program's main() function +*/ + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#ifdef _WIN32_WCE +# define DIR_SEPERATOR TEXT("\\") +# undef _getcwd +# define _getcwd(str,len) wcscpy(str,TEXT("")) +# define setbuf(f,b) +# define setvbuf(w,x,y,z) +# define fopen _wfopen +# define freopen _wfreopen +# define remove(x) DeleteFile(x) +#else +# define DIR_SEPERATOR TEXT("/") +# include +#endif + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +# ifndef _WIN32_WCE_EMULATION +# undef main +# endif /* _WIN32_WCE_EMULATION */ +#endif /* main */ + +/* The standard output files */ +#define STDOUT_FILE TEXT("stdout.txt") +#define STDERR_FILE TEXT("stderr.txt") + +#ifndef NO_STDIO_REDIRECT +# ifdef _WIN32_WCE + static wchar_t stdoutPath[MAX_PATH]; + static wchar_t stderrPath[MAX_PATH]; +# else + static char stdoutPath[MAX_PATH]; + static char stderrPath[MAX_PATH]; +# endif +#endif + +#if defined(_WIN32_WCE) && _WIN32_WCE < 300 +/* seems to be undefined in Win CE although in online help */ +#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) +#endif /* _WIN32_WCE < 300 */ + +static void UnEscapeQuotes( char *arg ) +{ + char *last = NULL; + + while( *arg ) { + if( *arg == '"' && *last == '\\' ) { + char *c_curr = arg; + char *c_last = last; + + while( *c_curr ) { + *c_last = *c_curr; + c_last = c_curr; + c_curr++; + } + *c_last = '\0'; + } + last = arg; + arg++; + } +} + +/* Parse a command line buffer into arguments */ +static int ParseCommandLine(char *cmdline, char **argv) +{ + char *bufp; + char *lastp = NULL; + int argc, last_argc; + + argc = last_argc = 0; + for ( bufp = cmdline; *bufp; ) { + /* Skip leading whitespace */ + while ( isspace(*bufp) ) { + ++bufp; + } + /* Skip over argument */ + if ( *bufp == '"' ) { + ++bufp; + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && ( *bufp != '"' || *lastp == '\\' ) ) { + lastp = bufp; + ++bufp; + } + } else { + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && ! isspace(*bufp) ) { + ++bufp; + } + } + if ( *bufp ) { + if ( argv ) { + *bufp = '\0'; + } + ++bufp; + } + + /* Strip out \ from \" sequences */ + if( argv && last_argc != argc ) { + UnEscapeQuotes( argv[last_argc] ); + } + last_argc = argc; + } + if ( argv ) { + argv[argc] = NULL; + } + return(argc); +} + +/* Show an error message */ +static void ShowError(const char *title, const char *message) +{ +/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ +#ifdef USE_MESSAGEBOX + MessageBox(NULL, message, title, MB_ICONEXCLAMATION|MB_OK); +#else + fprintf(stderr, "%s: %s\n", title, message); +#endif +} + +/* Pop up an out of memory message, returns to Windows */ +static BOOL OutOfMemory(void) +{ + ShowError("Fatal Error", "Out of memory - aborting"); + return FALSE; +} + +/* SDL_Quit() shouldn't be used with atexit() directly because + calling conventions may differ... */ +static void cleanup(void) +{ + SDL_Quit(); +} + +/* Remove the output files if there was no output written */ +static void cleanup_output(void) +{ +#ifndef NO_STDIO_REDIRECT + FILE *file; + int empty; +#endif + + /* Flush the output in case anything is queued */ + fclose(stdout); + fclose(stderr); + +#ifndef NO_STDIO_REDIRECT + /* See if the files have any output in them */ + if ( stdoutPath[0] ) { + file = fopen(stdoutPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + remove(stdoutPath); + } + } + } + if ( stderrPath[0] ) { + file = fopen(stderrPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + remove(stderrPath); + } + } + } +#endif +} + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +/* The VC++ compiler needs main defined */ +#define console_main main +#endif + +/* This is where execution begins [console apps] */ +int console_main(int argc, char *argv[]) +{ + size_t n; + char *bufp, *appname; + int status; + + /* Get the class name from argv[0] */ + appname = argv[0]; + if ( (bufp=SDL_strrchr(argv[0], '\\')) != NULL ) { + appname = bufp+1; + } else + if ( (bufp=SDL_strrchr(argv[0], '/')) != NULL ) { + appname = bufp+1; + } + + if ( (bufp=SDL_strrchr(appname, '.')) == NULL ) + n = SDL_strlen(appname); + else + n = (bufp-appname); + + bufp = SDL_stack_alloc(char, n+1); + if ( bufp == NULL ) { + return OutOfMemory(); + } + SDL_strlcpy(bufp, appname, n+1); + appname = bufp; + + /* Load SDL dynamic link library */ + if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { + ShowError("WinMain() error", SDL_GetError()); + return(FALSE); + } + atexit(cleanup_output); + atexit(cleanup); + + /* Sam: + We still need to pass in the application handle so that + DirectInput will initialize properly when SDL_RegisterApp() + is called later in the video initialization. + */ + SDL_SetModuleHandle(GetModuleHandle(NULL)); + + /* Run the application main() code */ + status = SDL_main(argc, argv); + + /* Exit cleanly, calling atexit() functions */ + exit(status); + + /* Hush little compiler, don't you cry... */ + return 0; +} + +/* This is where execution begins [windowed apps] */ +#ifdef _WIN32_WCE +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) +#else +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +#endif +{ + HINSTANCE handle; + char **argv; + int argc; + char *cmdline; +#ifdef _WIN32_WCE + wchar_t *bufp; + int nLen; +#else + char *bufp; + size_t nLen; +#endif +#ifndef NO_STDIO_REDIRECT + DWORD pathlen; +#ifdef _WIN32_WCE + wchar_t path[MAX_PATH]; +#else + char path[MAX_PATH]; +#endif + FILE *newfp; +#endif + + /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't + keep them open. This is a hack.. hopefully it will be fixed + someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. + */ + handle = LoadLibrary(TEXT("DDRAW.DLL")); + if ( handle != NULL ) { + FreeLibrary(handle); + } + +#ifndef NO_STDIO_REDIRECT + pathlen = GetModuleFileName(NULL, path, SDL_arraysize(path)); + while ( pathlen > 0 && path[pathlen] != '\\' ) { + --pathlen; + } + path[pathlen] = '\0'; + +#ifdef _WIN32_WCE + wcsncpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); + wcsncat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#else + SDL_strlcpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); + SDL_strlcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#endif + + /* Redirect standard input and standard output */ + newfp = freopen(stdoutPath, TEXT("w"), stdout); + +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stdout) + stdout = fopen(stdoutPath, TEXT("w")); +#else + newfp = fopen(stdoutPath, TEXT("w")); + if ( newfp ) { + *stdout = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + +#ifdef _WIN32_WCE + wcsncpy( stderrPath, path, SDL_arraysize(stdoutPath) ); + wcsncat( stderrPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#else + SDL_strlcpy( stderrPath, path, SDL_arraysize(stderrPath) ); + SDL_strlcat( stderrPath, DIR_SEPERATOR STDERR_FILE, SDL_arraysize(stderrPath) ); +#endif + + newfp = freopen(stderrPath, TEXT("w"), stderr); +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stderr) + stderr = fopen(stderrPath, TEXT("w")); +#else + newfp = fopen(stderrPath, TEXT("w")); + if ( newfp ) { + *stderr = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ + setbuf(stderr, NULL); /* No buffering */ +#endif /* !NO_STDIO_REDIRECT */ + +#ifdef _WIN32_WCE + nLen = wcslen(szCmdLine)+128+1; + bufp = SDL_stack_alloc(wchar_t, nLen*2); + wcscpy (bufp, TEXT("\"")); + GetModuleFileName(NULL, bufp+1, 128-3); + wcscpy (bufp+wcslen(bufp), TEXT("\" ")); + wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); + nLen = wcslen(bufp)+1; + cmdline = SDL_stack_alloc(char, nLen); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); +#else + /* Grab the command line */ + bufp = GetCommandLine(); + nLen = SDL_strlen(bufp)+1; + cmdline = SDL_stack_alloc(char, nLen); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + SDL_strlcpy(cmdline, bufp, nLen); +#endif + + /* Parse it into argv and argc */ + argc = ParseCommandLine(cmdline, NULL); + argv = SDL_stack_alloc(char*, argc+1); + if ( argv == NULL ) { + return OutOfMemory(); + } + ParseCommandLine(cmdline, argv); + + /* Run the main program (after a little SDL initialization) */ + console_main(argc, argv); + + /* Hush little compiler, don't you cry... */ + return 0; +} diff --git a/stella/src/win32/SettingsWin32.cxx b/stella/src/win32/SettingsWin32.cxx index 634e435d2..98ac5f3e3 100644 --- a/stella/src/win32/SettingsWin32.cxx +++ b/stella/src/win32/SettingsWin32.cxx @@ -1,37 +1,37 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: SettingsWin32.cxx,v 1.27 2008-02-06 13:45:24 stephena Exp $ -//============================================================================ - -#include "bspf.hxx" -#include "Settings.hxx" -#include "SettingsWin32.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SettingsWin32::SettingsWin32(OSystem* osystem) - : Settings(osystem) -{ - // Anything less than this usually causes sound skipping - setInternal("fragsize", "2048"); - // Most Windows systems work better without this - setInternal("dirtyrects", "false"); - setInternal("romdir", "c:\\"); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SettingsWin32::~SettingsWin32() -{ -} +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: SettingsWin32.cxx,v 1.28 2008-03-08 23:34:24 stephena Exp $ +//============================================================================ + +#include "bspf.hxx" +#include "Settings.hxx" +#include "SettingsWin32.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SettingsWin32::SettingsWin32(OSystem* osystem) + : Settings(osystem) +{ + // Anything less than this usually causes sound skipping + setInternal("fragsize", "2048"); + // Most Windows systems work better without this + setInternal("dirtyrects", "false"); + setInternal("romdir", "c:\\"); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SettingsWin32::~SettingsWin32() +{ +} diff --git a/stella/src/win32/SettingsWin32.hxx b/stella/src/win32/SettingsWin32.hxx index 291136bac..e987f194a 100644 --- a/stella/src/win32/SettingsWin32.hxx +++ b/stella/src/win32/SettingsWin32.hxx @@ -1,41 +1,40 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: SettingsWin32.hxx,v 1.9 2008-02-06 13:45:24 stephena Exp $ -//============================================================================ - -#ifndef SETTINGS_WIN32_HXX -#define SETTINGS_WIN32_HXX - -class OSystem; - -#include "bspf.hxx" - - -class SettingsWin32 : public Settings -{ - public: - /** - Create a new UNIX settings object - */ - SettingsWin32(OSystem* osystem); - - /** - Destructor - */ - virtual ~SettingsWin32(); -}; - -#endif +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: SettingsWin32.hxx,v 1.10 2008-03-08 23:34:24 stephena Exp $ +//============================================================================ + +#ifndef SETTINGS_WIN32_HXX +#define SETTINGS_WIN32_HXX + +class OSystem; + +#include "bspf.hxx" + +class SettingsWin32 : public Settings +{ + public: + /** + Create a new UNIX settings object + */ + SettingsWin32(OSystem* osystem); + + /** + Destructor + */ + virtual ~SettingsWin32(); +}; + +#endif diff --git a/stella/src/win32/Stella.vcproj b/stella/src/win32/Stella.vcproj index bcec2f694..040868e29 100755 --- a/stella/src/win32/Stella.vcproj +++ b/stella/src/win32/Stella.vcproj @@ -1,1543 +1,1552 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +