Guest User

Untitled

a guest
Aug 29th, 2018
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 51.33 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdarg>
  3. #include <math.h>
  4. #include "types.h"
  5.  
  6. #include <sys/stat.h>
  7. #include <retro_stat.h>
  8.  
  9. #include <libretro.h>
  10.  
  11. #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
  12. #include <glsm/glsm.h>
  13. #endif
  14. #include "../rend/rend.h"
  15. #include "../hw/sh4/sh4_mem.h"
  16.  
  17. #if defined(_XBOX) || defined(_WIN32)
  18. char slash = '\\';
  19. #else
  20. char slash = '/';
  21. #endif
  22.  
  23. u32 fskip;
  24. extern int screen_width;
  25. extern int screen_height;
  26. char save_dir[PATH_MAX];
  27. char eeprom_file[PATH_MAX];
  28. char nvmem_file[PATH_MAX];
  29. bool boot_to_bios;
  30.  
  31. static int astick_deadzone = 0;
  32. static int trigger_deadzone = 0;
  33. static bool digital_triggers = false;
  34. static bool allow_service_buttons = false;
  35.  
  36. u16 kcode[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
  37. u8 rt[4] = {0, 0, 0, 0};
  38. u8 lt[4] = {0, 0, 0, 0};
  39. u32 vks[4];
  40. s8 joyx[4], joyy[4];
  41.  
  42. bool enable_purupuru = true;
  43.  
  44. static bool first_run = true;
  45.  
  46. enum DreamcastController
  47. {
  48. DC_BTN_C = 1,
  49. DC_BTN_B = 1<<1,
  50. DC_BTN_A = 1<<2,
  51. DC_BTN_START = 1<<3,
  52. DC_DPAD_UP = 1<<4,
  53. DC_DPAD_DOWN = 1<<5,
  54. DC_DPAD_LEFT = 1<<6,
  55. DC_DPAD_RIGHT = 1<<7,
  56. DC_BTN_Z = 1<<8,
  57. DC_BTN_Y = 1<<9,
  58. DC_BTN_X = 1<<10,
  59. DC_BTN_D = 1<<11,
  60. DC_DPAD2_UP = 1<<12,
  61. DC_DPAD2_DOWN = 1<<13,
  62. DC_DPAD2_LEFT = 1<<14,
  63. DC_DPAD2_RIGHT = 1<<15,
  64.  
  65. DC_AXIS_LT = 0X10000,
  66. DC_AXIS_RT = 0X10001,
  67. DC_AXIS_X = 0X20000,
  68. DC_AXIS_Y = 0X20001,
  69. };
  70.  
  71. enum NAOMI_KEYS
  72. {
  73. NAOMI_SERVICE_KEY_1 = 1 << 0,
  74. NAOMI_TEST_KEY_1 = 1 << 1,
  75. NAOMI_SERVICE_KEY_2 = 1 << 2,
  76. NAOMI_TEST_KEY_2 = 1 << 3,
  77.  
  78. NAOMI_START_KEY = 1 << 4,
  79.  
  80. NAOMI_UP_KEY = 1 << 5,
  81. NAOMI_DOWN_KEY = 1 << 6,
  82. NAOMI_LEFT_KEY = 1 << 7,
  83. NAOMI_RIGHT_KEY = 1 << 8,
  84.  
  85. NAOMI_BTN0_KEY = 1 << 9,
  86. NAOMI_BTN1_KEY = 1 << 10,
  87. NAOMI_BTN2_KEY = 1 << 11,
  88. NAOMI_BTN3_KEY = 1 << 12,
  89. NAOMI_BTN4_KEY = 1 << 13,
  90. NAOMI_BTN5_KEY = 1 << 14,
  91. NAOMI_COIN_KEY = 1 << 15,
  92. };
  93.  
  94. struct retro_perf_callback perf_cb;
  95. retro_get_cpu_features_t perf_get_cpu_features_cb = NULL;
  96.  
  97. // Callbacks
  98. retro_log_printf_t log_cb = NULL;
  99. retro_video_refresh_t video_cb = NULL;
  100. retro_input_poll_t poll_cb = NULL;
  101. retro_input_state_t input_cb = NULL;
  102. retro_audio_sample_batch_t audio_batch_cb = NULL;
  103. retro_environment_t environ_cb = NULL;
  104. static retro_rumble_interface rumble;
  105.  
  106. int dc_init(int argc,wchar* argv[]);
  107. void dc_run();
  108. void dc_term(void);
  109. void dc_stop();
  110. void bm_Reset() ;
  111. extern Renderer* renderer;
  112. bool rend_single_frame();
  113. void rend_cancel_emu_wait();
  114.  
  115. static int co_argc;
  116. static wchar** co_argv;
  117.  
  118. char *game_data;
  119. char g_base_name[128];
  120. char game_dir[1024];
  121. char game_dir_no_slash[1024];
  122. static bool emu_inited = false;
  123. static bool performed_serialization = false;
  124. #if !defined(TARGET_NO_THREADS)
  125. static void *emu_thread_func(void *);
  126. static cThread emu_thread(&emu_thread_func, 0);
  127. static cMutex mtx_serialization ;
  128. static cMutex mtx_mainloop ;
  129. static void *emu_thread_func(void *)
  130. {
  131. char* argv[] = { "reicast" };
  132.  
  133. dc_init(1, argv);
  134.  
  135. emu_inited = true;
  136. while ( true )
  137. {
  138. printf("SERIAL - emuthread1\n") ;
  139. performed_serialization = false ;
  140. printf("SERIAL - emuthread2\n") ;
  141. mtx_mainloop.Lock() ;
  142. printf("SERIAL - emuthread3\n") ;
  143. dc_run();
  144. printf("SERIAL - emuthread4\n") ;
  145. mtx_mainloop.Unlock() ;
  146. printf("SERIAL - emuthread5\n") ;
  147.  
  148. mtx_serialization.Lock() ;
  149. printf("SERIAL - emuthread6\n") ;
  150. mtx_serialization.Unlock() ;
  151. printf("SERIAL - emuthread7\n") ;
  152.  
  153. if (!performed_serialization)
  154. break ;
  155. }
  156.  
  157. printf("SERIAL - emuthread8\n") ;
  158. dc_term();
  159. printf("SERIAL - emuthread9\n") ;
  160.  
  161. return NULL;
  162. }
  163. #endif
  164.  
  165.  
  166. void co_dc_yield(void)
  167. {
  168. #if !defined(TARGET_NO_THREADS)
  169. if (!settings.rend.ThreadedRendering)
  170. #endif
  171. {
  172. if (settings.UpdateMode || settings.UpdateModeForced)
  173. return;
  174. dc_stop();
  175. }
  176. }
  177.  
  178. void retro_set_video_refresh(retro_video_refresh_t cb)
  179. {
  180. video_cb = cb;
  181. }
  182.  
  183. void retro_set_audio_sample(retro_audio_sample_t cb)
  184. {
  185. // Nothing to do here
  186. }
  187.  
  188. void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
  189. {
  190. audio_batch_cb = cb;
  191. }
  192.  
  193. void retro_set_input_poll(retro_input_poll_t cb)
  194. {
  195. poll_cb = cb;
  196. }
  197.  
  198. void retro_set_input_state(retro_input_state_t cb)
  199. {
  200. input_cb = cb;
  201. }
  202.  
  203. static void input_set_deadzone_stick( int percent )
  204. {
  205. if ( percent >= 0 && percent <= 100 )
  206. astick_deadzone = (int)( percent * 0.01f * 0x8000);
  207. }
  208.  
  209. static void input_set_deadzone_trigger( int percent )
  210. {
  211. if ( percent >= 0 && percent <= 100 )
  212. trigger_deadzone = (int)( percent * 0.01f * 0x8000);
  213. }
  214.  
  215. void retro_set_environment(retro_environment_t cb)
  216. {
  217. environ_cb = cb;
  218.  
  219. struct retro_variable variables[] = {
  220. #if ((FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_X64) || TARGET_NO_JIT)
  221. {
  222. "reicast_cpu_mode",
  223. "CPU Mode (restart); "
  224. #if (FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86) || (HOST_CPU == CPU_ARM) || (HOST_CPU == CPU_X64)
  225. "dynamic_recompiler"
  226. #endif
  227. #ifdef TARGET_NO_JIT
  228. "|"
  229. "generic_recompiler"
  230. #endif
  231. ,
  232. },
  233. #endif
  234. {
  235. "reicast_boot_to_bios",
  236. "Boot to BIOS (restart); disabled|enabled",
  237. },
  238. {
  239. "reicast_system",
  240. "System type (restart); auto|dreamcast|naomi",
  241. },
  242. #ifdef HAVE_OIT
  243. {
  244. "reicast_oit_abuffer_size",
  245. "Accumulation pixel buffer size (restart); 512MB|1GB|2GB",
  246. },
  247. #endif
  248. {
  249. "reicast_internal_resolution",
  250. "Internal resolution (restart); 640x480|320x240|1280x960|1920x1440|2560x1920|3200x2400|3840x2880|4480x3360|5120x3840|5760x4320|6400x4800|7040x5280|7680x5760|8320x6240|8960x6720|9600x7200|10240x7680|10880x8160|11520x8640|12160x9120|12800x9600",
  251. },
  252. {
  253. #ifdef HAVE_OIT
  254. "reicast_oit_alpha_sorting",
  255. "Alpha sorting; per-pixel (accurate)",
  256. #else
  257. "reicast_alpha_sorting",
  258. "Alpha sorting; per-triangle (normal)|per-strip (fast, least accurate)",
  259. #endif
  260. },
  261. {
  262. "reicast_gdrom_fast_loading",
  263. "GDROM Fast Loading (inaccurate); disabled|enabled",
  264. },
  265. {
  266. "reicast_mipmapping",
  267. "Mipmapping; enabled|disabled",
  268. },
  269. {
  270. "reicast_volume_modifier_enable",
  271. "Volume modifier; enabled|disabled",
  272. },
  273. {
  274. "reicast_widescreen_hack",
  275. "Widescreen hack (restart); disabled|enabled",
  276. },
  277. {
  278. "reicast_audio_buffer_size",
  279. "Audio buffer size; 1024|2048",
  280. },
  281. {
  282. "reicast_cable_type",
  283. "Cable type; TV (RGB)|TV (VBS/Y+S/C)|VGA (RGB)",
  284. },
  285. {
  286. "reicast_broadcast",
  287. "Broadcast; PAL_M|PAL_N|NTSC|PAL|Default",
  288. },
  289. {
  290. "reicast_framerate",
  291. "Framerate; fullspeed|normal",
  292. },
  293. {
  294. "reicast_region",
  295. "Region; Default|Japan|USA|Europe",
  296. },
  297. {
  298. "reicast_analog_stick_deadzone",
  299. "Analog Stick Deadzone; 15%|20%|25%|30%|0%|5%|10%"
  300. },
  301. {
  302. "reicast_trigger_deadzone",
  303. "Trigger Deadzone; 0%|5%|10%|15%|20%|25%|30%"
  304. },
  305. {
  306. "reicast_digital_triggers",
  307. "Digital Triggers; disabled|enabled",
  308. },
  309. {
  310. "reicast_enable_dsp",
  311. "Enable DSP; enabled|disabled",
  312. },
  313. #ifndef HAVE_OIT
  314. {
  315. "reicast_precompile_shaders",
  316. "Precompile shaders; disabled|enabled",
  317. },
  318. #endif
  319. #ifdef HAVE_TEXUPSCALE
  320. {
  321. "reicast_texupscale",
  322. "Texture upscaling (xBRZ); off|2x|4x|6x",
  323. },
  324. {
  325. "reicast_texupscale_max_filtered_texture_size",
  326. "Texture upscaling max filtered size; 256|512|1024",
  327. },
  328. #endif
  329. {
  330. "reicast_enable_rtt",
  331. "Enable RTT (Render To Texture); enabled|disabled",
  332. },
  333. {
  334. "reicast_enable_rttb",
  335. "Enable RTT (Render To Texture) Buffer; disabled|enabled",
  336. },
  337. {
  338. "reicast_render_to_texture_upscaling",
  339. "Render To Texture Upscaling; 1x|2x|3x|4x|8x",
  340. },
  341. #if !defined(TARGET_NO_THREADS)
  342. {
  343. "reicast_threaded_rendering",
  344. "Threaded rendering (restart); disabled|enabled",
  345. },
  346. #endif
  347. {
  348. "reicast_enable_purupuru",
  349. "Purupuru Pack (restart); enabled|disabled"
  350. },
  351. {
  352. "reicast_allow_service_buttons",
  353. "Allow Naomi service buttons; disabled|enabled"
  354. },
  355. { NULL, NULL },
  356. };
  357.  
  358. cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
  359. }
  360.  
  361.  
  362. // Now comes the interesting stuff
  363. void retro_init(void)
  364. {
  365. screen_width = 640;
  366. screen_height = 480;
  367. // Logging
  368. struct retro_log_callback log;
  369. if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
  370. log_cb = log.log;
  371. else
  372. log_cb = NULL;
  373.  
  374. if (environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb))
  375. perf_get_cpu_features_cb = perf_cb.get_cpu_features;
  376. else
  377. perf_get_cpu_features_cb = NULL;
  378.  
  379. // Set color mode
  380. unsigned color_mode = RETRO_PIXEL_FORMAT_XRGB8888;
  381. environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &color_mode);
  382. }
  383.  
  384. void retro_deinit(void)
  385. {
  386. first_run = true;
  387. }
  388.  
  389. static bool is_dupe = false;
  390. extern int GDROM_TICK;
  391.  
  392. static void update_variables(bool first_startup)
  393. {
  394. struct retro_variable var;
  395.  
  396. var.key = "reicast_widescreen_hack";
  397.  
  398. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  399. {
  400. if (!strcmp(var.value, "enabled"))
  401. settings.rend.WideScreen = 1;
  402. else
  403. settings.rend.WideScreen = 0;
  404. }
  405. else
  406. settings.rend.WideScreen = 0;
  407.  
  408. var.key = "reicast_internal_resolution";
  409.  
  410. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  411. {
  412. char *pch;
  413. char str[100];
  414. snprintf(str, sizeof(str), "%s", var.value);
  415.  
  416. pch = strtok(str, "x");
  417. if (pch)
  418. screen_width = strtoul(pch, NULL, 0);
  419. pch = strtok(NULL, "x");
  420. if (pch)
  421. screen_height = strtoul(pch, NULL, 0);
  422.  
  423. if (settings.rend.WideScreen)
  424. {
  425. if (!strcmp(var.value, "640x480"))
  426. {
  427. screen_width = 854;
  428. }
  429. else if (!strcmp(var.value, "1280x960"))
  430. {
  431. screen_width = 1536;
  432. }
  433. else if (!strcmp(var.value, "1920x1440"))
  434. screen_height = 1200;
  435. else if (!strcmp(var.value, "2560x1920"))
  436. screen_width = 3200;
  437. }
  438.  
  439. fprintf(stderr, "[reicast]: Got size: %u x %u.\n", screen_width, screen_height);
  440. }
  441.  
  442.  
  443. var.key = "reicast_cpu_mode";
  444.  
  445. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  446. {
  447. if (!strcmp(var.value, "dynamic_recompiler"))
  448. settings.dynarec.Type = 0;
  449. else if (!strcmp(var.value, "generic_recompiler"))
  450. settings.dynarec.Type = 1;
  451. }
  452.  
  453. var.key = "reicast_boot_to_bios";
  454.  
  455. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  456. {
  457. if (!strcmp(var.value, "enabled"))
  458. boot_to_bios = true;
  459. else if (!strcmp(var.value, "disabled"))
  460. boot_to_bios = false;
  461. }
  462. else
  463. boot_to_bios = false;
  464.  
  465. var.key = "reicast_gdrom_fast_loading";
  466.  
  467. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  468. {
  469. if (!strcmp(var.value, "enabled"))
  470. GDROM_TICK = 0001000;
  471. else if (!strcmp(var.value, "disabled"))
  472. GDROM_TICK = 1500000;
  473. }
  474. else
  475. GDROM_TICK = 1500000;
  476.  
  477. #ifdef HAVE_OIT
  478. var.key = "reicast_oit_alpha_sorting";
  479. #else
  480. var.key = "reicast_alpha_sorting";
  481. #endif
  482.  
  483. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  484. {
  485. if (!strcmp(var.value, "per-strip (fast, least accurate)"))
  486. settings.pvr.Emulation.AlphaSortMode = 1;
  487. else if (!strcmp(var.value, "per-triangle (normal)"))
  488. settings.pvr.Emulation.AlphaSortMode = 0;
  489. else if (!strcmp(var.value, "per-pixel (accurate)"))
  490. settings.pvr.Emulation.AlphaSortMode = 0; /* value not used for OIT */
  491. }
  492. else
  493. settings.pvr.Emulation.AlphaSortMode = 0;
  494.  
  495.  
  496. var.key = "reicast_mipmapping";
  497.  
  498. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  499. {
  500. if (!strcmp(var.value, "enabled"))
  501. settings.rend.UseMipmaps = 1;
  502. else if (!strcmp(var.value, "disabled"))
  503. settings.rend.UseMipmaps = 0;
  504. }
  505. else
  506. settings.rend.UseMipmaps = 1;
  507.  
  508. if (first_startup)
  509. {
  510. var.key = "reicast_system";
  511.  
  512. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  513. {
  514. if (!strcmp(var.value, "auto"))
  515. settings.System = DC_PLATFORM_DREAMCAST;
  516. else if (!strcmp(var.value, "dreamcast"))
  517. settings.System = DC_PLATFORM_DREAMCAST;
  518. else if (!strcmp(var.value, "naomi"))
  519. settings.System = DC_PLATFORM_NAOMI;
  520. }
  521. else
  522. settings.System = DC_PLATFORM_DREAMCAST;
  523.  
  524. #ifdef HAVE_OIT
  525. extern GLuint pixel_buffer_size;
  526. var.key = "reicast_oit_abuffer_size";
  527.  
  528. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  529. {
  530. if (!strcmp(var.value, "512MB"))
  531. pixel_buffer_size = 0x20000000;
  532. else if (!strcmp(var.value, "1GB"))
  533. pixel_buffer_size = 0x40000000;
  534. else if (!strcmp(var.value, "2GB"))
  535. pixel_buffer_size = 0x80000000;
  536. else
  537. pixel_buffer_size = 0x20000000;
  538. }
  539. else
  540. pixel_buffer_size = 0x20000000;
  541.  
  542. #endif
  543. }
  544.  
  545. var.key = "reicast_volume_modifier_enable";
  546.  
  547. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  548. {
  549. if (!strcmp(var.value, "disabled"))
  550. settings.pvr.Emulation.ModVol = false;
  551. else if (!strcmp(var.value, "enabled"))
  552. settings.pvr.Emulation.ModVol = true;
  553. }
  554. else
  555. settings.pvr.Emulation.ModVol = true;
  556.  
  557.  
  558. var.key = "reicast_audio_buffer_size";
  559.  
  560. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  561. {
  562. settings.aica.BufferSize = atoi(var.value);
  563. }
  564. else
  565. settings.aica.BufferSize = 1024;
  566.  
  567. var.key = "reicast_cable_type";
  568.  
  569. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  570. {
  571. if (!strcmp("VGA (RGB)", var.value))
  572. settings.dreamcast.cable = 0;
  573. else if (!strcmp("TV (RGB)", var.value))
  574. settings.dreamcast.cable = 2;
  575. else if (!strcmp("TV (VBS/Y+S/C)", var.value))
  576. settings.dreamcast.cable = 3;
  577. }
  578.  
  579. var.key = "reicast_broadcast";
  580.  
  581. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  582. {
  583. if (!strcmp("NTSC", var.value))
  584. settings.dreamcast.broadcast = 0;
  585. else if (!strcmp("PAL", var.value))
  586. settings.dreamcast.broadcast = 1;
  587. else if (!strcmp("PAL_M", var.value))
  588. settings.dreamcast.broadcast = 2;
  589. else if (!strcmp("PAL_N", var.value))
  590. settings.dreamcast.broadcast = 3;
  591. else if (!strcmp("Default", var.value))
  592. settings.dreamcast.broadcast = 4;
  593. }
  594. else
  595. settings.dreamcast.broadcast = 4;
  596.  
  597. var.key = "reicast_framerate";
  598.  
  599. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  600. {
  601. if (!strcmp("normal", var.value))
  602. settings.UpdateMode = 0;
  603. else if (!strcmp("fullspeed", var.value))
  604. settings.UpdateMode = 1;
  605. }
  606. else
  607. settings.UpdateMode = 0;
  608.  
  609. var.key = "reicast_region";
  610.  
  611. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  612. {
  613. if (!strcmp("Japan", var.value))
  614. settings.dreamcast.region = 0;
  615. else if (!strcmp("USA", var.value))
  616. settings.dreamcast.region = 1;
  617. else if (!strcmp("Europe", var.value))
  618. settings.dreamcast.region = 2;
  619. else if (!strcmp("Default", var.value))
  620. settings.dreamcast.region = 3;
  621. }
  622. else
  623. settings.dreamcast.region = 3;
  624.  
  625. #ifndef HAVE_OIT
  626. var.key = "reicast_precompile_shaders";
  627.  
  628. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  629. {
  630. if (!strcmp("disabled", var.value))
  631. settings.pvr.Emulation.precompile_shaders = false;
  632. else
  633. settings.pvr.Emulation.precompile_shaders = true;
  634. }
  635. #endif
  636.  
  637. #ifdef HAVE_TEXUPSCALE
  638. var.key = "reicast_texupscale";
  639.  
  640. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  641. {
  642. if (!strcmp("off", var.value))
  643. settings.rend.TextureUpscale = 1;
  644. else if (!strcmp("2x", var.value))
  645. settings.rend.TextureUpscale = 2;
  646. else if (!strcmp("4x", var.value))
  647. settings.rend.TextureUpscale = 4;
  648. else if (!strcmp("6x", var.value))
  649. settings.rend.TextureUpscale = 6;
  650. }
  651. else if (first_startup)
  652. settings.rend.TextureUpscale = 1;
  653.  
  654. var.key = "reicast_texupscale_max_filtered_texture_size";
  655.  
  656. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  657. {
  658. if (!strcmp("256", var.value))
  659. settings.rend.MaxFilteredTextureSize = 256;
  660. else if (!strcmp("512", var.value))
  661. settings.rend.MaxFilteredTextureSize = 512;
  662. else if (!strcmp("1024", var.value))
  663. settings.rend.MaxFilteredTextureSize = 1024;
  664. }
  665. else
  666. settings.rend.MaxFilteredTextureSize = 256;
  667. #endif
  668.  
  669. var.key = "reicast_enable_rtt";
  670.  
  671. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  672. {
  673. if (!strcmp("enabled", var.value))
  674. settings.rend.RenderToTexture = true;
  675. else
  676. settings.rend.RenderToTexture = false;
  677. }
  678. else
  679. settings.rend.RenderToTexture = true;
  680.  
  681. var.key = "reicast_enable_rttb";
  682.  
  683. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  684. {
  685. if (!strcmp("enabled", var.value))
  686. settings.rend.RenderToTextureBuffer = true;
  687. else
  688. settings.rend.RenderToTextureBuffer = false;
  689. }
  690. else
  691. settings.rend.RenderToTextureBuffer = false;
  692.  
  693. var.key = "reicast_render_to_texture_upscaling";
  694.  
  695. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  696. {
  697. char *pch;
  698. char str[100];
  699. sprintf(str, "%s", var.value);
  700.  
  701. pch = strtok(str, "x");
  702. if (pch)
  703. settings.rend.RenderToTextureUpscale = strtoul(pch, NULL, 0);
  704. }
  705. else if (first_startup)
  706. settings.rend.RenderToTextureUpscale = 1;
  707.  
  708. #if !defined(TARGET_NO_THREADS)
  709. if (first_startup)
  710. {
  711. var.key = "reicast_threaded_rendering";
  712.  
  713. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  714. {
  715. if (!strcmp("enabled", var.value))
  716. settings.rend.ThreadedRendering = true;
  717. else
  718. settings.rend.ThreadedRendering = false;
  719. }
  720. else
  721. settings.rend.ThreadedRendering = false;
  722. }
  723. #endif
  724.  
  725. var.key = "reicast_enable_purupuru";
  726. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  727. enable_purupuru = (strcmp("enabled", var.value) == 0);
  728.  
  729. var.key = "reicast_analog_stick_deadzone";
  730. var.value = NULL;
  731.  
  732. if ( environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
  733. input_set_deadzone_stick( atoi( var.value ) );
  734.  
  735. var.key = "reicast_trigger_deadzone";
  736. var.value = NULL;
  737.  
  738. if ( environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
  739. input_set_deadzone_trigger( atoi( var.value ) );
  740.  
  741. var.key = "reicast_enable_dsp";
  742.  
  743. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  744. {
  745. if (!strcmp("enabled", var.value))
  746. {
  747. settings.aica.DSPEnabled = true;
  748. settings.aica.NoBatch = 1;
  749. }
  750. else
  751. {
  752. settings.aica.DSPEnabled = false;
  753. settings.aica.NoBatch = 0;
  754. }
  755. }
  756. else if (first_run)
  757. {
  758. settings.aica.DSPEnabled = true;
  759. settings.aica.NoBatch = 1;
  760. }
  761.  
  762. var.key = "reicast_digital_triggers";
  763.  
  764. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  765. {
  766. if (!strcmp("enabled", var.value))
  767. digital_triggers = true;
  768. else
  769. digital_triggers = false;
  770. }
  771. else
  772. digital_triggers = false;
  773.  
  774. var.key = "reicast_allow_service_buttons";
  775.  
  776. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
  777. {
  778. if (!strcmp("enabled", var.value))
  779. allow_service_buttons = true;
  780. else
  781. allow_service_buttons = false;
  782. }
  783. else
  784. allow_service_buttons = false;
  785. }
  786. bool renderer_inited = false;
  787. void retro_run (void)
  788. {
  789. bool updated = false;
  790. if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
  791. update_variables(false);
  792.  
  793. #if !defined(TARGET_NO_THREADS)
  794. if (settings.rend.ThreadedRendering)
  795. {
  796. // On the first call, we start the emulator thread
  797. if (first_run)
  798. {
  799. emu_thread.Start();
  800. first_run = false;
  801. }
  802. // Then we wait until the emulator has initialized
  803. if (!emu_inited)
  804. return;
  805.  
  806. glsm_ctl(GLSM_CTL_STATE_BIND, NULL);
  807.  
  808. // We can now initialize the renderer
  809. if (!renderer_inited)
  810. {
  811. renderer->Init();
  812. renderer_inited = true;
  813. }
  814. /// And start rendering
  815. is_dupe = !rend_single_frame();
  816.  
  817. glsm_ctl(GLSM_CTL_STATE_UNBIND, NULL);
  818.  
  819. poll_cb();
  820. }
  821. else
  822. #endif
  823. {
  824. if (first_run)
  825. {
  826. dc_init(co_argc,co_argv);
  827. dc_run();
  828. first_run = false;
  829. return;
  830. }
  831. dc_run();
  832. }
  833. #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
  834. video_cb(is_dupe ? 0 : RETRO_HW_FRAME_BUFFER_VALID, screen_width, screen_height, 0);
  835. #endif
  836. #if !defined(TARGET_NO_THREADS)
  837. if (!settings.rend.ThreadedRendering)
  838. #endif
  839. is_dupe = true;
  840. }
  841.  
  842. void retro_reset (void)
  843. {
  844. #if !defined(TARGET_NO_THREADS)
  845. if (settings.rend.ThreadedRendering)
  846. {
  847. dc_stop();
  848. emu_inited = false;
  849. }
  850. else
  851. #endif
  852. dc_term();
  853. first_run = true;
  854. settings.dreamcast.cable = 3;
  855. update_variables(false);
  856. }
  857.  
  858. #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
  859. static void context_reset(void)
  860. {
  861. printf("context_reset.\n");
  862. glsm_ctl(GLSM_CTL_STATE_CONTEXT_RESET, NULL);
  863. }
  864.  
  865. static void context_destroy(void)
  866. {
  867. glsm_ctl(GLSM_CTL_STATE_CONTEXT_DESTROY, NULL);
  868. }
  869. #endif
  870.  
  871. static void extract_directory(char *buf, const char *path, size_t size)
  872. {
  873. strncpy(buf, path, size - 1);
  874. buf[size - 1] = '\0';
  875.  
  876. char *base = strrchr(buf, '/');
  877. if (!base)
  878. base = strrchr(buf, '\\');
  879.  
  880. if (base)
  881. *base = '\0';
  882. else
  883. buf[0] = '\0';
  884. }
  885.  
  886. extern void dc_prepare_system(void);
  887.  
  888. static void extract_basename(char *buf, const char *path, size_t size)
  889. {
  890. const char *base = strrchr(path, slash);
  891. if (!base)
  892. base = path;
  893.  
  894. if (*base == slash)
  895. base++;
  896.  
  897. strncpy(buf, base, size - 1);
  898. buf[size - 1] = '\0';
  899. }
  900.  
  901. // Loading/unloading games
  902. bool retro_load_game(const struct retro_game_info *game)
  903. {
  904. glsm_ctx_params_t params = {0};
  905. const char *dir = NULL;
  906. #ifdef _WIN32
  907. char slash = '\\';
  908. #else
  909. char slash = '/';
  910. #endif
  911.  
  912. extract_basename(g_base_name, game->path, sizeof(g_base_name));
  913. extract_directory(game_dir, game->path, sizeof(game_dir));
  914.  
  915. // Storing rom dir for later use
  916. char g_roms_dir[PATH_MAX];
  917. snprintf(g_roms_dir, sizeof(g_roms_dir), "%s%c", game_dir, slash);
  918.  
  919. if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble) && log_cb)
  920. log_cb(RETRO_LOG_INFO, "Rumble interface supported!\n");
  921.  
  922. if (!(environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir))
  923. dir = game_dir;
  924.  
  925. snprintf(game_dir, sizeof(game_dir), "%s%cdc%c", dir, slash, slash);
  926. snprintf(game_dir_no_slash, sizeof(game_dir_no_slash), "%s%cdc", dir, slash);
  927.  
  928. settings.dreamcast.cable = 3;
  929. update_variables(true);
  930.  
  931. {
  932. /* Check for extension .lst. If found, we will set the system type
  933. * automatically to Naomi. */
  934. char *ext = strrchr(g_base_name, '.');
  935. if (ext)
  936. {
  937. log_cb(RETRO_LOG_INFO, "File extension is: %s\n", ext);
  938. if (!strcmp(".lst", ext))
  939. settings.System = DC_PLATFORM_NAOMI;
  940. }
  941. }
  942.  
  943. if (settings.System == DC_PLATFORM_NAOMI)
  944. {
  945. struct retro_input_descriptor desc[] = {
  946. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  947. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  948. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  949. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  950. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Button 1" },
  951. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Button 2" },
  952. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Button 3" },
  953. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Button 4" },
  954. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Button 5" },
  955. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Button 6" },
  956. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  957. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Coin" },
  958. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Service 1" },
  959. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Test 1" },
  960. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Service 2" },
  961. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Test 2" },
  962. { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  963. { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  964.  
  965. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  966. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  967. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  968. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  969. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Button 1" },
  970. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Button 2" },
  971. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Button 3" },
  972. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Button 4" },
  973. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Button 5" },
  974. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Button 6" },
  975. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  976. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Coin" },
  977. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Service 1" },
  978. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Test 1" },
  979. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Service 2" },
  980. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Test 2" },
  981. { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  982. { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  983.  
  984. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  985. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  986. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  987. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  988. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Button 2" },
  989. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Button 2" },
  990. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Button 3" },
  991. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Button 4" },
  992. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Button 5" },
  993. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Button 6" },
  994. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  995. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Coin" },
  996. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Service 2" },
  997. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Test 2" },
  998. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Service 2" },
  999. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Test 2" },
  1000. { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1001. { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1002.  
  1003. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  1004. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  1005. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  1006. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  1007. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Button 3" },
  1008. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Button 2" },
  1009. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Button 3" },
  1010. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Button 4" },
  1011. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Button 5" },
  1012. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Button 6" },
  1013. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  1014. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Coin" },
  1015. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Service 3" },
  1016. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Test 3" },
  1017. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Service 2" },
  1018. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Test 2" },
  1019. { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1020. { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1021.  
  1022. { 0 },
  1023. };
  1024.  
  1025. environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
  1026. }
  1027. else
  1028. {
  1029. struct retro_input_descriptor desc[] = {
  1030. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  1031. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  1032. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  1033. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  1034. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" },
  1035. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "B" },
  1036. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
  1037. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "X" },
  1038. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L Trigger" },
  1039. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R Trigger" },
  1040. { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  1041. { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1042. { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1043.  
  1044. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  1045. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  1046. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  1047. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  1048. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" },
  1049. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "B" },
  1050. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
  1051. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "X" },
  1052. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L Trigger" },
  1053. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R Trigger" },
  1054. { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  1055. { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1056. { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1057.  
  1058. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  1059. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  1060. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  1061. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  1062. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" },
  1063. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "B" },
  1064. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
  1065. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "X" },
  1066. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L Trigger" },
  1067. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R Trigger" },
  1068. { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  1069. { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1070. { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1071.  
  1072. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
  1073. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
  1074. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
  1075. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
  1076. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "A" },
  1077. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "B" },
  1078. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Y" },
  1079. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "X" },
  1080. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L Trigger" },
  1081. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R Trigger" },
  1082. { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
  1083. { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Analog X" },
  1084. { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Analog Y" },
  1085.  
  1086. { 0 },
  1087. };
  1088.  
  1089. environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
  1090. }
  1091.  
  1092. if (game->path[0] == '\0')
  1093. boot_to_bios = true;
  1094.  
  1095. if (!boot_to_bios)
  1096. game_data = strdup(game->path);
  1097.  
  1098. {
  1099. char data_dir[1024];
  1100.  
  1101. snprintf(data_dir, sizeof(data_dir), "%s%s", game_dir, "data");
  1102.  
  1103. printf("Creating dir: %s\n", data_dir);
  1104. struct stat buf;
  1105. if (stat(data_dir, &buf) < 0)
  1106. {
  1107. mkdir_norecurse(data_dir);
  1108. }
  1109. }
  1110.  
  1111. #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
  1112. params.context_reset = context_reset;
  1113. params.context_destroy = context_destroy;
  1114. params.environ_cb = environ_cb;
  1115. #ifdef TARGET_NO_STENCIL
  1116. params.stencil = false;
  1117. #else
  1118. params.stencil = true;
  1119. #endif
  1120. params.imm_vbo_draw = NULL;
  1121. params.imm_vbo_disable = NULL;
  1122.  
  1123. if (!glsm_ctl(GLSM_CTL_STATE_CONTEXT_INIT, &params))
  1124. return false;
  1125.  
  1126. #endif
  1127.  
  1128. if (settings.System == DC_PLATFORM_NAOMI)
  1129. {
  1130. if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir) {
  1131. char g_save_dir[PATH_MAX];
  1132. strncpy(g_save_dir, dir, sizeof(g_save_dir));
  1133. if(strcmp(g_save_dir,g_roms_dir) != 0)
  1134. snprintf(save_dir, sizeof(save_dir), "%s%creicast%c", g_save_dir, slash, slash);
  1135. else
  1136. strncpy(save_dir, g_roms_dir, sizeof(save_dir));
  1137. struct stat buf;
  1138. if (stat(save_dir, &buf) < 0)
  1139. {
  1140. log_cb(RETRO_LOG_INFO, "Creating dir: %s\n", save_dir);
  1141. mkdir_norecurse(save_dir);
  1142. }
  1143. } else {
  1144. strncpy(save_dir, g_roms_dir, sizeof(save_dir));
  1145. }
  1146. log_cb(RETRO_LOG_INFO, "Setting save dir to %s\n", save_dir);
  1147. snprintf(eeprom_file, sizeof(eeprom_file), "%s%s.eeprom", save_dir, g_base_name);
  1148. snprintf(nvmem_file, sizeof(nvmem_file), "%s%s.nvmem", save_dir, g_base_name);
  1149. }
  1150.  
  1151. dc_prepare_system();
  1152.  
  1153. return true;
  1154. }
  1155.  
  1156. bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
  1157. {
  1158. return false; //TODO (?)
  1159. }
  1160.  
  1161. void retro_unload_game(void)
  1162. {
  1163. if (game_data)
  1164. free(game_data);
  1165. game_data = NULL;
  1166.  
  1167. dc_stop();
  1168. #if !defined(TARGET_NO_THREADS)
  1169. if (settings.rend.ThreadedRendering)
  1170. {
  1171. rend_cancel_emu_wait();
  1172. printf("Waiting for emu thread...\n");
  1173. emu_thread.WaitToEnd();
  1174. printf("...Done\n");
  1175. }
  1176. else
  1177. #endif
  1178. dc_term();
  1179. }
  1180.  
  1181.  
  1182. // Memory/Serialization
  1183. void *retro_get_memory_data(unsigned type)
  1184. {
  1185. if ( type == RETRO_MEMORY_SYSTEM_RAM )
  1186. return mem_b.data;
  1187. return 0; //TODO
  1188. }
  1189.  
  1190. size_t retro_get_memory_size(unsigned type)
  1191. {
  1192. if ( type == RETRO_MEMORY_SYSTEM_RAM )
  1193. return mem_b.size;
  1194. return 0; //TODO
  1195. }
  1196.  
  1197. size_t retro_serialize_size (void)
  1198. {
  1199. unsigned int total_size = 0 ;
  1200. void *data = NULL ;
  1201.  
  1202. printf("SERIAL - sersize1\n") ;
  1203. #if !defined(TARGET_NO_THREADS)
  1204. if (settings.rend.ThreadedRendering && emu_inited)
  1205. {
  1206. printf("SERIAL - sersize2\n") ;
  1207. mtx_serialization.Lock() ;
  1208. printf("SERIAL - sersize3\n") ;
  1209. dc_stop() ;
  1210. printf("SERIAL - sersize4\n") ;
  1211. rend_cancel_emu_wait();
  1212. printf("SERIAL - sersize5\n") ;
  1213. mtx_mainloop.Lock() ;
  1214. printf("SERIAL - sersize6\n") ;
  1215. }
  1216. #endif
  1217. printf("SERIAL - sersize7\n") ;
  1218. dc_serialize(&data, &total_size) ;
  1219. printf("SERIAL - sersize8\n") ;
  1220. performed_serialization = true ;
  1221.  
  1222. #if !defined(TARGET_NO_THREADS)
  1223. if (settings.rend.ThreadedRendering && emu_inited)
  1224. {
  1225. printf("SERIAL - sersize9\n") ;
  1226. mtx_mainloop.Unlock() ;
  1227. printf("SERIAL - sersize10\n") ;
  1228. mtx_serialization.Unlock() ;
  1229. printf("SERIAL - sersize11\n") ;
  1230. }
  1231. #endif
  1232. return total_size;
  1233. }
  1234.  
  1235. bool retro_serialize(void *data, size_t size)
  1236. {
  1237. unsigned int total_size = 0 ;
  1238. void *data_ptr = data ;
  1239. bool result = false ;
  1240.  
  1241. #if !defined(TARGET_NO_THREADS)
  1242. if ( settings.rend.ThreadedRendering && !emu_inited )
  1243. return false ;
  1244.  
  1245. if (settings.rend.ThreadedRendering && emu_inited)
  1246. {
  1247. printf("SERIAL - save1\n") ;
  1248. mtx_serialization.Lock() ;
  1249. printf("SERIAL - save2\n") ;
  1250. dc_stop() ;
  1251. printf("SERIAL - save3\n") ;
  1252. rend_cancel_emu_wait();
  1253. printf("SERIAL - save4\n") ;
  1254. mtx_mainloop.Lock() ;
  1255. printf("SERIAL - save5\n") ;
  1256. }
  1257. #endif
  1258.  
  1259. printf("SERIAL - save6\n") ;
  1260. result = dc_serialize(&data_ptr, &total_size) ;
  1261. printf("SERIAL - save7\n") ;
  1262. performed_serialization = true ;
  1263.  
  1264. #if !defined(TARGET_NO_THREADS)
  1265. if (settings.rend.ThreadedRendering && emu_inited)
  1266. {
  1267. printf("SERIAL - save8\n") ;
  1268. mtx_mainloop.Unlock() ;
  1269. printf("SERIAL - save9\n") ;
  1270. mtx_serialization.Unlock() ;
  1271. printf("SERIAL - save10\n") ;
  1272. }
  1273. #endif
  1274.  
  1275. return result ;
  1276. }
  1277.  
  1278. bool retro_unserialize(const void * data, size_t size)
  1279. {
  1280. unsigned int total_size = 0 ;
  1281. void *data_ptr = (void*)data ;
  1282. bool result = false ;
  1283.  
  1284. #if !defined(TARGET_NO_THREADS)
  1285. if ( settings.rend.ThreadedRendering && !emu_inited )
  1286. return false ;
  1287. #endif
  1288.  
  1289. bm_Reset() ;
  1290.  
  1291. #if !defined(TARGET_NO_THREADS)
  1292. if (settings.rend.ThreadedRendering && emu_inited)
  1293. {
  1294. mtx_serialization.Lock() ;
  1295. dc_stop() ;
  1296. rend_cancel_emu_wait();
  1297. mtx_mainloop.Lock() ;
  1298. }
  1299. #endif
  1300.  
  1301. result = dc_unserialize(&data_ptr, &total_size) ;
  1302. performed_serialization = true ;
  1303.  
  1304. #if !defined(TARGET_NO_THREADS)
  1305. if (settings.rend.ThreadedRendering && emu_inited)
  1306. {
  1307. mtx_mainloop.Unlock() ;
  1308. mtx_serialization.Unlock() ;
  1309. }
  1310. #endif
  1311.  
  1312. return result ;
  1313. }
  1314.  
  1315. // Cheats
  1316. void retro_cheat_reset(void)
  1317. {
  1318. // Nothing to do here
  1319. }
  1320. void retro_cheat_set(unsigned unused, bool unused1, const char* unused2)
  1321. {
  1322. // Nothing to do here
  1323. }
  1324.  
  1325.  
  1326. // Get info
  1327. const char* retro_get_system_directory(void)
  1328. {
  1329. const char* dir;
  1330. environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir);
  1331. return dir ? dir : ".";
  1332. }
  1333.  
  1334. void retro_get_system_info(struct retro_system_info *info)
  1335. {
  1336. #ifdef HAVE_OIT
  1337. info->library_name = "Reicast OIT";
  1338. #else
  1339. info->library_name = "Reicast";
  1340. #endif
  1341. #ifndef GIT_VERSION
  1342. #define GIT_VERSION ""
  1343. #endif
  1344. info->library_version = "0.1" GIT_VERSION;
  1345. info->valid_extensions = "chd|cdi|iso|elf|bin|cue|gdi|lst";
  1346. info->need_fullpath = true;
  1347. info->block_extract = false;
  1348. }
  1349.  
  1350. void retro_get_system_av_info(struct retro_system_av_info *info)
  1351. {
  1352. /* 00=VGA 01=NTSC 10=PAL, 11=illegal/undocumented */
  1353. const int spg_clks[4] = { 26944080, 13458568, 13462800, 26944080 };
  1354. u32 pixel_clock= spg_clks[(SPG_CONTROL.full >> 6) & 3];
  1355.  
  1356. info->geometry.base_width = screen_width;
  1357. info->geometry.base_height = screen_height;
  1358. info->geometry.max_width = screen_width;
  1359. info->geometry.max_height = screen_height;
  1360. info->geometry.aspect_ratio = settings.rend.WideScreen ? (16.0 / 9.0) : (4.0 / 3.0);
  1361.  
  1362. switch (pixel_clock)
  1363. {
  1364. case 26944080:
  1365. info->timing.fps = 60.00; /* (VGA 480 @ 60.00) */
  1366. break;
  1367. case 26917135:
  1368. info->timing.fps = 59.94; /* (NTSC 480 @ 59.94) */
  1369. break;
  1370. case 13462800:
  1371. info->timing.fps = 50.00; /* (PAL 240 @ 50.00) */
  1372. break;
  1373. case 13458568:
  1374. info->timing.fps = 59.94; /* (NTSC 240 @ 59.94) */
  1375. break;
  1376. case 25925600:
  1377. info->timing.fps = 50.00; /* (PAL 480 @ 50.00) */
  1378. break;
  1379. }
  1380.  
  1381. info->timing.sample_rate = 44100.0;
  1382. }
  1383.  
  1384. unsigned retro_get_region (void)
  1385. {
  1386. return RETRO_REGION_NTSC; //TODO
  1387. }
  1388.  
  1389.  
  1390. // Controller
  1391. void retro_set_controller_port_device(unsigned in_port, unsigned device)
  1392. {
  1393. //TODO
  1394. if (rumble.set_rumble_state)
  1395. {
  1396. rumble.set_rumble_state(in_port, RETRO_RUMBLE_STRONG, 0);
  1397. rumble.set_rumble_state(in_port, RETRO_RUMBLE_WEAK, 0);
  1398. }
  1399. }
  1400.  
  1401.  
  1402. // API version (to detect version mismatch)
  1403. unsigned retro_api_version(void)
  1404. {
  1405. return RETRO_API_VERSION;
  1406. }
  1407.  
  1408. //Reicast stuff
  1409. void os_DoEvents(void)
  1410. {
  1411. #if !defined(TARGET_NO_THREADS)
  1412. if (!settings.rend.ThreadedRendering)
  1413. #endif
  1414. {
  1415. is_dupe = false;
  1416. poll_cb();
  1417.  
  1418. if (settings.UpdateMode || settings.UpdateModeForced)
  1419. {
  1420. rend_end_render();
  1421. dc_stop();
  1422. }
  1423. }
  1424. }
  1425.  
  1426. void os_CreateWindow()
  1427. {
  1428. // Nothing to do here
  1429. }
  1430.  
  1431. static void get_analog_stick( retro_input_state_t input_state_cb,
  1432. int player_index,
  1433. int stick,
  1434. s8* p_analog_x,
  1435. s8* p_analog_y )
  1436. {
  1437. int analog_x, analog_y;
  1438. analog_x = input_state_cb( player_index, RETRO_DEVICE_ANALOG, stick, RETRO_DEVICE_ID_ANALOG_X );
  1439. analog_y = input_state_cb( player_index, RETRO_DEVICE_ANALOG, stick, RETRO_DEVICE_ID_ANALOG_Y );
  1440.  
  1441. // Analog stick deadzone (borrowed code from parallel-n64 core)
  1442. if ( astick_deadzone > 0 )
  1443. {
  1444. static const int ASTICK_MAX = 0x8000;
  1445.  
  1446. // Convert cartesian coordinate analog stick to polar coordinates
  1447. double radius = sqrt(analog_x * analog_x + analog_y * analog_y);
  1448. double angle = atan2(analog_y, analog_x);
  1449.  
  1450. if (radius > astick_deadzone)
  1451. {
  1452. // Re-scale analog stick range to negate deadzone (makes slow movements possible)
  1453. radius = (radius - astick_deadzone)*((float)ASTICK_MAX/(ASTICK_MAX - astick_deadzone));
  1454.  
  1455. // Convert back to cartesian coordinates
  1456. analog_x = (int)round(radius * cos(angle));
  1457. analog_y = (int)round(radius * sin(angle));
  1458.  
  1459. // Clamp to correct range
  1460. if (analog_x > +32767) analog_x = +32767;
  1461. if (analog_x < -32767) analog_x = -32767;
  1462. if (analog_y > +32767) analog_y = +32767;
  1463. if (analog_y < -32767) analog_y = -32767;
  1464. }
  1465. else
  1466. {
  1467. analog_x = 0;
  1468. analog_y = 0;
  1469. }
  1470. }
  1471.  
  1472. // output
  1473. *p_analog_x = (s8)(analog_x >> 8);
  1474. *p_analog_y = (s8)(analog_y >> 8);
  1475. }
  1476.  
  1477. static uint16_t apply_trigger_deadzone( uint16_t input )
  1478. {
  1479. if ( trigger_deadzone > 0 )
  1480. {
  1481. static const int TRIGGER_MAX = 0x8000;
  1482. const float scale = ((float)TRIGGER_MAX/(float)(TRIGGER_MAX - trigger_deadzone));
  1483.  
  1484. if ( input > trigger_deadzone )
  1485. {
  1486. // Re-scale analog range
  1487. float scaled = (input - trigger_deadzone)*scale;
  1488.  
  1489. input = (int)round(scaled);
  1490. if (input > +32767) {
  1491. input = +32767;
  1492. }
  1493. }
  1494. else
  1495. {
  1496. input = 0;
  1497. }
  1498. }
  1499.  
  1500. return input;
  1501. }
  1502.  
  1503. static uint16_t get_analog_trigger( retro_input_state_t input_state_cb,
  1504. int player_index,
  1505. int id )
  1506. {
  1507. uint16_t trigger;
  1508.  
  1509. // NOTE: Analog triggers were added Nov 2017. Not all front-ends support this
  1510. // feature (or pre-date it) so we need to handle this in a graceful way.
  1511.  
  1512. // First, try and get an analog value using the new libretro API constant
  1513. trigger = input_state_cb( player_index,
  1514. RETRO_DEVICE_ANALOG,
  1515. RETRO_DEVICE_INDEX_ANALOG_BUTTON,
  1516. id );
  1517.  
  1518. if ( trigger == 0 )
  1519. {
  1520. // If we got exactly zero, we're either not pressing the button, or the front-end
  1521. // is not reporting analog values. We need to do a second check using the classic
  1522. // digital API method, to at least get some response - better than nothing.
  1523.  
  1524. // NOTE: If we're really just not holding the trigger, we're still going to get zero.
  1525.  
  1526. trigger = input_state_cb( player_index,
  1527. RETRO_DEVICE_JOYPAD,
  1528. 0,
  1529. id ) ? 0x7FFF : 0;
  1530. }
  1531. else
  1532. {
  1533. // We got something, which means the front-end can handle analog buttons.
  1534. // So we apply a deadzone to the input and use it.
  1535.  
  1536. trigger = apply_trigger_deadzone( trigger );
  1537. }
  1538.  
  1539. return trigger;
  1540. }
  1541.  
  1542. static void UpdateInputStateNaomi(u32 port)
  1543. {
  1544. int id;
  1545. int max_id;
  1546.  
  1547. static const uint16_t joymap[] =
  1548. {
  1549. /* JOYPAD_B */ NAOMI_BTN3_KEY, /* BTN4 */
  1550. /* JOYPAD_Y */ NAOMI_BTN0_KEY, /* BTN1 */
  1551. /* JOYPAD_SELECT */ NAOMI_COIN_KEY,
  1552. /* JOYPAD_START */ NAOMI_START_KEY,
  1553. /* JOYPAD_UP */ NAOMI_UP_KEY,
  1554. /* JOYPAD_DOWN */ NAOMI_DOWN_KEY,
  1555. /* JOYPAD_LEFT */ NAOMI_LEFT_KEY,
  1556. /* JOYPAD_RIGHT */ NAOMI_RIGHT_KEY,
  1557. /* JOYPAD_A */ NAOMI_BTN4_KEY, /* BTN5 */
  1558. /* JOYPAD_X */ NAOMI_BTN1_KEY, /* BTN2 */
  1559. /* JOYPAD_L */ NAOMI_BTN2_KEY, /* BTN3 */
  1560. /* JOYPAD_R */ NAOMI_BTN5_KEY, /* BTN6 */
  1561. /* JOYPAD_L2 */ NAOMI_SERVICE_KEY_1,
  1562. /* JOYPAD_R2 */ NAOMI_TEST_KEY_1,
  1563. /* JOYPAD_L3 */ NAOMI_SERVICE_KEY_2,
  1564. /* JOYPAD_R3 */ NAOMI_TEST_KEY_2,
  1565. };
  1566.  
  1567. //
  1568. // -- buttons
  1569.  
  1570. max_id = (allow_service_buttons ? RETRO_DEVICE_ID_JOYPAD_R3 : RETRO_DEVICE_ID_JOYPAD_R);
  1571.  
  1572. for (id = RETRO_DEVICE_ID_JOYPAD_B; id <= max_id; ++id)
  1573. {
  1574. uint16_t dc_key = joymap[id];
  1575. bool is_down = input_cb(port, RETRO_DEVICE_JOYPAD, 0, id);
  1576.  
  1577. if ( is_down )
  1578. kcode[port] &= ~dc_key;
  1579. else
  1580. kcode[port] |= dc_key;
  1581. }
  1582.  
  1583. //
  1584. // -- analog stick
  1585.  
  1586. get_analog_stick( input_cb, port, RETRO_DEVICE_INDEX_ANALOG_LEFT, &(joyx[port]), &(joyy[port]) );
  1587. }
  1588.  
  1589. void UpdateInputState(u32 port)
  1590. {
  1591. if (settings.System == DC_PLATFORM_NAOMI)
  1592. {
  1593. UpdateInputStateNaomi(0);
  1594. UpdateInputStateNaomi(1);
  1595. UpdateInputStateNaomi(2);
  1596. UpdateInputStateNaomi(3);
  1597. return;
  1598. }
  1599.  
  1600. int id;
  1601. static const uint16_t joymap[] =
  1602. {
  1603. /* JOYPAD_B */ DC_BTN_A,
  1604. /* JOYPAD_Y */ DC_BTN_X,
  1605. /* JOYPAD_SELECT */ 0,
  1606. /* JOYPAD_START */ DC_BTN_START,
  1607. /* JOYPAD_UP */ DC_DPAD_UP,
  1608. /* JOYPAD_DOWN */ DC_DPAD_DOWN,
  1609. /* JOYPAD_LEFT */ DC_DPAD_LEFT,
  1610. /* JOYPAD_RIGHT */ DC_DPAD_RIGHT,
  1611. /* JOYPAD_A */ DC_BTN_B,
  1612. /* JOYPAD_X */ DC_BTN_Y,
  1613. };
  1614.  
  1615. //
  1616. // -- buttons
  1617.  
  1618. for (id = RETRO_DEVICE_ID_JOYPAD_B; id <= RETRO_DEVICE_ID_JOYPAD_X; ++id)
  1619. {
  1620. uint16_t dc_key = joymap[id];
  1621. bool is_down = input_cb(port, RETRO_DEVICE_JOYPAD, 0, id);
  1622.  
  1623. if ( is_down )
  1624. kcode[port] &= ~dc_key;
  1625. else
  1626. kcode[port] |= dc_key;
  1627. }
  1628.  
  1629. //
  1630. // -- analog stick
  1631.  
  1632. get_analog_stick( input_cb, port, RETRO_DEVICE_INDEX_ANALOG_LEFT, &(joyx[port]), &(joyy[port]) );
  1633.  
  1634.  
  1635. //
  1636. // -- triggers
  1637.  
  1638. if ( digital_triggers )
  1639. {
  1640. // -- digital left trigger
  1641. if ( input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L) )
  1642. lt[port]=0xFF;
  1643. else if ( input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2) )
  1644. lt[port]=0x7F;
  1645. else
  1646. lt[port]=0;
  1647. // -- digital right trigger
  1648. if ( input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R) )
  1649. rt[port]=0xFF;
  1650. else if ( input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2) )
  1651. rt[port]=0x7F;
  1652. else
  1653. rt[port]=0;
  1654. }
  1655. else
  1656. {
  1657. // -- analog triggers
  1658. lt[port] = get_analog_trigger( input_cb, port, RETRO_DEVICE_ID_JOYPAD_L2 ) / 128;
  1659. rt[port] = get_analog_trigger( input_cb, port, RETRO_DEVICE_ID_JOYPAD_R2 ) / 128;
  1660. }
  1661. }
  1662.  
  1663. void UpdateVibration(u32 port, u32 value)
  1664. {
  1665. if (!rumble.set_rumble_state)
  1666. return;
  1667.  
  1668. u8 POW_POS = (value >> 8) & 0x3;
  1669. u8 POW_NEG = (value >> 12) & 0x3;
  1670. u8 FREQ = (value >> 16) & 0xFF;
  1671.  
  1672. double pow = (POW_POS + POW_NEG) / 7.0;
  1673. double pow_l = pow * (0x3B - FREQ) / 17.0;
  1674. double pow_r = pow * (FREQ - 0x07) / 15.0;
  1675.  
  1676. if (pow_l > 1.0) pow_l = 1.0;
  1677. if (pow_r > 1.0) pow_r = 1.0;
  1678.  
  1679. rumble.set_rumble_state(port, RETRO_RUMBLE_STRONG, (u16)(65535 * pow_l));
  1680. rumble.set_rumble_state(port, RETRO_RUMBLE_WEAK, (u16)(65535 * pow_r));
  1681. }
  1682.  
  1683. void* libPvr_GetRenderTarget()
  1684. {
  1685. return NULL;
  1686. }
  1687.  
  1688. void* libPvr_GetRenderSurface()
  1689. {
  1690. return NULL;
  1691. }
  1692.  
  1693. int msgboxf(const char* text, unsigned int type, ...)
  1694. {
  1695. if (log_cb)
  1696. {
  1697. va_list args;
  1698.  
  1699. char temp[2048];
  1700.  
  1701. va_start(args, type);
  1702. vsprintf(temp, text, args);
  1703. va_end(args);
  1704.  
  1705. log_cb(RETRO_LOG_INFO, temp);
  1706. }
  1707. return 0;
  1708. }
  1709.  
  1710. int get_mic_data(u8* buffer) { return 0; }
  1711. int push_vmu_screen(u8* buffer) { return 0; }
  1712.  
  1713. void os_DebugBreak(void)
  1714. {
  1715. printf("DEBUGBREAK!\n");
  1716. //exit(-1);
  1717. __builtin_trap();
  1718. }
Advertisement
Add Comment
Please, Sign In to add comment