src/emu/clifront.c
| r14615 | r14616 | |
| 88 | 88 | { CLICOMMAND_LISTSLOTS ";lslot", "0", OPTION_COMMAND, "list available slots and slot devices" }, |
| 89 | 89 | { CLICOMMAND_LISTMEDIA ";lm", "0", OPTION_COMMAND, "list available media for the system" }, |
| 90 | 90 | { CLICOMMAND_LISTSOFTWARE ";lsoft", "0", OPTION_COMMAND, "list known software for the system" }, |
| 91 | | |
| 91 | { CLICOMMAND_GETSOFTLIST ";glist", "0", OPTION_COMMAND, "retrieve software list by name" }, |
| 92 | 92 | { NULL } |
| 93 | 93 | }; |
| 94 | 94 | |
| r14615 | r14616 | |
| 795 | 795 | } |
| 796 | 796 | |
| 797 | 797 | driver_enumerator dummy_drivlist(m_options); |
| 798 | | typedef tagmap_t<FPTR> int_map; |
| 799 | 798 | int_map device_map; |
| 800 | 799 | while (dummy_drivlist.next()) |
| 801 | 800 | { |
| r14615 | r14616 | |
| 1039 | 1038 | mame_printf_info("%d samplesets found, %d were OK.\n", correct, correct); |
| 1040 | 1039 | } |
| 1041 | 1040 | } |
| 1041 | #define SOFTLIST_XML_BEGIN "<?xml version=\"1.0\"?>\n" \ |
| 1042 | "<!DOCTYPE softwarelist [\n" \ |
| 1043 | "<!ELEMENT softwarelists (softwarelist*)>\n" \ |
| 1044 | "\t<!ELEMENT softwarelist (software+)>\n" \ |
| 1045 | "\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" \ |
| 1046 | "\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" \ |
| 1047 | "\t\t<!ELEMENT software (description, year?, publisher, info*, sharedfeat*, part*)>\n" \ |
| 1048 | "\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" \ |
| 1049 | "\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" \ |
| 1050 | "\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" \ |
| 1051 | "\t\t\t<!ELEMENT description (#PCDATA)>\n" \ |
| 1052 | "\t\t\t<!ELEMENT year (#PCDATA)>\n" \ |
| 1053 | "\t\t\t<!ELEMENT publisher (#PCDATA)>\n" \ |
| 1054 | "\t\t\t<!ELEMENT info EMPTY>\n" \ |
| 1055 | "\t\t\t\t<!ATTLIST info name CDATA #REQUIRED>\n" \ |
| 1056 | "\t\t\t\t<!ATTLIST info value CDATA #IMPLIED>\n" \ |
| 1057 | "\t\t\t<!ELEMENT sharedfeat EMPTY>\n" \ |
| 1058 | "\t\t\t\t<!ATTLIST sharedfeat name CDATA #REQUIRED>\n" \ |
| 1059 | "\t\t\t\t<!ATTLIST sharedfeat value CDATA #IMPLIED>\n" \ |
| 1060 | "\t\t\t<!ELEMENT part (feature*, dataarea*, diskarea*, dipswitch*)>\n" \ |
| 1061 | "\t\t\t\t<!ATTLIST part name CDATA #REQUIRED>\n" \ |
| 1062 | "\t\t\t\t<!ATTLIST part interface CDATA #REQUIRED>\n" \ |
| 1063 | "\t\t\t\t<!ELEMENT feature EMPTY>\n" \ |
| 1064 | "\t\t\t\t\t<!ATTLIST feature name CDATA #REQUIRED>\n" \ |
| 1065 | "\t\t\t\t\t<!ATTLIST feature value CDATA #IMPLIED>\n" \ |
| 1066 | "\t\t\t\t<!ELEMENT dataarea (rom*)>\n" \ |
| 1067 | "\t\t\t\t\t<!ATTLIST dataarea name CDATA #REQUIRED>\n" \ |
| 1068 | "\t\t\t\t\t<!ATTLIST dataarea size CDATA #REQUIRED>\n" \ |
| 1069 | "\t\t\t\t\t<!ATTLIST dataarea databits (8|16|32|64) \"8\">\n" \ |
| 1070 | "\t\t\t\t\t<!ATTLIST dataarea endian (big|little) \"little\">\n" \ |
| 1071 | "\t\t\t\t\t<!ELEMENT rom EMPTY>\n" \ |
| 1072 | "\t\t\t\t\t\t<!ATTLIST rom name CDATA #IMPLIED>\n" \ |
| 1073 | "\t\t\t\t\t\t<!ATTLIST rom size CDATA #IMPLIED>\n" \ |
| 1074 | "\t\t\t\t\t\t<!ATTLIST rom length CDATA #IMPLIED>\n" \ |
| 1075 | "\t\t\t\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" \ |
| 1076 | "\t\t\t\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" \ |
| 1077 | "\t\t\t\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" \ |
| 1078 | "\t\t\t\t\t\t<!ATTLIST rom value CDATA #IMPLIED>\n" \ |
| 1079 | "\t\t\t\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" \ |
| 1080 | "\t\t\t\t\t\t<!ATTLIST rom loadflag (load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload|fill|continue) #IMPLIED>\n" \ |
| 1081 | "\t\t\t\t<!ELEMENT diskarea (disk*)>\n" \ |
| 1082 | "\t\t\t\t\t<!ATTLIST diskarea name CDATA #REQUIRED>\n" \ |
| 1083 | "\t\t\t\t\t<!ELEMENT disk EMPTY>\n" \ |
| 1084 | "\t\t\t\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n" \ |
| 1085 | "\t\t\t\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n" \ |
| 1086 | "\t\t\t\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n" \ |
| 1087 | "\t\t\t\t\t\t<!ATTLIST disk writeable (yes|no) \"no\">\n" \ |
| 1088 | "\t\t\t\t<!ELEMENT dipswitch (dipvalue*)>\n" \ |
| 1089 | "\t\t\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n" \ |
| 1090 | "\t\t\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n" \ |
| 1091 | "\t\t\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n" \ |
| 1092 | "\t\t\t\t\t<!ELEMENT dipvalue EMPTY>\n" \ |
| 1093 | "\t\t\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n" \ |
| 1094 | "\t\t\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n" \ |
| 1095 | "\t\t\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" \ |
| 1096 | "]>\n\n" \ |
| 1097 | "<softwarelists>\n" |
| 1042 | 1098 | |
| 1099 | void cli_frontend::output_single_softlist(FILE *out,software_list *list, const char *listname) |
| 1100 | { |
| 1101 | astring tempstr; |
| 1102 | software_list_parse( list, NULL, NULL ); |
| 1043 | 1103 | |
| 1104 | fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", listname, xml_normalize_string(software_list_get_description(list)) ); |
| 1105 | |
| 1106 | for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) |
| 1107 | { |
| 1108 | fprintf( out, "\t\t<software name=\"%s\"", swinfo->shortname ); |
| 1109 | if ( swinfo->parentname != NULL ) |
| 1110 | fprintf( out, " cloneof=\"%s\"", swinfo->parentname ); |
| 1111 | if ( swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL ) |
| 1112 | fprintf( out, " supported=\"partial\"" ); |
| 1113 | if ( swinfo->supported == SOFTWARE_SUPPORTED_NO ) |
| 1114 | fprintf( out, " supported=\"no\"" ); |
| 1115 | fprintf( out, ">\n" ); |
| 1116 | fprintf( out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo->longname) ); |
| 1117 | fprintf( out, "\t\t\t<year>%s</year>\n", xml_normalize_string( swinfo->year ) ); |
| 1118 | fprintf( out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string( swinfo->publisher ) ); |
| 1119 | |
| 1120 | for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) |
| 1121 | { |
| 1122 | fprintf( out, "\t\t\t<part name=\"%s\"", part->name ); |
| 1123 | if ( part->interface_ ) |
| 1124 | fprintf( out, " interface=\"%s\"", part->interface_ ); |
| 1125 | |
| 1126 | fprintf( out, ">\n"); |
| 1127 | |
| 1128 | if ( part->featurelist ) |
| 1129 | { |
| 1130 | feature_list *flist = part->featurelist; |
| 1131 | |
| 1132 | while( flist ) |
| 1133 | { |
| 1134 | fprintf( out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist->name, flist->value ); |
| 1135 | flist = flist->next; |
| 1136 | } |
| 1137 | } |
| 1138 | |
| 1139 | /* TODO: display rom region information */ |
| 1140 | for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) ) |
| 1141 | { |
| 1142 | int is_disk = ROMREGION_ISDISKDATA(region); |
| 1143 | |
| 1144 | if (!is_disk) |
| 1145 | fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) ); |
| 1146 | else |
| 1147 | fprintf( out, "\t\t\t\t<diskarea name=\"%s\">\n", ROMREGION_GETTAG(region) ); |
| 1148 | |
| 1149 | for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ ) |
| 1150 | { |
| 1151 | if ( ROMENTRY_ISFILE(rom) ) |
| 1152 | { |
| 1153 | if (!is_disk) |
| 1154 | fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) ); |
| 1155 | else |
| 1156 | fprintf( out, "\t\t\t\t\t<disk name=\"%s\"", xml_normalize_string(ROM_GETNAME(rom)) ); |
| 1157 | |
| 1158 | /* dump checksum information only if there is a known dump */ |
| 1159 | hash_collection hashes(ROM_GETHASHDATA(rom)); |
| 1160 | if ( !hashes.flag(hash_collection::FLAG_NO_DUMP) ) |
| 1161 | fprintf( out, " %s", hashes.attribute_string(tempstr) ); |
| 1162 | else |
| 1163 | fprintf( out, " status=\"nodump\"" ); |
| 1164 | |
| 1165 | if (is_disk) |
| 1166 | fprintf( out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes"); |
| 1167 | |
| 1168 | if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1)) |
| 1169 | fprintf( out, " loadflag=\"load16_byte\"" ); |
| 1170 | |
| 1171 | if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3)) |
| 1172 | fprintf( out, " loadflag=\"load32_byte\"" ); |
| 1173 | |
| 1174 | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(2)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1175 | { |
| 1176 | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1177 | fprintf( out, " loadflag=\"load32_word\"" ); |
| 1178 | else |
| 1179 | fprintf( out, " loadflag=\"load32_word_swap\"" ); |
| 1180 | } |
| 1181 | |
| 1182 | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(6)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1183 | { |
| 1184 | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1185 | fprintf( out, " loadflag=\"load64_word\"" ); |
| 1186 | else |
| 1187 | fprintf( out, " loadflag=\"load64_word_swap\"" ); |
| 1188 | } |
| 1189 | |
| 1190 | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_NOSKIP) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1191 | { |
| 1192 | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1193 | fprintf( out, " loadflag=\"load32_dword\"" ); |
| 1194 | else |
| 1195 | fprintf( out, " loadflag=\"load16_word_swap\"" ); |
| 1196 | } |
| 1197 | |
| 1198 | fprintf( out, "/>\n" ); |
| 1199 | } |
| 1200 | else if ( ROMENTRY_ISRELOAD(rom) ) |
| 1201 | { |
| 1202 | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1203 | } |
| 1204 | else if ( ROMENTRY_ISCONTINUE(rom) ) |
| 1205 | { |
| 1206 | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"continue\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1207 | } |
| 1208 | else if ( ROMENTRY_ISFILL(rom) ) |
| 1209 | { |
| 1210 | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"fill\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1211 | } |
| 1212 | } |
| 1213 | |
| 1214 | if (!is_disk) |
| 1215 | fprintf( out, "\t\t\t\t</dataarea>\n" ); |
| 1216 | else |
| 1217 | fprintf( out, "\t\t\t\t</diskarea>\n" ); |
| 1218 | } |
| 1219 | |
| 1220 | fprintf( out, "\t\t\t</part>\n" ); |
| 1221 | } |
| 1222 | |
| 1223 | fprintf( out, "\t\t</software>\n" ); |
| 1224 | } |
| 1225 | fprintf(out, "\t</softwarelist>\n" ); |
| 1226 | } |
| 1044 | 1227 | /*------------------------------------------------- |
| 1045 | 1228 | info_listsoftware - output the list of |
| 1046 | 1229 | software supported by a given game or set of |
| r14615 | r14616 | |
| 1053 | 1236 | void cli_frontend::listsoftware(const char *gamename) |
| 1054 | 1237 | { |
| 1055 | 1238 | FILE *out = stdout; |
| 1239 | int_map list_map; |
| 1240 | bool isfirst = TRUE; |
| 1056 | 1241 | |
| 1057 | 1242 | // determine which drivers to output; return an error if none found |
| 1058 | 1243 | driver_enumerator drivlist(m_options, gamename); |
| 1059 | 1244 | if (drivlist.count() == 0) |
| 1060 | 1245 | throw emu_fatalerror(MAMERR_NO_SUCH_GAME, "No matching games found for '%s'", gamename); |
| 1061 | | |
| 1062 | | // first determine the maximum number of lists we might encounter |
| 1063 | | int list_count = 0; |
| 1246 | |
| 1064 | 1247 | while (drivlist.next()) |
| 1065 | 1248 | { |
| 1066 | 1249 | software_list_device_iterator iter(drivlist.config().root_device()); |
| 1067 | 1250 | for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) |
| 1068 | | if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) |
| 1069 | | list_count++; |
| 1070 | | } |
| 1071 | | |
| 1072 | | // allocate a list |
| 1073 | | astring *lists = global_alloc_array(astring, list_count); |
| 1074 | | |
| 1075 | | if (list_count) |
| 1076 | | { |
| 1077 | | fprintf( out, |
| 1078 | | "<?xml version=\"1.0\"?>\n" |
| 1079 | | "<!DOCTYPE softwarelist [\n" |
| 1080 | | "<!ELEMENT softwarelists (softwarelist*)>\n" |
| 1081 | | "\t<!ELEMENT softwarelist (software+)>\n" |
| 1082 | | "\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" |
| 1083 | | "\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" |
| 1084 | | "\t\t<!ELEMENT software (description, year?, publisher, info*, sharedfeat*, part*)>\n" |
| 1085 | | "\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" |
| 1086 | | "\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" |
| 1087 | | "\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" |
| 1088 | | "\t\t\t<!ELEMENT description (#PCDATA)>\n" |
| 1089 | | "\t\t\t<!ELEMENT year (#PCDATA)>\n" |
| 1090 | | "\t\t\t<!ELEMENT publisher (#PCDATA)>\n" |
| 1091 | | // we still do not store the info strings internally, so there is no output here |
| 1092 | | // TODO: add parsing info in softlist.c and then add output here! |
| 1093 | | "\t\t\t<!ELEMENT info EMPTY>\n" |
| 1094 | | "\t\t\t\t<!ATTLIST info name CDATA #REQUIRED>\n" |
| 1095 | | "\t\t\t\t<!ATTLIST info value CDATA #IMPLIED>\n" |
| 1096 | | // shared features get stored in the part->feature below and are output there |
| 1097 | | // this means that we don't output any <sharedfeat> and that -lsoft output will |
| 1098 | | // be different from the list in hash/ when the list uses sharedfeat. But this |
| 1099 | | // is by design: sharedfeat is only available to simplify the life to list creators, |
| 1100 | | // to e.g. avoid manually adding the same feature to each disk of a 9 floppies game! |
| 1101 | | "\t\t\t<!ELEMENT sharedfeat EMPTY>\n" |
| 1102 | | "\t\t\t\t<!ATTLIST sharedfeat name CDATA #REQUIRED>\n" |
| 1103 | | "\t\t\t\t<!ATTLIST sharedfeat value CDATA #IMPLIED>\n" |
| 1104 | | "\t\t\t<!ELEMENT part (feature*, dataarea*, diskarea*, dipswitch*)>\n" |
| 1105 | | "\t\t\t\t<!ATTLIST part name CDATA #REQUIRED>\n" |
| 1106 | | "\t\t\t\t<!ATTLIST part interface CDATA #REQUIRED>\n" |
| 1107 | | "\t\t\t\t<!ELEMENT feature EMPTY>\n" |
| 1108 | | "\t\t\t\t\t<!ATTLIST feature name CDATA #REQUIRED>\n" |
| 1109 | | "\t\t\t\t\t<!ATTLIST feature value CDATA #IMPLIED>\n" |
| 1110 | | "\t\t\t\t<!ELEMENT dataarea (rom*)>\n" |
| 1111 | | "\t\t\t\t\t<!ATTLIST dataarea name CDATA #REQUIRED>\n" |
| 1112 | | "\t\t\t\t\t<!ATTLIST dataarea size CDATA #REQUIRED>\n" |
| 1113 | | "\t\t\t\t\t<!ATTLIST dataarea databits (8|16|32|64) \"8\">\n" |
| 1114 | | "\t\t\t\t\t<!ATTLIST dataarea endian (big|little) \"little\">\n" |
| 1115 | | "\t\t\t\t\t<!ELEMENT rom EMPTY>\n" |
| 1116 | | "\t\t\t\t\t\t<!ATTLIST rom name CDATA #IMPLIED>\n" |
| 1117 | | "\t\t\t\t\t\t<!ATTLIST rom size CDATA #IMPLIED>\n" |
| 1118 | | "\t\t\t\t\t\t<!ATTLIST rom length CDATA #IMPLIED>\n" |
| 1119 | | "\t\t\t\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" |
| 1120 | | "\t\t\t\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" |
| 1121 | | "\t\t\t\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" |
| 1122 | | "\t\t\t\t\t\t<!ATTLIST rom value CDATA #IMPLIED>\n" |
| 1123 | | "\t\t\t\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" |
| 1124 | | "\t\t\t\t\t\t<!ATTLIST rom loadflag (load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload|fill|continue) #IMPLIED>\n" |
| 1125 | | "\t\t\t\t<!ELEMENT diskarea (disk*)>\n" |
| 1126 | | "\t\t\t\t\t<!ATTLIST diskarea name CDATA #REQUIRED>\n" |
| 1127 | | "\t\t\t\t\t<!ELEMENT disk EMPTY>\n" |
| 1128 | | "\t\t\t\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n" |
| 1129 | | "\t\t\t\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n" |
| 1130 | | "\t\t\t\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n" |
| 1131 | | "\t\t\t\t\t\t<!ATTLIST disk writeable (yes|no) \"no\">\n" |
| 1132 | | // we still do not store the dipswitch values internally, so there is no output here |
| 1133 | | // TODO: add parsing dipsw in softlist.c and then add output here! |
| 1134 | | "\t\t\t\t<!ELEMENT dipswitch (dipvalue*)>\n" |
| 1135 | | "\t\t\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n" |
| 1136 | | "\t\t\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n" |
| 1137 | | "\t\t\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n" |
| 1138 | | "\t\t\t\t\t<!ELEMENT dipvalue EMPTY>\n" |
| 1139 | | "\t\t\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n" |
| 1140 | | "\t\t\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n" |
| 1141 | | "\t\t\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n" |
| 1142 | | "]>\n\n" |
| 1143 | | "<softwarelists>\n" |
| 1144 | | ); |
| 1145 | | } |
| 1146 | | |
| 1147 | | drivlist.reset(); |
| 1148 | | list_count = 0; |
| 1149 | | astring tempstr; |
| 1150 | | while (drivlist.next()) |
| 1151 | | { |
| 1152 | | software_list_device_iterator iter(drivlist.config().root_device()); |
| 1153 | | for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) |
| 1154 | 1251 | { |
| 1155 | 1252 | if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) |
| 1156 | 1253 | { |
| r14615 | r14616 | |
| 1159 | 1256 | if ( list ) |
| 1160 | 1257 | { |
| 1161 | 1258 | /* Verify if we have encountered this list before */ |
| 1162 | | bool seen_before = false; |
| 1163 | | for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++) |
| 1164 | | if (lists[seen_index] == swlist->list_name()) |
| 1165 | | seen_before = true; |
| 1259 | if (list_map.add(swlist->list_name(), 0, false) != TMERR_DUPLICATE) |
| 1260 | { |
| 1261 | if (isfirst) { fprintf( out, SOFTLIST_XML_BEGIN); isfirst = FALSE; } |
| 1262 | output_single_softlist(out, list, swlist->list_name()); |
| 1263 | } |
| 1166 | 1264 | |
| 1167 | | if (!seen_before) |
| 1168 | | { |
| 1169 | | lists[list_count++] = swlist->list_name(); |
| 1170 | | software_list_parse( list, NULL, NULL ); |
| 1265 | software_list_close( list ); |
| 1266 | } |
| 1267 | } |
| 1268 | } |
| 1269 | } |
| 1171 | 1270 | |
| 1172 | | fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name(), xml_normalize_string(software_list_get_description(list)) ); |
| 1271 | if (!isfirst) |
| 1272 | fprintf( out, "</softwarelists>\n" ); |
| 1273 | else |
| 1274 | fprintf( out, "No software lists found for this system\n" ); |
| 1275 | } |
| 1173 | 1276 | |
| 1174 | | for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) |
| 1175 | | { |
| 1176 | | fprintf( out, "\t\t<software name=\"%s\"", swinfo->shortname ); |
| 1177 | | if ( swinfo->parentname != NULL ) |
| 1178 | | fprintf( out, " cloneof=\"%s\"", swinfo->parentname ); |
| 1179 | | if ( swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL ) |
| 1180 | | fprintf( out, " supported=\"partial\"" ); |
| 1181 | | if ( swinfo->supported == SOFTWARE_SUPPORTED_NO ) |
| 1182 | | fprintf( out, " supported=\"no\"" ); |
| 1183 | | fprintf( out, ">\n" ); |
| 1184 | | fprintf( out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo->longname) ); |
| 1185 | | fprintf( out, "\t\t\t<year>%s</year>\n", xml_normalize_string( swinfo->year ) ); |
| 1186 | | fprintf( out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string( swinfo->publisher ) ); |
| 1187 | 1277 | |
| 1188 | | for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) |
| 1189 | | { |
| 1190 | | fprintf( out, "\t\t\t<part name=\"%s\"", part->name ); |
| 1191 | | if ( part->interface_ ) |
| 1192 | | fprintf( out, " interface=\"%s\"", part->interface_ ); |
| 1278 | /*------------------------------------------------- |
| 1279 | getsoftlist - retrieve software list by name |
| 1280 | -------------------------------------------------*/ |
| 1193 | 1281 | |
| 1194 | | fprintf( out, ">\n"); |
| 1195 | | |
| 1196 | | if ( part->featurelist ) |
| 1197 | | { |
| 1198 | | feature_list *flist = part->featurelist; |
| 1199 | | |
| 1200 | | while( flist ) |
| 1201 | | { |
| 1202 | | fprintf( out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist->name, flist->value ); |
| 1203 | | flist = flist->next; |
| 1204 | | } |
| 1205 | | } |
| 1206 | | |
| 1207 | | /* TODO: display rom region information */ |
| 1208 | | for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) ) |
| 1209 | | { |
| 1210 | | int is_disk = ROMREGION_ISDISKDATA(region); |
| 1211 | | |
| 1212 | | if (!is_disk) |
| 1213 | | fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%d\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) ); |
| 1214 | | else |
| 1215 | | fprintf( out, "\t\t\t\t<diskarea name=\"%s\">\n", ROMREGION_GETTAG(region) ); |
| 1216 | | |
| 1217 | | for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ ) |
| 1218 | | { |
| 1219 | | if ( ROMENTRY_ISFILE(rom) ) |
| 1220 | | { |
| 1221 | | if (!is_disk) |
| 1222 | | fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) ); |
| 1223 | | else |
| 1224 | | fprintf( out, "\t\t\t\t\t<disk name=\"%s\"", xml_normalize_string(ROM_GETNAME(rom)) ); |
| 1225 | | |
| 1226 | | /* dump checksum information only if there is a known dump */ |
| 1227 | | hash_collection hashes(ROM_GETHASHDATA(rom)); |
| 1228 | | if ( !hashes.flag(hash_collection::FLAG_NO_DUMP) ) |
| 1229 | | fprintf( out, " %s", hashes.attribute_string(tempstr) ); |
| 1230 | | else |
| 1231 | | fprintf( out, " status=\"nodump\"" ); |
| 1232 | | |
| 1233 | | if (is_disk) |
| 1234 | | fprintf( out, " writeable=\"%s\"", (ROM_GETFLAGS(rom) & DISK_READONLYMASK) ? "no" : "yes"); |
| 1235 | | |
| 1236 | | if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(1)) |
| 1237 | | fprintf( out, " loadflag=\"load16_byte\"" ); |
| 1238 | | |
| 1239 | | if ((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(3)) |
| 1240 | | fprintf( out, " loadflag=\"load32_byte\"" ); |
| 1241 | | |
| 1242 | | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(2)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1243 | | { |
| 1244 | | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1245 | | fprintf( out, " loadflag=\"load32_word\"" ); |
| 1246 | | else |
| 1247 | | fprintf( out, " loadflag=\"load32_word_swap\"" ); |
| 1248 | | } |
| 1249 | | |
| 1250 | | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_SKIP(6)) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1251 | | { |
| 1252 | | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1253 | | fprintf( out, " loadflag=\"load64_word\"" ); |
| 1254 | | else |
| 1255 | | fprintf( out, " loadflag=\"load64_word_swap\"" ); |
| 1256 | | } |
| 1257 | | |
| 1258 | | if (((ROM_GETFLAGS(rom) & ROM_SKIPMASK) == ROM_NOSKIP) && ((ROM_GETFLAGS(rom) & ROM_GROUPMASK) == ROM_GROUPWORD)) |
| 1259 | | { |
| 1260 | | if (!(ROM_GETFLAGS(rom) & ROM_REVERSEMASK)) |
| 1261 | | fprintf( out, " loadflag=\"load32_dword\"" ); |
| 1262 | | else |
| 1263 | | fprintf( out, " loadflag=\"load16_word_swap\"" ); |
| 1264 | | } |
| 1265 | | |
| 1266 | | fprintf( out, "/>\n" ); |
| 1267 | | } |
| 1268 | | else if ( ROMENTRY_ISRELOAD(rom) ) |
| 1269 | | { |
| 1270 | | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1271 | | } |
| 1272 | | else if ( ROMENTRY_ISCONTINUE(rom) ) |
| 1273 | | { |
| 1274 | | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"continue\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1275 | | } |
| 1276 | | else if ( ROMENTRY_ISFILL(rom) ) |
| 1277 | | { |
| 1278 | | fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"0x%x\" loadflag=\"fill\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); |
| 1279 | | } |
| 1280 | | } |
| 1281 | | |
| 1282 | | if (!is_disk) |
| 1283 | | fprintf( out, "\t\t\t\t</dataarea>\n" ); |
| 1284 | | else |
| 1285 | | fprintf( out, "\t\t\t\t</diskarea>\n" ); |
| 1286 | | } |
| 1287 | | |
| 1288 | | fprintf( out, "\t\t\t</part>\n" ); |
| 1289 | | } |
| 1290 | | |
| 1291 | | fprintf( out, "\t\t</software>\n" ); |
| 1292 | | } |
| 1293 | | |
| 1294 | | fprintf(out, "\t</softwarelist>\n" ); |
| 1295 | | } |
| 1296 | | |
| 1297 | | software_list_close( list ); |
| 1282 | void cli_frontend::getsoftlist(const char *gamename) |
| 1283 | { |
| 1284 | FILE *out = stdout; |
| 1285 | int_map list_map; |
| 1286 | bool isfirst = TRUE; |
| 1287 | |
| 1288 | driver_enumerator drivlist(m_options); |
| 1289 | while (drivlist.next()) |
| 1290 | { |
| 1291 | software_list_device_iterator iter(drivlist.config().root_device()); |
| 1292 | for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) |
| 1293 | { |
| 1294 | software_list *list = software_list_open(m_options, swlist->list_name(), FALSE, NULL); |
| 1295 | if ( list ) |
| 1296 | { |
| 1297 | if ((mame_strwildcmp(swlist->list_name(),gamename)==0) && list_map.add(swlist->list_name(), 0, false) != TMERR_DUPLICATE) |
| 1298 | { |
| 1299 | if (isfirst) { fprintf( out, SOFTLIST_XML_BEGIN); isfirst = FALSE; } |
| 1300 | output_single_softlist(out, list, swlist->list_name()); |
| 1298 | 1301 | } |
| 1302 | software_list_close( list ); |
| 1299 | 1303 | } |
| 1300 | 1304 | } |
| 1301 | 1305 | } |
| 1302 | 1306 | |
| 1303 | | if (list_count > 0) |
| 1307 | if (!isfirst) |
| 1304 | 1308 | fprintf( out, "</softwarelists>\n" ); |
| 1305 | 1309 | else |
| 1306 | | fprintf( out, "No software lists found for this system\n" ); |
| 1307 | | |
| 1308 | | global_free( lists ); |
| 1310 | fprintf( out, "No such software lists found\n" ); |
| 1309 | 1311 | } |
| 1310 | 1312 | |
| 1311 | 1313 | |
| r14615 | r14616 | |
| 1414 | 1416 | { CLICOMMAND_VERIFYROMS, &cli_frontend::verifyroms }, |
| 1415 | 1417 | { CLICOMMAND_VERIFYSAMPLES, &cli_frontend::verifysamples }, |
| 1416 | 1418 | { CLICOMMAND_LISTMEDIA, &cli_frontend::listmedia }, |
| 1417 | | { CLICOMMAND_LISTSOFTWARE, &cli_frontend::listsoftware }, |
| 1418 | | { CLICOMMAND_ROMIDENT, &cli_frontend::romident } |
| 1419 | { CLICOMMAND_LISTSOFTWARE, &cli_frontend::listsoftware }, |
| 1420 | { CLICOMMAND_ROMIDENT, &cli_frontend::romident }, |
| 1421 | { CLICOMMAND_GETSOFTLIST, &cli_frontend::getsoftlist }, |
| 1419 | 1422 | }; |
| 1420 | 1423 | |
| 1421 | 1424 | // find the command |