Skip to content

Commit acf821e

Browse files
committed
v1.2.1, disk interface added
Implemented interface for disk (and, actually, tape image) swapping. Not really useful for Enterprise due to lack of multi-disk content, but works for CPC disks, and ZX tapes.
1 parent 8bde6e8 commit acf821e

File tree

2 files changed

+194
-41
lines changed

2 files changed

+194
-41
lines changed

core/main.cpp

Lines changed: 168 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ virtual keyboard
2626
core options v2 https://github.com/libretro/libretro-common/tree/master/samples/core_options
2727
check and include libretro common
2828
detailed type detection from content name
29-
m3u (or, rather, name-based autodetect) multi-disk, multi-tape interface support (cpc 3 guerra)
3029
locale support ep, cpc
3130
rom config for clkoff+hfont
3231
@@ -42,6 +41,7 @@ EP Mouse support
4241
achievement support
4342
test mp3 support with sndfile 1.1 - cmake won't find lame / mpeg123 when compiling libsndfile
4443
led driver for tape / disk loading - see comments inside
44+
name-based autodetect for multi-disk, multi-tape interface support (cpc 3 guerra)
4545
4646
*/
4747

@@ -104,15 +104,25 @@ retro_usec_t prev_frame_time = 0;
104104
float waitPeriod = 0.001;
105105
bool useSwFb = false;
106106
bool useHalfFrame = false;
107-
bool enableDiskControl = false;
108-
bool needsDiskControl = false;
109107
int borderSize = 0;
110108
bool soundHq = true;
111-
unsigned maxUsers;
112-
bool maxUsersSupported = true;
113109
bool canSkipFrames = false;
114110
bool enhancedRom = false;
115111

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+
116126
Ep128Emu::VMThread *vmThread = (Ep128Emu::VMThread *) 0;
117127
Ep128Emu::EmulatorConfiguration *config = (Ep128Emu::EmulatorConfiguration *) 0;
118128
Ep128Emu::LibretroCore *core = (Ep128Emu::LibretroCore *) 0;
@@ -293,6 +303,117 @@ static void check_variables(void)
293303
if(vmThread) vmThread->resetKeyboard();
294304
}
295305

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+
296417
void retro_init(void)
297418
{
298419
struct retro_log_callback log;
@@ -303,12 +424,42 @@ void retro_init(void)
303424
else
304425
log_cb = fallback_log;
305426

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+
307457
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+
}
312463

