@@ -26,7 +26,6 @@ virtual keyboard
26
26
core options v2 https://github.com/libretro/libretro-common/tree/master/samples/core_options
27
27
check and include libretro common
28
28
detailed type detection from content name
29
- m3u (or, rather, name-based autodetect) multi-disk, multi-tape interface support (cpc 3 guerra)
30
29
locale support ep, cpc
31
30
rom config for clkoff+hfont
32
31
@@ -42,6 +41,7 @@ EP Mouse support
42
41
achievement support
43
42
test mp3 support with sndfile 1.1 - cmake won't find lame / mpeg123 when compiling libsndfile
44
43
led driver for tape / disk loading - see comments inside
44
+ name-based autodetect for multi-disk, multi-tape interface support (cpc 3 guerra)
45
45
46
46
*/
47
47
@@ -104,15 +104,25 @@ retro_usec_t prev_frame_time = 0;
104
104
float waitPeriod = 0.001 ;
105
105
bool useSwFb = false ;
106
106
bool useHalfFrame = false ;
107
- bool enableDiskControl = false ;
108
- bool needsDiskControl = false ;
109
107
int borderSize = 0 ;
110
108
bool soundHq = true ;
111
- unsigned maxUsers;
112
- bool maxUsersSupported = true ;
113
109
bool canSkipFrames = false ;
114
110
bool enhancedRom = false ;
115
111
112
+ unsigned maxUsers;
113
+ bool maxUsersSupported = true ;
114
+
115
+ unsigned diskIndex = 0 ;
116
+ unsigned diskCount = 1 ;
117
+ #define MAX_DISK_COUNT 6
118
+ std::string diskPaths[MAX_DISK_COUNT];
119
+ std::string diskNames[MAX_DISK_COUNT];
120
+ bool diskEjected = false ;
121
+
122
+ bool tapeContent = false ;
123
+ bool diskContent = false ;
124
+ bool fileContent = false ;
125
+
116
126
Ep128Emu::VMThread *vmThread = (Ep128Emu::VMThread *) 0 ;
117
127
Ep128Emu::EmulatorConfiguration *config = (Ep128Emu::EmulatorConfiguration *) 0 ;
118
128
Ep128Emu::LibretroCore *core = (Ep128Emu::LibretroCore *) 0 ;
@@ -293,6 +303,117 @@ static void check_variables(void)
293
303
if (vmThread) vmThread->resetKeyboard ();
294
304
}
295
305
306
+ /* If ejected is true, "ejects" the virtual disk tray.
307
+ */
308
+ static bool set_eject_state_cb (bool ejected) {
309
+ log_cb (RETRO_LOG_DEBUG, " Disk control: eject (%d)\n " ,ejected?1 :0 );
310
+ diskEjected = ejected;
311
+ return true ;
312
+ }
313
+
314
+ /* Gets current eject state. The initial state is 'not ejected'. */
315
+ static bool get_eject_state_cb (void ) {
316
+ // log_cb(RETRO_LOG_DEBUG, "Disk control: get eject status (%d)\n",diskEjected?1:0);
317
+ return diskEjected;
318
+ }
319
+
320
+ /* Gets current disk index. First disk is index 0.
321
+ * If return value is >= get_num_images(), no disk is currently inserted.
322
+ */
323
+ static unsigned get_image_index_cb (void ) {
324
+ // log_cb(RETRO_LOG_DEBUG, "Disk control: get image index (%d)\n",diskIndex);
325
+ if (diskEjected) return diskCount + 1 ;
326
+ return diskIndex;
327
+ }
328
+
329
+ /* Sets image index. Can only be called when disk is ejected.
330
+ */
331
+ static bool set_image_index_cb (unsigned index) {
332
+ log_cb (RETRO_LOG_DEBUG, " Disk control: change image to (%d)\n " ,index);
333
+ if (index>=diskCount) {
334
+ diskIndex = diskCount + 1 ;
335
+ } else {
336
+ diskIndex = index;
337
+ if (core) {
338
+ config = core->config ;
339
+ if (diskContent) {
340
+ config->floppy .a .imageFile = diskPaths[index];
341
+ config->floppyAChanged = true ;
342
+ log_cb (RETRO_LOG_DEBUG, " Disk control: new disk is %s\n " ,diskPaths[index].c_str ());
343
+ } else if (tapeContent) {
344
+ config->tape .imageFile = diskPaths[index];
345
+ config->tapeFileChanged = true ;
346
+ log_cb (RETRO_LOG_DEBUG, " Disk control: new tape is %s\n " ,diskPaths[index].c_str ());
347
+ }
348
+ config->applySettings ();
349
+ }
350
+ }
351
+ return true ;
352
+ }
353
+
354
+ /* Gets total number of images which are available to use. */
355
+ static unsigned get_num_images_cb (void ) {return diskCount;}
356
+
357
+ /* Replaces the disk image associated with index.
358
+ * Arguments to pass in info have same requirements as retro_load_game().
359
+ */
360
+ static bool replace_image_index_cb (unsigned index,
361
+ const struct retro_game_info *info) {
362
+
363
+ log_cb (RETRO_LOG_DEBUG, " Disk control: replace image index (%d) to %s\n " ,index,info->path );
364
+ if (index >= diskCount) return false ;
365
+ diskPaths[index] = info->path ;
366
+ std::string contentPath;
367
+ Ep128Emu::splitPath (diskPaths[index],contentPath,diskNames[index]);
368
+ return true ;
369
+ }
370
+
371
+ /* Adds a new valid index (get_num_images()) to the internal disk list.
372
+ * This will increment subsequent return values from get_num_images() by 1.
373
+ * This image index cannot be used until a disk image has been set
374
+ * with replace_image_index. */
375
+ static bool add_image_index_cb (void ) {
376
+ log_cb (RETRO_LOG_DEBUG, " Disk control: add image index (current %d)\n " ,diskCount);
377
+ if (diskCount >= MAX_DISK_COUNT) return false ;
378
+ diskCount++;
379
+ return true ;
380
+ }
381
+
382
+ /* Sets initial image to insert in drive when calling
383
+ * core_load_game().
384
+ * Returns 'false' if index or 'path' are invalid, or core
385
+ * does not support this functionality
386
+ */
387
+ static bool set_initial_image_cb (unsigned index, const char *path) {return false ;}
388
+
389
+ /* Fetches the path of the specified disk image file.
390
+ * Returns 'false' if index is invalid (index >= get_num_images())
391
+ * or path is otherwise unavailable.
392
+ */
393
+ static bool get_image_path_cb (unsigned index, char *path, size_t len) {
394
+ if (index >= diskCount) return false ;
395
+ if (diskPaths[index].length () > 0 )
396
+ path=(char *)diskPaths[index].c_str ();
397
+ len=diskPaths[index].length ();
398
+ log_cb (RETRO_LOG_DEBUG, " Disk control: get image path (%d) %s\n " ,index,path);
399
+ return true ;
400
+ }
401
+
402
+ /* Fetches a core-provided 'label' for the specified disk
403
+ * image file. In the simplest case this may be a file name
404
+ * Returns 'false' if index is invalid (index >= get_num_images())
405
+ * or label is otherwise unavailable.
406
+ */
407
+ static bool get_image_label_cb (unsigned index, char *label, size_t len) {
408
+ if (index >= diskCount) return false ;
409
+ if (diskNames[index].length () > 0 )
410
+ label=(char *)diskNames[index].c_str ();
411
+ len=diskNames[index].length ();
412
+ // log_cb(RETRO_LOG_DEBUG, "Disk control: get image label (%d) %s\n",index,label);
413
+ return true ;
414
+ }
415
+
416
+
296
417
void retro_init (void )
297
418
{
298
419
struct retro_log_callback log;
@@ -303,12 +424,42 @@ void retro_init(void)
303
424
else
304
425
log_cb = fallback_log;
305
426
306
- // actually it is the advanced disk control...
427
+ struct retro_disk_control_callback dccb =
428
+ {
429
+ set_eject_state_cb,
430
+ get_eject_state_cb,
431
+
432
+ get_image_index_cb,
433
+ set_image_index_cb,
434
+ get_num_images_cb,
435
+
436
+ replace_image_index_cb,
437
+ add_image_index_cb
438
+ };
439
+
440
+ struct retro_disk_control_ext_callback dccb_ext =
441
+ {
442
+ set_eject_state_cb,
443
+ get_eject_state_cb,
444
+
445
+ get_image_index_cb,
446
+ set_image_index_cb,
447
+ get_num_images_cb,
448
+
449
+ replace_image_index_cb,
450
+ add_image_index_cb,
451
+ set_initial_image_cb,
452
+
453
+ get_image_path_cb,
454
+ get_image_label_cb
455
+ };
456
+
307
457
unsigned dci;
308
- if (environ_cb (RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci))
309
- enableDiskControl = true ;
310
- else
311
- enableDiskControl = false ;
458
+ if (environ_cb (RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci)) {
459
+ environ_cb (RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &dccb_ext);
460
+ } else {
461
+ environ_cb (RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &dccb);
462
+ }
312
463
313
464
/* struct retro_led_interface led_interface;
314
465
if(environ_cb(RETRO_ENVIRONMENT_GET_LED_INTERFACE, &led_interface)) {
@@ -366,7 +517,7 @@ void retro_init(void)
366
517
sizeof (retro_system_save_directory) - 1
367
518
);
368
519
369
- log_cb (RETRO_LOG_INFO , " Retro ROM DIRECTORY %s\n " , retro_system_bios_directory);
520
+ log_cb (RETRO_LOG_DEBUG , " Retro ROM DIRECTORY %s\n " , retro_system_bios_directory);
370
521
log_cb (RETRO_LOG_DEBUG, " Retro SAVE_DIRECTORY %s\n " , retro_system_save_directory);
371
522
log_cb (RETRO_LOG_DEBUG, " Retro CONTENT_DIRECTORY %s\n " , retro_content_directory);
372
523
@@ -421,7 +572,7 @@ void retro_get_system_info(struct retro_system_info *info)
421
572
{
422
573
memset (info, 0 , sizeof (*info));
423
574
info->library_name = " ep128emu" ;
424
- info->library_version = " v1.2.0 " ;
575
+ info->library_version = " v1.2.1 " ;
425
576
info->need_fullpath = true ;
426
577
info->valid_extensions = " img|dsk|tap|dtf|com|trn|128|bas|cas|cdt|tzx|wav|tvcwav|." ;
427
578
}
@@ -642,6 +793,8 @@ bool retro_load_game(const struct retro_game_info *info)
642
793
log_cb (RETRO_LOG_DEBUG, " Content extension: %s \n " ,contentExt.c_str ());
643
794
Ep128Emu::splitPath (filename,contentPath,contentFile);
644
795
contentBasename = contentFile;
796
+ diskPaths[0 ] = filename;
797
+ diskNames[0 ] = contentBasename;
645
798
Ep128Emu::stringToLowerCase (contentBasename);
646
799
647
800
int contentLocale = Ep128Emu::LOCALE_UK;
@@ -720,9 +873,9 @@ bool retro_load_game(const struct retro_game_info *info)
720
873
// - 0xfe as "
721
874
// - 0xfd as F1 (START)
722
875
const char * startupSequence = " " ;
723
- bool tapeContent = false ;
724
- bool diskContent = false ;
725
- bool fileContent = false ;
876
+ tapeContent = false ;
877
+ diskContent = false ;
878
+ fileContent = false ;
726
879
int detectedMachineDetailedType = Ep128Emu::VM_config.at (" VM_CONFIG_UNKNOWN" );
727
880
728
881
// start with longer magic strings - less chance of mis-detection
0 commit comments