PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/OsmoseConfiguration.cpp

https://github.com/johan--/gamingcape_osmose
C++ | 609 lines | 511 code | 46 blank | 52 comment | 44 complexity | 4bc30fb4445e9fa58bc33956c880c2a4 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*****************************************************************************
  2. *
  3. * File: OsmoseConfiguration.cpp
  4. *
  5. * Project: Osmose emulator.
  6. *
  7. * Description: This class will handle emulator all things related to Osmose
  8. * configuration, like keyboard config, or default path ect...
  9. *
  10. * Author: Vedder Bruno
  11. * Date: 08/10/2004, 18h00
  12. *
  13. * URL: http://bcz.emu-france.com/
  14. *****************************************************************************/
  15. #include "OsmoseConfiguration.h"
  16. #ifdef __USE_UNIX98
  17. #include <pwd.h> // For passwd structure
  18. #include <unistd.h> // For getlogin, ...
  19. #include <sys/stat.h> // For mkdir, chown, ...
  20. #endif
  21. #ifdef __WIN32
  22. #include <windows.h>
  23. #endif
  24. OsmoseConfiguration::OsmoseConfiguration(const char *filename)
  25. {
  26. bool ret = false;
  27. string default_filename;
  28. // Try to load config from file.
  29. #ifdef __USE_UNIX98 // Unices
  30. passwd * password;
  31. char * Temp = getlogin();
  32. if ( Temp != NULL )
  33. {
  34. password = getpwnam(Temp);
  35. }
  36. else
  37. {
  38. password = getpwuid(geteuid());
  39. }
  40. if ( password != NULL)
  41. {
  42. user_home_folder = password->pw_dir;
  43. //User = password->pw_name; // Good to know
  44. default_filename = user_home_folder + "/.osmose/osmose.ini";
  45. }
  46. #endif
  47. ret = loadConfigurationFromFile(filename);
  48. if (ret != true)
  49. {
  50. // If unsuccessful, setup default configuration.
  51. reset();
  52. }
  53. }
  54. OsmoseConfiguration::OsmoseConfiguration()
  55. {
  56. // Here we should attempt to read default configuration file first,
  57. // And create one if there aren't.
  58. // The folder where it will we be created, and where it will be read by default depends on the OS we are using.
  59. // I'll give here the code to be used under Linux/Unix/BSD, and Windows...
  60. string default_filename;
  61. #ifdef _WIN32
  62. default_filename = "osmose.ini";
  63. #endif
  64. #ifdef __USE_UNIX98 // Unices
  65. default_filename = "./osmose_files/osmose.ini";
  66. #endif
  67. // Try to load config from file.
  68. bool ret = false;
  69. ret = loadConfigurationFromFile(default_filename.c_str());
  70. if (ret != true)
  71. {
  72. // If unsuccessful, setup default configuration.
  73. // And don't forget to create a default config file...
  74. reset();
  75. // Default config creation
  76. #ifdef __USE_UNIX98 // Unices.
  77. // Create Osmose directory.
  78. int md = 0;
  79. md = mkdir( string("./osmose_files").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  80. if (md == -1)
  81. {
  82. cout << "Unable to create ./osmose_files/ directory." << endl;
  83. }
  84. // Create bbr subdirectory.
  85. md = mkdir( string("./osmose_files/bbr").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  86. if (md == -1)
  87. {
  88. cout << "Unable to create bbr subdirectory." << endl;
  89. }
  90. // Create snd subdirectory.
  91. md = mkdir( string("./osmose_files/snd").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  92. if (md == -1)
  93. {
  94. cout << "Unable to create snd subdirectory." << endl;
  95. }
  96. // Create screen subdirectory.
  97. md = mkdir( string("./osmose_files/screen").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  98. if (md == -1)
  99. {
  100. cout << "Unable to create screen subdirectory." << endl;
  101. }
  102. // Create tile subdirectory.
  103. md = mkdir( string("./osmose_files/tiles").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  104. if (md == -1)
  105. {
  106. cout << "Unable to create tiles subdirectory." << endl;
  107. }
  108. // Create Save State subdirectory.
  109. md = mkdir( string("./osmose_files/saves").c_str(), S_IRWXU | S_IRWXG | S_IXOTH);
  110. if (md == -1)
  111. {
  112. cout << "Unable to create saves subdirectory." << endl;
  113. }
  114. #endif // __USE_UNIX98
  115. #ifdef __WIN32
  116. bool md = CreateDirectory(".\\screen", NULL);
  117. if (!md){cout << "Unable to create screen subdirectory." << endl;}
  118. md = CreateDirectory(".\\tiles", NULL);
  119. if (!md){cout << "Unable to create tiles subdirectory." << endl;}
  120. md = CreateDirectory(".\\snd", NULL);
  121. if (!md){cout << "Unable to create snd subdirectory." << endl;}
  122. md = CreateDirectory(".\\bbr", NULL);
  123. if (!md){cout << "Unable to create bbr subdirectory." << endl;}
  124. md = CreateDirectory(".\\saves", NULL);
  125. if (!md){cout << "Unable to create saves subdirectory." << endl;}
  126. #endif
  127. ofstream file(default_filename.c_str(), ios::out);
  128. if (file.is_open() == false )
  129. {
  130. cerr << "Unable to create '" << default_filename << "' init file. Default configuration loaded." << endl;
  131. }
  132. else // Default ini file creation
  133. {
  134. file << "#########################################################################\n";
  135. file << "#\n";
  136. file << "# This is an example of Osmose .ini file.\n";
  137. file << "# It can be used to modify keyboard configuration.\n";
  138. file << "# Lines beginning with '#' are considered as comment and\n";
  139. file << "# will be ignored.\n";
  140. file << "#\n";
  141. file << "# For retrieving key correspondance osmose looks for these\n";
  142. file << "# tags:\n";
  143. file << "#\n";
  144. file << "# SCREENSHOT\n";
  145. file << "# SOUNDSHOT\n";
  146. file << "# QUIT\n";
  147. file << "# TILESHOT\n";
  148. file << "# DEBUGGER\n";
  149. file << "# PAUSE\n";
  150. file << "# PAD1_UP\n";
  151. file << "# PAD1_DOWN\n";
  152. file << "# PAD1_LEFT\n";
  153. file << "# PAD1_RIGHT\n";
  154. file << "# PAD1_BUTTON_A\n";
  155. file << "# PAD1_BUTTON_B\n";
  156. file << "# PAD2_UP\n";
  157. file << "# PAD2_DOWN\n";
  158. file << "# PAD2_LEFT\n";
  159. file << "# PAD2_RIGHT\n";
  160. file << "# PAD2_BUTTON_A\n";
  161. file << "# PAD2_BUTTON_B\n";
  162. file << "# GAMEGEAR_START\n";
  163. file << "#\n";
  164. file << "# If a tag is found, it looks for a valid key definition.\n";
  165. file << "# The list of valid keys are listed in comment at the end of\n";
  166. file << "# this file. All definition begins w ith'SDLK'.n \n";
  167. file << "# Note that missing tags will result in disabled key. You can\n";
  168. file << "# disallow screenshot in emulation by commenting the line with\n";
  169. file << "# SCREENSHOT tag.\n";
  170. file << "#\n";
  171. file << "#########################################################################\n\n";
  172. file << "# Configuration Starts Here !\n\n";
  173. file << "#\n";
  174. file << "# General emulation keys:\n";
  175. file << "#\n\n";
  176. file << "SCREENSHOT = SDLK_F2\n";
  177. file << "SOUNDSHOT = SDLK_F1\n";
  178. file << "QUIT = SDLK_ESCAPE\n";
  179. file << "TILESHOT = SDLK_F3\n";
  180. file << "DEBUGGER = SDLK_d\n";
  181. file << "PAUSE = SDLK_p\n\n";
  182. file << "#\n";
  183. file << "# First Player PAD:\n";
  184. file << "#\n\n";
  185. file << "PAD1_UP = SDLK_UP\n";
  186. file << "PAD1_DOWN = SDLK_DOWN\n";
  187. file << "PAD1_LEFT = SDLK_LEFT\n";
  188. file << "PAD1_RIGHT = SDLK_RIGHT\n";
  189. file << "PAD1_BUTTON_A = SDLK_LCTRL\n";
  190. file << "PAD1_BUTTON_B = SDLK_LALT\n\n";
  191. file << "#\n";
  192. file << "# Second Player PAD:\n";
  193. file << "#\n\n";
  194. file << "PAD2_UP = SDLK_KP5\n";
  195. file << "PAD2_DOWN = SDLK_KP2\n";
  196. file << "PAD2_LEFT = SDLK_KP1\n";
  197. file << "PAD2_RIGHT = SDLK_KP3\n";
  198. file << "PAD2_BUTTON_A = SDLK_n\n";
  199. file << "PAD2_BUTTON_B = SDLK_b\n\n";
  200. file << "#\n";
  201. file << "# GAME GEAR Specific:\n";
  202. file << "#\n\n";
  203. file << "GAMEGEAR_START = SDLK_RETURN\n\n";
  204. file << "# Configuration Ends Here !\n\n\n\n\n\n\n";
  205. file << "#########################################################################\n";
  206. file << "#\n";
  207. file << "# You can remove this list, it's just provided to help user to\n";
  208. file << "# configure osmose emulator.\n";
  209. file << "#\n";
  210. file << "# Valid Key definitions:\n";
  211. file << "# ----------------------\n";
  212. file << "#\n";
  213. file << "# SDLK_BACKSPACE\n";
  214. file << "# SDLK_TAB\n";
  215. file << "# SDLK_CLEAR\n";
  216. file << "# SDLK_RETURN\n";
  217. file << "# SDLK_PAUSE\n";
  218. file << "# SDLK_ESCAPE\n";
  219. file << "# SDLK_SPACE\n";
  220. file << "# SDLK_EXCLAIM\n";
  221. file << "# SDLK_QUOTEDBL\n";
  222. file << "# SDLK_HASH\n";
  223. file << "# SDLK_DOLLAR\n";
  224. file << "# SDLK_AMPERSAND\n";
  225. file << "# SDLK_QUOTE\n";
  226. file << "# SDLK_LEFTPAREN\n";
  227. file << "# SDLK_RIGHTPAREN\n";
  228. file << "# SDLK_ASTERISK\n";
  229. file << "# SDLK_PLUS\n";
  230. file << "# SDLK_COMMA\n";
  231. file << "# SDLK_MINUS\n";
  232. file << "# SDLK_PERIOD\n";
  233. file << "# SDLK_SLASH\n";
  234. file << "# SDLK_0\n";
  235. file << "# SDLK_1\n";
  236. file << "# SDLK_2\n";
  237. file << "# SDLK_3\n";
  238. file << "# SDLK_4\n";
  239. file << "# SDLK_5\n";
  240. file << "# SDLK_6\n";
  241. file << "# SDLK_7\n";
  242. file << "# SDLK_8\n";
  243. file << "# SDLK_9\n";
  244. file << "# SDLK_COLON\n";
  245. file << "# SDLK_SEMICOLON\n";
  246. file << "# SDLK_LESS\n";
  247. file << "# SDLK_EQUALS\n";
  248. file << "# SDLK_GREATER\n";
  249. file << "# SDLK_QUESTION\n";
  250. file << "# SDLK_AT\n";
  251. file << "#\n";
  252. file << "# -Don't use uppercase letters\n";
  253. file << "#\n";
  254. file << "# SDLK_LEFTBRACKET\n";
  255. file << "# SDLK_BACKSLASH\n";
  256. file << "# SDLK_RIGHTBRACKET\n";
  257. file << "# SDLK_CARET\n";
  258. file << "# SDLK_UNDERSCORE\n";
  259. file << "# SDLK_BACKQUOTE\n";
  260. file << "# SDLK_a\n";
  261. file << "# SDLK_b\n";
  262. file << "# SDLK_c\n";
  263. file << "# SDLK_d\n";
  264. file << "# SDLK_e\n";
  265. file << "# SDLK_f\n";
  266. file << "# SDLK_g\n";
  267. file << "# SDLK_h\n";
  268. file << "# SDLK_i\n";
  269. file << "# SDLK_j\n";
  270. file << "# SDLK_k\n";
  271. file << "# SDLK_l\n";
  272. file << "# SDLK_m\n";
  273. file << "# SDLK_n\n";
  274. file << "# SDLK_o\n";
  275. file << "# SDLK_p\n";
  276. file << "# SDLK_q\n";
  277. file << "# SDLK_r\n";
  278. file << "# SDLK_s\n";
  279. file << "# SDLK_t\n";
  280. file << "# SDLK_u\n";
  281. file << "# SDLK_v\n";
  282. file << "# SDLK_w\n";
  283. file << "# SDLK_x\n";
  284. file << "# SDLK_y\n";
  285. file << "# SDLK_z\n";
  286. file << "# SDLK_DELETE\n";
  287. file << "#\n\n";
  288. file << "# -Numeric keypad\n";
  289. file << "#\n";
  290. file << "# SDLK_KP0\n";
  291. file << "# SDLK_KP1\n";
  292. file << "# SDLK_KP2\n";
  293. file << "# SDLK_KP3\n";
  294. file << "# SDLK_KP4\n";
  295. file << "# SDLK_KP5\n";
  296. file << "# SDLK_KP6\n";
  297. file << "# SDLK_KP7\n";
  298. file << "# SDLK_KP8\n";
  299. file << "# SDLK_KP9\n";
  300. file << "# SDLK_KP_PERIOD\n";
  301. file << "# SDLK_KP_DIVIDE\n";
  302. file << "# SDLK_KP_MULTIPLY\n";
  303. file << "# SDLK_KP_MINUS\n";
  304. file << "# SDLK_KP_PLUS\n";
  305. file << "# SDLK_KP_ENTER\n";
  306. file << "# SDLK_KP_EQUALS\n";
  307. file << "#\n";
  308. file << "# -Arrows + Home/End p\n";
  309. file << "#\n";
  310. file << "# SDLK_UP\n";
  311. file << "# SDLK_DOWN\n";
  312. file << "# SDLK_RIGHT\n";
  313. file << "# SDLK_LEFT\n";
  314. file << "# SDLK_INSERT\n";
  315. file << "# SDLK_HOME\n";
  316. file << "# SDLK_END\n";
  317. file << "# SDLK_PAGEUP\n";
  318. file << "# SDLK_PAGEDOWN\n";
  319. file << "#\n";
  320. file << "# -Function keys\n";
  321. file << "#\n";
  322. file << "# SDLK_F1\n";
  323. file << "# SDLK_F2\n";
  324. file << "# SDLK_F3\n";
  325. file << "# SDLK_F4\n";
  326. file << "# SDLK_F5\n";
  327. file << "# SDLK_F6\n";
  328. file << "# SDLK_F7\n";
  329. file << "# SDLK_F8\n";
  330. file << "# SDLK_F9\n";
  331. file << "# SDLK_F10\n";
  332. file << "# SDLK_F11\n";
  333. file << "# SDLK_F12\n";
  334. file << "# SDLK_F13\n";
  335. file << "# SDLK_F14\n";
  336. file << "# SDLK_F15\n";
  337. file << "#\n";
  338. file << "# -Key state modifier\n";
  339. file << "#\n";
  340. file << "# SDLK_NUMLOCK\n";
  341. file << "# SDLK_CAPSLOCK\n";
  342. file << "# SDLK_SCROLLOCK\n";
  343. file << "# SDLK_RSHIFT\n";
  344. file << "# SDLK_LSHIFT\n";
  345. file << "# SDLK_RCTRL\n";
  346. file << "# SDLK_LCTRL\n";
  347. file << "# SDLK_RALT\n";
  348. file << "# SDLK_LALT\n";
  349. file << "# SDLK_RMETA\n";
  350. file << "# SDLK_LMETA\n";
  351. file << "# SDLK_LSUPER\n";
  352. file << "# SDLK_RSUPER\n";
  353. file << "# SDLK_COMPOSE\n";
  354. file << "#\n";
  355. file << "# -Miscellaneous functions\n";
  356. file << "#\n";
  357. file << "# SDLK_HELP\n";
  358. file << "# SDLK_PRINT\n";
  359. file << "# SDLK_SYSREQ\n";
  360. file << "# SDLK_BREAK\n";
  361. file << "# SDLK_MENU\n";
  362. file << "# SDLK_EURO\n";
  363. file << "# SDLK_UNDO\n";
  364. file << "#\n";
  365. file << "#########################################################################\n";
  366. } // End of default ini file creation
  367. file.close();
  368. }
  369. }
  370. /*--------------------------------------------------------------------*/
  371. /* This method Set up Osmose default configuration. */
  372. /*--------------------------------------------------------------------*/
  373. void OsmoseConfiguration::reset()
  374. {
  375. P1_UP_KEY = SDLK_UP;
  376. P1_DOWN_KEY = SDLK_DOWN;
  377. P1_LEFT_KEY = SDLK_LEFT;
  378. P1_RIGHT_KEY = SDLK_RIGHT;
  379. P1_A_KEY = SDLK_LCTRL;
  380. P1_B_KEY = SDLK_LALT;
  381. P2_UP_KEY = SDLK_KP5;
  382. P2_DOWN_KEY = SDLK_KP2;
  383. P2_LEFT_KEY = SDLK_KP1;
  384. P2_RIGHT_KEY = SDLK_KP3;
  385. P2_A_KEY = SDLK_n;
  386. P2_B_KEY = SDLK_b;
  387. GG_START_KEY = SDLK_RETURN;
  388. TILESHOT_KEY = SDLK_F3;
  389. SCREENSHOT_KEY = SDLK_F2;
  390. SOUNDSHOT_KEY = SDLK_F1;
  391. PAUSE_KEY = SDLK_p;
  392. QUIT_KEY = SDLK_ESCAPE;
  393. DEBUGGER_KEY = SDLK_d;
  394. }
  395. /*--------------------------------------------------------------------*/
  396. /* This method Set up Osmose configuration from by loading it from a */
  397. /* given file. Lines begining with # are considered to be comment. */
  398. /* Format expected: */
  399. /* PAD1_UP = SDLK_UP */
  400. /*--------------------------------------------------------------------*/
  401. bool OsmoseConfiguration::loadConfigurationFromFile(const char *f)
  402. {
  403. bool ret = false;
  404. // Reset all keys.
  405. P1_UP_KEY = 0;
  406. P1_DOWN_KEY = 0;
  407. P1_LEFT_KEY = 0;
  408. P1_RIGHT_KEY = 0;
  409. P1_A_KEY = 0;
  410. P1_B_KEY = 0;
  411. P2_UP_KEY = 0;
  412. P2_DOWN_KEY = 0;
  413. P2_LEFT_KEY = 0;
  414. P2_RIGHT_KEY = 0;
  415. P2_A_KEY = 0;
  416. P2_B_KEY = 0;
  417. GG_START_KEY = 0;
  418. SCREENSHOT_KEY = 0;
  419. TILESHOT_KEY = 0;
  420. SOUNDSHOT_KEY = 0;
  421. PAUSE_KEY = 0;
  422. QUIT_KEY = 0;
  423. DEBUGGER_KEY = 0;
  424. ifstream file(f, ios::in);
  425. if (file.is_open() == false )
  426. {
  427. cerr << "Unable to open '" << f << "' init file. Default configuration loaded." << endl;
  428. return false;
  429. }
  430. ret = true;
  431. while (!file.eof())
  432. {
  433. string rd;
  434. char buffer[256];
  435. file.getline(buffer, 256);
  436. rd = string(buffer, 256);
  437. analyseLine(rd);
  438. }
  439. file.close();
  440. return ret;
  441. }
  442. /*--------------------------------------------------------------------*/
  443. /* This method looks up for an entry into key_list, and return it's */
  444. /* associated value. If not found, return value is -1. */
  445. /*--------------------------------------------------------------------*/
  446. int OsmoseConfiguration::findSDLKeySym(string wrd)
  447. {
  448. int ret = -1;
  449. int i = 0;
  450. bool found = false;
  451. while (key_list[i].key_value != -1)
  452. {
  453. if (key_list[i].key_name == wrd)
  454. {
  455. found = true;
  456. ret = key_list[i].key_value;
  457. }
  458. i++;
  459. }
  460. return ret;
  461. }
  462. /*--------------------------------------------------------------------*/
  463. /* This method returns true if the line does not start with # comment */
  464. /* if the line is not empty, and if the line contains a tag, an '=' */
  465. /* and a Valid SDL key name. */
  466. /*--------------------------------------------------------------------*/
  467. void OsmoseConfiguration::analyseLine(string rd)
  468. {
  469. unsigned int r;
  470. unsigned int comment_pos;
  471. string kn;
  472. int ks;
  473. #define KEY_NBR 19
  474. string k_list[] = {"PAD1_UP","PAD1_DOWN","PAD1_LEFT","PAD1_RIGHT","PAD1_BUTTON_A","PAD1_BUTTON_B",
  475. "PAD2_UP","PAD2_DOWN","PAD2_LEFT","PAD2_RIGHT","PAD2_BUTTON_A","PAD2_BUTTON_B",
  476. "PAUSE","QUIT","SCREENSHOT","TILESHOT","DEBUGGER","SOUNDSHOT","GAMEGEAR_START"};
  477. for (int i = 0; i < KEY_NBR; i++)
  478. {
  479. r = rd.find(k_list[i], 0);
  480. comment_pos = rd.find("#", 0);
  481. // Comment before TAG, skip this line.
  482. if ((r !=string::npos) && (comment_pos !=string::npos) && (comment_pos < r))
  483. return;
  484. if (r != string::npos)
  485. {
  486. int ind = 0;
  487. unsigned int p;
  488. // We have found a known tag.
  489. while(key_list[ind].key_value != -1)
  490. {
  491. p = rd.find(key_list[ind].key_name, 0);
  492. if (p != string::npos)
  493. {
  494. #ifdef CONFIGURATION_VERBOSE
  495. cout << k_list[i] << " is associated to keysym " << (int)key_list[ind].key_value << endl;
  496. #endif
  497. ks = key_list[ind].key_value;
  498. switch(i)
  499. {
  500. case 0:
  501. P1_UP_KEY = ks;
  502. break;
  503. case 1:
  504. P1_DOWN_KEY = ks;
  505. break;
  506. case 2:
  507. P1_LEFT_KEY = ks;
  508. break;
  509. case 3:
  510. P1_RIGHT_KEY = ks;
  511. break;
  512. case 4:
  513. P1_A_KEY = ks;
  514. break;
  515. case 5:
  516. P1_B_KEY = ks;
  517. break;
  518. case 6:
  519. P2_UP_KEY = ks;
  520. break;
  521. case 7:
  522. P2_DOWN_KEY = ks;
  523. break;
  524. case 8:
  525. P2_LEFT_KEY = ks;
  526. break;
  527. case 9:
  528. P2_RIGHT_KEY = ks;
  529. break;
  530. case 10:
  531. P2_A_KEY = ks;
  532. break;
  533. case 11:
  534. P2_B_KEY = ks;
  535. break;
  536. case 12:
  537. PAUSE_KEY = ks;
  538. break;
  539. case 13:
  540. QUIT_KEY = ks;
  541. break;
  542. case 14:
  543. SCREENSHOT_KEY = ks;
  544. break;
  545. case 15:
  546. TILESHOT_KEY = ks;
  547. break;
  548. case 16:
  549. DEBUGGER_KEY = ks;
  550. break;
  551. case 17:
  552. SOUNDSHOT_KEY = ks;
  553. break;
  554. case 18:
  555. GG_START_KEY = ks;
  556. break;
  557. }
  558. }
  559. ind++;
  560. }
  561. }
  562. }
  563. }