00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanUtils.h"
00028
00029
00030 #include "CeylanLogPlug.h"
00031 #include "CeylanStringUtils.h"
00032 #include "CeylanOperators.h"
00033
00034
00035
00036 #include "CeylanSystem.h"
00037 #include "CeylanFeatures.h"
00038
00039
00040 #include <cstdio>
00041 #include <ctime>
00042 #include <cstring>
00043
00044 #include <algorithm>
00045 #include <iostream>
00046
00047
00048
00049 #ifdef CEYLAN_USES_CONFIG_H
00050 #include <CeylanConfig.h>
00051 #endif // CEYLAN_USES_CONFIG_H
00052
00053 #if CEYLAN_ARCH_NINTENDO_DS
00054 #include "CeylanConfigForNintendoDS.h"
00055 #endif // CEYLAN_ARCH_NINTENDO_DS
00056
00057
00058
00059 #if defined(CEYLAN_ARCH_NINTENDO_DS) && CEYLAN_ARCH_NINTENDO_DS == 1
00060
00061 #ifdef CEYLAN_RUNS_ON_ARM9
00062
00063
00064
00065 extern const Ceylan::DSBinaryInput Ceylan::ButtonX = KEY_X ;
00066 extern const Ceylan::DSBinaryInput Ceylan::ButtonY = KEY_Y ;
00067
00068 extern const Ceylan::DSBinaryInput Ceylan::ButtonA = KEY_A ;
00069 extern const Ceylan::DSBinaryInput Ceylan::ButtonB = KEY_B ;
00070
00071 extern const Ceylan::DSBinaryInput Ceylan::ButtonStart = KEY_START ;
00072 extern const Ceylan::DSBinaryInput Ceylan::ButtonSelect = KEY_SELECT ;
00073
00074 extern const Ceylan::DSBinaryInput Ceylan::ButtonLeft = KEY_LEFT ;
00075 extern const Ceylan::DSBinaryInput Ceylan::ButtonRight = KEY_RIGHT ;
00076
00077 extern const Ceylan::DSBinaryInput Ceylan::ButtonUp = KEY_UP ;
00078 extern const Ceylan::DSBinaryInput Ceylan::ButtonDown = KEY_DOWN ;
00079
00080 extern const Ceylan::DSBinaryInput Ceylan::ShoulderButtonLeft = KEY_L ;
00081 extern const Ceylan::DSBinaryInput Ceylan::ShoulderButtonRight = KEY_R ;
00082
00083 extern const Ceylan::DSBinaryInput Ceylan::StylusContact = KEY_TOUCH ;
00084 extern const Ceylan::DSBinaryInput Ceylan::LidOpen = KEY_LID ;
00085
00086
00087
00088 extern const Ceylan::DSBinaryInput Ceylan::AllUserInputs = ButtonX | ButtonY
00089 | ButtonA | ButtonB | ButtonStart | ButtonSelect
00090 | ButtonLeft | ButtonRight | ButtonUp | ButtonDown
00091 | ShoulderButtonLeft | ShoulderButtonRight | StylusContact ;
00092
00093
00094 #endif // CEYLAN_RUNS_ON_ARM9
00095
00096
00097 #endif // CEYLAN_ARCH_NINTENDO_DS
00098
00099
00100
00101 extern "C"
00102 {
00103
00104 #ifdef CEYLAN_USES_TERMIOS_H
00105 #include <termios.h>
00106 #endif // CEYLAN_USES_TERMIOS_H
00107
00108 #ifdef CEYLAN_USES_CONIO_H
00109 #include <conio.h>
00110 #endif // CEYLAN_USES_CONIO_H
00111
00112 }
00113
00114
00115
00116 const Ceylan::ExitCode Ceylan::ExitSuccess = 0 ;
00117 const Ceylan::ExitCode Ceylan::ExitFailure = 1 ;
00118 const Ceylan::ExitCode Ceylan::ExitDebugFailure = 10 ;
00119
00120 const std::string Ceylan::DefaultWaitForKeyMessage(
00121 "< Press any key to continue >" ) ;
00122
00123
00124 using std::string ;
00125 using std::list ;
00126
00127
00128 using namespace Ceylan ;
00129 using namespace Ceylan::Log ;
00130
00131
00132
00133
00134 #define CEYLAN_DEBUG_VERSION 0
00135
00136 const Ceylan::LibtoolVersion & Ceylan::GetVersion()
00137 {
00138
00139
00140 #if CEYLAN_DEBUG_VERSION
00141
00142
00143
00144 LibtoolVersion * ceylanVersion ;
00145
00146 try
00147 {
00148
00149 ceylanVersion = new LibtoolVersion( CEYLAN_LIBTOOL_VERSION ) ;
00150
00151 }
00152 catch( const Ceylan::Exception & e )
00153 {
00154
00155 Ceylan::emergencyShutdown( "Ceylan::GetVersion failed: "
00156 + e.toString() ) ;
00157
00158 }
00159
00160 return * ceylanVersion ;
00161
00162
00163 #else // CEYLAN_DEBUG_VERSION
00164
00165 static LibtoolVersion ceylanVersion( CEYLAN_LIBTOOL_VERSION ) ;
00166 return ceylanVersion ;
00167
00168 #endif // CEYLAN_DEBUG_VERSION
00169
00170 }
00171
00172
00173
00174 void Ceylan::parseCommandLineOptions( std::string & readExecutableName,
00175 list<string> & readOptions, Ceylan::Uint16 argumentCount,
00176 char ** argumentVector )
00177 {
00178
00179 readExecutableName = string( argumentVector[0] ) ;
00180
00181 for ( Ceylan::Uint16 arg = 1 ; arg < argumentCount; arg++ )
00182 readOptions.push_back( argumentVector[arg] ) ;
00183
00184 }
00185
00186
00187
00188 void Ceylan::emergencyShutdown( const string & message )
00189 {
00190
00191 string outputMessage = "Fatal error: "
00192 "Ceylan is performing an emergency shutdown "
00193 "since an abnormal situation occured. "
00194 + message ;
00195
00196 std::cerr << std::endl << outputMessage << std::endl << std::flush ;
00197
00198
00199 if ( Log::LogPlug::IsFatalLogSourceAvailable() )
00200 Log::LogPlug::fatal( outputMessage ) ;
00201
00202
00203 Log::LogPlug::StopService( false ) ;
00204
00205 ::exit( ExitFailure ) ;
00206
00207 }
00208
00209
00210
00211 bool Ceylan::keyboardHit()
00212 {
00213
00214 #if CEYLAN_ARCH_NINTENDO_DS
00215
00216 #ifdef CEYLAN_RUNS_ON_ARM7
00217
00218 throw UtilsException( "Ceylan::keyboardHit: only available on the ARM9.") ;
00219
00220 #elif defined(CEYLAN_RUNS_ON_ARM9)
00221
00222
00223 Ceylan::System::InitializeInterrupts() ;
00224
00225
00226
00227 scanKeys() ;
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 return ( ( keysHeld() & AllUserInputs ) != 0 ) ;
00243
00244 #endif // CEYLAN_RUNS_ON_ARM7
00245
00246
00247 #else // CEYLAN_ARCH_NINTENDO_DS
00248
00249
00250 #ifdef CEYLAN_USES_TERMIOS_H
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 struct termios term, oterm ;
00262 System::FileDescriptor fd = 0 ;
00263 KeyChar c = 0 ;
00264
00265
00266 ::tcgetattr( fd, & oterm ) ;
00267
00268
00269 ::memcpy( &term, &oterm, sizeof( term ) ) ;
00270
00271
00272
00273
00274
00275
00276 term.c_lflag &= ! ICANON ;
00277 term.c_cc[ VMIN ] = 0 ;
00278 term.c_cc[ VTIME ] = 1 ;
00279 ::tcsetattr( fd, TCSANOW, & term ) ;
00280
00281
00282
00283
00284
00285
00286 c =::getchar() ;
00287
00288
00289 ::tcsetattr( fd, TCSANOW, & oterm ) ;
00290
00291
00292
00293
00294
00295 if ( c != -1 )
00296 ::ungetc( c, stdin ) ;
00297
00298
00299 return ( c != -1 ) ;
00300
00301
00302 #elif defined(CEYLAN_USES_CONIO_H)
00303
00304 return ( ::_kbhit() != 0 ) ;
00305
00306 #else // CEYLAN_USES_CONIO_H
00307
00308 #error Ceylan::KeyboardHit not available for your architecture.
00309
00310 #endif // CEYLAN_USES_TERMIOS_H
00311
00312 #endif // CEYLAN_ARCH_NINTENDO_DS
00313
00314 }
00315
00316
00317
00318 KeyChar Ceylan::getChar()
00319 {
00320
00321 #if CEYLAN_ARCH_NINTENDO_DS
00322
00323 #ifdef CEYLAN_RUNS_ON_ARM7
00324
00325
00326 throw UtilsException( "Ceylan::getChar: "
00327 "not available on the Nintendo DS ARM7." ) ;
00328
00329 #else // CEYLAN_RUNS_ON_ARM7
00330
00331
00332 Ceylan::System::InitializeInterrupts() ;
00333
00334 KeyChar key ;
00335
00336 do
00337 {
00338
00339 System::atomicSleep() ;
00340 scanKeys() ;
00341 key = keysDownRepeat() & AllUserInputs ;
00342
00343 }
00344 while ( key == 0 ) ;
00345
00346 return key ;
00347
00348 #endif // CEYLAN_RUNS_ON_ARM7
00349
00350
00351 #else // CEYLAN_ARCH_NINTENDO_DS
00352
00353
00354 #ifdef CEYLAN_USES_TERMIOS_H
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 KeyChar c ;
00367 int fd = 0 ;
00368
00369 struct termios term, oterm ;
00370
00371
00372 ::tcgetattr( fd, & oterm ) ;
00373
00374
00375 ::memcpy( &term, & oterm, sizeof( term ) ) ;
00376
00377
00378
00379
00380
00381
00382
00383
00384 term.c_lflag &= ! ICANON ;
00385 term.c_cc[ VMIN ] = 1 ;
00386 term.c_cc[ VTIME ] = 0 ;
00387 ::tcsetattr( fd, TCSANOW, & term ) ;
00388
00389
00390 c =::getchar() ;
00391
00392
00393 ::tcsetattr( fd, TCSANOW, & oterm ) ;
00394
00395
00396 return c ;
00397
00398
00399 #elif defined(CEYLAN_USES_CONIO_H)
00400
00401 return::_getch() ;
00402
00403 #else // defined(CEYLAN_USES_CONIO_H)
00404
00405 #error Ceylan::GetChar() not defined for your architecture.
00406
00407 #endif // CEYLAN_USES_TERMIOS_H
00408
00409 #endif // CEYLAN_ARCH_NINTENDO_DS
00410
00411 }
00412
00413
00414
00415 KeyChar Ceylan::waitForKey( const string & message )
00416 {
00417
00418 #if CEYLAN_ARCH_NINTENDO_DS
00419
00420 #ifdef CEYLAN_RUNS_ON_ARM7
00421
00422 throw UtilsException(
00423 "Ceylan::waitForKey: only available on the ARM9." ) ;
00424
00425 #else // CEYLAN_RUNS_ON_ARM7
00426
00427
00428 if ( ! message.empty() )
00429 display( message ) ;
00430
00431 return Ceylan::getChar() ;
00432
00433 #endif // CEYLAN_RUNS_ON_ARM7
00434
00435
00436 #else // CEYLAN_ARCH_NINTENDO_DS
00437
00438
00439 bool sleepFailed = false ;
00440
00441
00442 if ( ! message.empty() )
00443 display( message ) ;
00444
00445
00446 while ( ! Ceylan::keyboardHit() )
00447 {
00448
00449
00450
00451 if ( System::areSubSecondSleepsAvailable() && ! sleepFailed )
00452 {
00453 try
00454 {
00455 Ceylan::System::atomicSleep() ;
00456 }
00457 catch( const System::SystemException & e )
00458 {
00459 LogPlug::error( "Ceylan::waitForKey: sleep failed: "
00460 + e.toString() ) ;
00461
00462
00463 sleepFailed = true ;
00464
00465 }
00466
00467 }
00468
00469
00470 }
00471
00472 return Ceylan::getChar() ;
00473
00474 #endif // CEYLAN_ARCH_NINTENDO_DS
00475
00476 }
00477
00478
00479
00480 void Ceylan::checkpoint( const std::string & message )
00481 {
00482
00483 static Ceylan::Uint32 checkpointCount = 1 ;
00484
00485 if ( message.empty() )
00486 display( "Checkpoint [" + Ceylan::toString( checkpointCount )
00487 + "]" ) ;
00488 else
00489 display( "Checkpoint [" + Ceylan::toString( checkpointCount )
00490 + "]: " + message ) ;
00491
00492 checkpointCount++ ;
00493
00494 }
00495
00496
00497
00498 void Ceylan::breakpoint( const std::string & message )
00499 {
00500
00501 static Ceylan::Uint32 breakpointCount = 1 ;
00502
00503 if ( ! message.empty() )
00504 display( "Breakpoint number #" + Ceylan::toString( breakpointCount )
00505 + ": " + message ) ;
00506 else
00507 display( "Successfully arrived at breakpoint number #"
00508 + Ceylan::toString( breakpointCount ) + "." ) ;
00509
00510 breakpointCount++ ;
00511
00512 waitForKey() ;
00513
00514 }
00515