313464
/* struct retro_led_interface led_interface;
314465
if(environ_cb(RETRO_ENVIRONMENT_GET_LED_INTERFACE, &led_interface)) {
@@ -366,7 +517,7 @@ void retro_init(void)
366517
sizeof(retro_system_save_directory) - 1
367518
);
368519

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);
370521
log_cb(RETRO_LOG_DEBUG, "Retro SAVE_DIRECTORY %s\n", retro_system_save_directory);
371522
log_cb(RETRO_LOG_DEBUG, "Retro CONTENT_DIRECTORY %s\n", retro_content_directory);
372523

@@ -421,7 +572,7 @@ void retro_get_system_info(struct retro_system_info *info)
421572
{
422573
memset(info, 0, sizeof(*info));
423574
info->library_name = "ep128emu";
424-
info->library_version = "v1.2.0";
575+
info->library_version = "v1.2.1";
425576
info->need_fullpath = true;
426577
info->valid_extensions = "img|dsk|tap|dtf|com|trn|128|bas|cas|cdt|tzx|wav|tvcwav|.";
427578
}
@@ -642,6 +793,8 @@ bool retro_load_game(const struct retro_game_info *info)
642793
log_cb(RETRO_LOG_DEBUG, "Content extension: %s \n",contentExt.c_str());
643794
Ep128Emu::splitPath(filename,contentPath,contentFile);
644795
contentBasename = contentFile;
796+
diskPaths[0] = filename;
797+
diskNames[0] = contentBasename;
645798
Ep128Emu::stringToLowerCase(contentBasename);
646799

647800
int contentLocale = Ep128Emu::LOCALE_UK;
@@ -720,9 +873,9 @@ bool retro_load_game(const struct retro_game_info *info)
720873
// - 0xfe as "
721874
// - 0xfd as F1 (START)
722875
const char* startupSequence = "";
723-
bool tapeContent = false;
724-
bool diskContent = false;
725-
bool fileContent = false;
876+
tapeContent = false;
877+
diskContent = false;
878+
fileContent = false;
726879
int detectedMachineDetailedType = Ep128Emu::VM_config.at("VM_CONFIG_UNKNOWN");
727880

728881
// start with longer magic strings - less chance of mis-detection

ep128emu_core_libretro.info

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ license = "GPLv2"
2323
permissions = ""
2424

2525
# Version of the core:
26-
display_version = "v1.2.0"
26+
display_version = "v1.2.1"
2727

2828
# Hardware Information - Information about the hardware the core supports (when applicable)
2929
# Name of the manufacturer who produced the emulated system:
@@ -48,91 +48,91 @@ firmware_count = 22
4848
# firmware0_opt = "true/false"
4949

5050
firmware0_desc = "exos21.rom (Enterprise 128 Expandible OS 2.1)"
51-
firmware0_path = "ep128emu/roms/exos21.rom";
51+
firmware0_path = "ep128emu/roms/exos21.rom"
5252
firmware0_opt = "true"
5353

5454
firmware1_desc = "basic21.rom (Enterprise 128 BASIC Interpreter v2.1)"
55-
firmware1_path = "ep128emu/roms/basic21.rom";
55+
firmware1_path = "ep128emu/roms/basic21.rom"
5656
firmware1_opt = "true"
5757

5858
firmware2_desc = "exdos13.rom (Enterprise 128 Disk Controller v1.3)"
59-
firmware2_path = "ep128emu/roms/exdos13.rom";
59+
firmware2_path = "ep128emu/roms/exdos13.rom"
6060
firmware2_opt = "true"
6161

6262
firmware3_desc = "exos20.rom (Enterprise 64 Expandible OS 2.0)"
63-
firmware3_path = "ep128emu/roms/exos20.rom";
63+
firmware3_path = "ep128emu/roms/exos20.rom"
6464
firmware3_opt = "true"
6565

6666
firmware4_desc = "basic20.rom (Enterprise 64 BASIC Interpreter v2.0)"
67-
firmware4_path = "ep128emu/roms/basic20.rom";
67+
firmware4_path = "ep128emu/roms/basic20.rom"
6868
firmware4_opt = "true"
6969

7070
firmware5_desc = "epfileio.rom (Enterprise 128 Direct File I/O)"
71-
firmware5_path = "ep128emu/roms/epfileio.rom";
71+
firmware5_path = "ep128emu/roms/epfileio.rom"
7272
firmware5_opt = "true"
7373

7474
firmware6_desc = "exos24uk.rom (Enterprise 128 Expandible OS 2.4)"
75-
firmware6_path = "ep128emu/roms/exos24uk.rom";
75+
firmware6_path = "ep128emu/roms/exos24uk.rom"
7676
firmware6_opt = "true"
7777

7878
firmware7_desc = "hun.rom (Enterprise 128 Hungarian language extension)"
79-
firmware7_path = "ep128emu/roms/hun.rom";
79+
firmware7_path = "ep128emu/roms/hun.rom"
8080
firmware7_opt = "true"
8181

8282
firmware8_desc = "epd19hft.rom (Enterprise 128 EP-DOS with Hungarian language extension)"
83-
firmware8_path = "ep128emu/roms/epd19hft.rom";
83+
firmware8_path = "ep128emu/roms/epd19hft.rom"
8484
firmware8_opt = "true"
8585

8686
firmware9_desc = "zt19hfnt.rom (Enterprise 128 ZozoTools with Hungarian language extension 1.9)"
87-
firmware9_path = "ep128emu/roms/zt19hfnt.rom";
87+
firmware9_path = "ep128emu/roms/zt19hfnt.rom"
8888
firmware9_opt = "true"
8989

9090
firmware10_desc = "brd.rom (Enterprise 128 German language extension)"
91-
firmware10_path = "ep128emu/roms/brd.rom";
91+
firmware10_path = "ep128emu/roms/brd.rom"
9292
firmware10_opt = "true"
9393

9494
firmware11_desc = "zt19uk.rom (Enterprise 128 ZozoTools extension)"
95-
firmware11_path = "ep128emu/roms/zt19uk.rom";
95+
firmware11_path = "ep128emu/roms/zt19uk.rom"
9696
firmware11_opt = "true"
9797

9898
firmware12_desc = "tvc22_sys.rom (Videoton TVC system BIOS)"
99-
firmware12_path = "ep128emu/roms/tvc22_sys.rom";
99+
firmware12_path = "ep128emu/roms/tvc22_sys.rom"
100100
firmware12_opt = "true"
101101

102102
firmware13_desc = "tvc22_ext.rom (Videoton TVC extension BIOS)"
103-
firmware13_path = "ep128emu/roms/tvc22_ext.rom";
103+
firmware13_path = "ep128emu/roms/tvc22_ext.rom"
104104
firmware13_opt = "true"
105105

106106
firmware14_desc = "tvcfileio.rom (Videoton TVC Direct File I/O)"
107-
firmware14_path = "ep128emu/roms/tvcfileio.rom";
107+
firmware14_path = "ep128emu/roms/tvcfileio.rom"
108108
firmware14_opt = "true"
109109

110110
firmware15_desc = "tvc_dos12d.rom (Videoton TVC disk BIOS)"
111-
firmware15_path = "ep128emu/roms/tvc_dos12d.rom";
111+
firmware15_path = "ep128emu/roms/tvc_dos12d.rom"
112112
firmware15_opt = "true"
113113

114114
firmware16_desc = "cpc464.rom (Amstrad CPC 464 BIOS)"
115-
firmware16_path = "ep128emu/roms/cpc464.rom";
115+
firmware16_path = "ep128emu/roms/cpc464.rom"
116116
firmware16_opt = "true"
117117

118118
firmware17_desc = "cpc664.rom (Amstrad CPC 664 BIOS)"
119-
firmware17_path = "ep128emu/roms/cpc664.rom";
119+
firmware17_path = "ep128emu/roms/cpc664.rom"
120120
firmware17_opt = "true"
121121

122122
firmware18_desc = "cpc6128.rom (Amstrad CPC 6128 BIOS)"
123-
firmware18_path = "ep128emu/roms/cpc6128.rom";
123+
firmware18_path = "ep128emu/roms/cpc6128.rom"
124124
firmware18_opt = "true"
125125

126126
firmware19_desc = "cpc_amsdos.rom (Amstrad CPC AMSDOS BIOS)"
127-
firmware19_path = "ep128emu/roms/cpc_amsdos.rom";
127+
firmware19_path = "ep128emu/roms/cpc_amsdos.rom"
128128
firmware19_opt = "true"
129129

130130
firmware20_desc = "zx128.rom (ZX Spectrum 128 BIOS)"
131-
firmware20_path = "ep128emu/roms/zx128.rom";
131+
firmware20_path = "ep128emu/roms/zx128.rom"
132132
firmware20_opt = "true"
133133

134134
firmware21_desc = "zx48.rom (ZX Spectrum 48 BIOS)"
135-
firmware21_path = "ep128emu/roms/zx48.rom";
135+
firmware21_path = "ep128emu/roms/zx48.rom"
136136
firmware21_opt = "true"
137137

138138
# Additional notes:
@@ -145,11 +145,11 @@ savestate = "true"
145145
# If true, how complete is the savestate support? basic, serialized (rewind), deterministic (netplay/runahead)
146146
savestate_features = "serialized"
147147
# Does the core support the libretro cheat interface?
148-
cheats = "false"
148+
cheats = "true"
149149
# Does the core support libretro input descriptors
150150
input_descriptors = "true"
151151
# Does the core support memory descriptors commonly used for achievements
152-
memory_descriptors = "false"
152+
memory_descriptors = "true"
153153
# Does the core use the libretro save interface or does it do its own thing (like with shared memory cards)?
154154
libretro_saves = "true"
155155
# Does the core support the core options interface?
@@ -171,7 +171,7 @@ hw_render = "false"
171171
# Does the core require ongoing access to the file after loading? Mostly used for softpatching and streaming of data
172172
needs_fullpath = "true"
173173
# Does the core support the libretro disk control interface for swapping disks on the fly?
174-
disk_control = "false"
174+
disk_control = "true"
175175
# Is the core currently suitable for general use? That is, will regular users find it useful or is it for development/testing only (subject to change over time)?
176176
is_experimental = "false"
177177

0 commit comments

Comments
 (0)