softlist.cpp: Add support for a 'notes' field to store information ab… (#8482)

* softlist.cpp: Add support for a 'notes' field to store information about a software list or software list item.  [Wilbert Pol]

* Add software list and software notes to minimaws
This commit is contained in:
wilbertpol 2021-10-05 19:16:42 +02:00 committed by GitHub
parent 716c9f4c86
commit eae75824d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 138 additions and 59 deletions

View File

@ -1,7 +1,8 @@
<!ELEMENT softwarelist (software+)> <!ELEMENT softwarelist (notes?, software+)>
<!ATTLIST softwarelist name CDATA #REQUIRED> <!ATTLIST softwarelist name CDATA #REQUIRED>
<!ATTLIST softwarelist description CDATA #IMPLIED> <!ATTLIST softwarelist description CDATA #IMPLIED>
<!ELEMENT software (description, year, publisher, info*, sharedfeat*, part*)> <!ELEMENT notes (#PCDATA)>
<!ELEMENT software (description, year, publisher, notes?, info*, sharedfeat*, part*)>
<!ATTLIST software name CDATA #REQUIRED> <!ATTLIST software name CDATA #REQUIRED>
<!ATTLIST software cloneof CDATA #IMPLIED> <!ATTLIST software cloneof CDATA #IMPLIED>
<!ATTLIST software supported (yes|partial|no) "yes"> <!ATTLIST software supported (yes|partial|no) "yes">

View File

@ -2,7 +2,9 @@
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd"> <!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
<!-- <!--
license:CC0 license:CC0
-->
<softwarelist name="wswan" description="Bandai Wonderswan cartridges">
<notes><![CDATA[
This is a full list of known WonderSwan and WonderSwan Color games. This is a full list of known WonderSwan and WonderSwan Color games.
+===+=====+==========+============+=====+================================================================================================+ +===+=====+==========+============+=====+================================================================================================+
| D | ROM | CRC | Serial | Rev | Name | | D | ROM | CRC | Serial | Rev | Name |
@ -281,9 +283,7 @@ game will boot up and start to initialize the save area.
The GIZA chip used on a lot of cartridges is a sram voltage switch. The GIZA chip used on a lot of cartridges is a sram voltage switch.
--> ]]></notes>
<softwarelist name="wswan" description="Bandai Wonderswan cartridges">
<software name="anchorz"> <software name="anchorz">
<description>Anchorz Field</description> <description>Anchorz Field</description>
<year>1999</year> <year>1999</year>
@ -523,10 +523,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="choaniki"> <software name="choaniki">
<!-- Rev 4 -->
<description>Chou Aniki - Otoko no Tamafuda</description> <description>Chou Aniki - Otoko no Tamafuda</description>
<year>2000</year> <year>2000</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<notes>Revision from header: Rev 4</notes>
<info name="serial" value="SWJ-BAN023"/> <info name="serial" value="SWJ-BAN023"/>
<info name="release" value="20000210"/> <info name="release" value="20000210"/>
<info name="alt_title" value="超兄貴 男の魂札"/> <info name="alt_title" value="超兄貴 男の魂札"/>
@ -546,10 +546,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="youfumak"> <software name="youfumak">
<!-- Rev 3 -->
<description>Chou Denki Card Game - Youfu Makai - Kikuchi Shuukou</description> <description>Chou Denki Card Game - Youfu Makai - Kikuchi Shuukou</description>
<year>1999</year> <year>1999</year>
<publisher>Kobunsha</publisher> <publisher>Kobunsha</publisher>
<notes>Revision from header: Rev 3</notes>
<info name="serial" value="SWJ-KBS002"/> <info name="serial" value="SWJ-KBS002"/>
<info name="release" value="19991216"/> <info name="release" value="19991216"/>
<info name="alt_title" value="超伝奇カードバトル 妖符魔界 菊地秀行"/> <info name="alt_title" value="超伝奇カードバトル 妖符魔界 菊地秀行"/>
@ -569,10 +569,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="clocktow"> <software name="clocktow">
<!-- Rev 1 -->
<description>Clock Tower for WonderSwan</description> <description>Clock Tower for WonderSwan</description>
<year>1999</year> <year>1999</year>
<publisher>Kaga Tech</publisher> <publisher>Kaga Tech</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-KGT002"/> <info name="serial" value="SWJ-KGT002"/>
<info name="release" value="19991209"/> <info name="release" value="19991209"/>
<info name="alt_title" value="クロックタワー フォー ワンダースワン"/> <info name="alt_title" value="クロックタワー フォー ワンダースワン"/>
@ -611,10 +611,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="dendego"> <software name="dendego">
<!-- Rev 1 -->
<description>Densha de Go!</description> <description>Densha de Go!</description>
<year>1999</year> <year>1999</year>
<publisher>Taito</publisher> <publisher>Taito</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-TAT001"/> <info name="serial" value="SWJ-TAT001"/>
<info name="release" value="19990304"/> <info name="release" value="19990304"/>
<info name="alt_title" value="電車でGO!"/> <info name="alt_title" value="電車でGO!"/>
@ -762,12 +762,11 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
--> -->
<!-- how to play? -->
<software name="digimon"> <software name="digimon">
<!-- Rev 1 -->
<description>Digital Monster - Ver. WonderSwan</description> <description>Digital Monster - Ver. WonderSwan</description>
<year>1999</year> <year>1999</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BAN005"/> <info name="serial" value="SWJ-BAN005"/>
<info name="release" value="19990325"/> <info name="release" value="19990325"/>
<info name="alt_title" value="デジタルモンスター バージョン ワンダースワン"/> <info name="alt_title" value="デジタルモンスター バージョン ワンダースワン"/>
@ -787,7 +786,6 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="digimon1" cloneof="digimon"> <software name="digimon1" cloneof="digimon">
<!-- Alt title: -->
<description>Digimon - Ver. WonderSwan (Asia)</description> <description>Digimon - Ver. WonderSwan (Asia)</description>
<year>19??</year> <year>19??</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
@ -980,10 +978,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="fireprow"> <software name="fireprow">
<!-- Rev 5 -->
<description>Fire Pro Wrestling for WonderSwan</description> <description>Fire Pro Wrestling for WonderSwan</description>
<year>2000</year> <year>2000</year>
<publisher>Kaga Tech</publisher> <publisher>Kaga Tech</publisher>
<notes>Revision from header: Rev 5</notes>
<info name="serial" value="SWJ-KGT007"/> <info name="serial" value="SWJ-KGT007"/>
<info name="release" value="20000831"/> <info name="release" value="20000831"/>
<info name="alt_title" value="ファイヤープロレスリング フォー ワンダースワン"/> <info name="alt_title" value="ファイヤープロレスリング フォー ワンダースワン"/>
@ -1063,10 +1061,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="gorakuta"> <software name="gorakuta">
<!-- Rev 2 -->
<description>Goraku Ou Tango!</description> <description>Goraku Ou Tango!</description>
<year>1999</year> <year>1999</year>
<publisher>Moebius</publisher> <publisher>Moebius</publisher>
<notes>Revision from header: Rev 2</notes>
<info name="serial" value="SWJ-PAW001"/> <info name="serial" value="SWJ-PAW001"/>
<info name="release" value="19990401"/> <info name="release" value="19990401"/>
<info name="alt_title" value="語楽王 タンゴ !"/> <info name="alt_title" value="語楽王 タンゴ !"/>
@ -1186,11 +1184,11 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</part> </part>
</software> </software>
<!-- background incorrect during bot transform? -->
<software name="harobots"> <software name="harobots">
<description>Harobots (Rev 1)</description> <description>Harobots (Rev 1)</description>
<year>1999</year> <year>1999</year>
<publisher>Sunrise Interactive</publisher> <publisher>Sunrise Interactive</publisher>
<notes>background incorrect during bot transform?</notes>
<info name="serial" value="SWJ-SRV001"/> <info name="serial" value="SWJ-SRV001"/>
<info name="release" value="19991007"/> <info name="release" value="19991007"/>
<info name="alt_title" value="ハロボッツ"/> <info name="alt_title" value="ハロボッツ"/>
@ -1339,10 +1337,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="kissyori"> <software name="kissyori">
<!-- Rev 2 -->
<description>Kiss Yori... - Seaside Serenade</description> <description>Kiss Yori... - Seaside Serenade</description>
<year>1999</year> <year>1999</year>
<publisher>Kid</publisher> <publisher>Kid</publisher>
<notes>Revision from header: Rev 2</notes>
<info name="serial" value="SWJ-KDX001"/> <info name="serial" value="SWJ-KDX001"/>
<info name="release" value="19991202"/> <info name="release" value="19991202"/>
<info name="alt_title" value="キスより... ~シーサイドセレナーデ~"/> <info name="alt_title" value="キスより... ~シーサイドセレナーデ~"/>
@ -1406,10 +1404,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="kyousoub"> <software name="kyousoub">
<!-- Rev 1 -->
<description>Kyousouba Ikusei Simulation - Keiba</description> <description>Kyousouba Ikusei Simulation - Keiba</description>
<year>1999</year> <year>1999</year>
<publisher>BEC</publisher> <publisher>BEC</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BEC001"/> <info name="serial" value="SWJ-BEC001"/>
<info name="release" value="19991118"/> <info name="release" value="19991118"/>
<info name="alt_title" value="競走馬育成シミュレーション ケイバ"/> <info name="alt_title" value="競走馬育成シミュレーション ケイバ"/>
@ -1429,10 +1427,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="langriss"> <software name="langriss">
<!-- Rev 1 -->
<description>Langrisser Millennium WS - The Last Century</description> <description>Langrisser Millennium WS - The Last Century</description>
<year>2000</year> <year>2000</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BAN024"/> <info name="serial" value="SWJ-BAN024"/>
<info name="release" value="20000309"/> <info name="release" value="20000309"/>
<info name="alt_title" value="ラングリッサーミレニアム WS The LastCentury"/> <info name="alt_title" value="ラングリッサーミレニアム WS The LastCentury"/>
@ -1516,11 +1514,11 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</part> </part>
</software> </software>
<!-- Small graphics glitch between 4th and 5th column -->
<software name="magdrop" supported="partial"> <software name="magdrop" supported="partial">
<description>Magical Drop for WonderSwan</description> <description>Magical Drop for WonderSwan</description>
<year>1999</year> <year>1999</year>
<publisher>Data East Corp.</publisher> <publisher>Data East Corp.</publisher>
<notes>Small graphics glitch between 4th and 5th column</notes>
<info name="serial" value="SWJ-DTE002"/> <info name="serial" value="SWJ-DTE002"/>
<info name="release" value="19991014"/> <info name="release" value="19991014"/>
<info name="alt_title" value="マジカルドロップ for ワンダースワン"/> <info name="alt_title" value="マジカルドロップ for ワンダースワン"/>
@ -1691,10 +1689,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="mingmagn"> <software name="mingmagn">
<!-- Rev 1 -->
<description>Mingle Magnet</description> <description>Mingle Magnet</description>
<year>1999</year> <year>1999</year>
<publisher>Hal Corporation</publisher> <publisher>Hal Corporation</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-HAL002"/> <info name="serial" value="SWJ-HAL002"/>
<info name="release" value="19991102"/> <info name="release" value="19991102"/>
<info name="alt_title" value="ミングルマグネット"/> <info name="alt_title" value="ミングルマグネット"/>
@ -1711,10 +1709,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="mjkiwame"> <software name="mjkiwame">
<!-- Rev 1 -->
<description>Pro Mahjong Kiwame for WonderSwan</description> <description>Pro Mahjong Kiwame for WonderSwan</description>
<year>1999</year> <year>1999</year>
<publisher>Athena</publisher> <publisher>Athena</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-ATN001"/> <info name="serial" value="SWJ-ATN001"/>
<info name="release" value="19991007"/> <info name="release" value="19991007"/>
<info name="alt_title" value="プロ麻雀 極 フォー ワンダースワン"/> <info name="alt_title" value="プロ麻雀 極 フォー ワンダースワン"/>
@ -1734,10 +1732,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="mjtetsu"> <software name="mjtetsu">
<!-- Rev 2 -->
<description>Nihon Pro Mahjong Renmei Kounin Tetsuman</description> <description>Nihon Pro Mahjong Renmei Kounin Tetsuman</description>
<year>1999</year> <year>1999</year>
<publisher>Kaga Tech</publisher> <publisher>Kaga Tech</publisher>
<notes>Revision from header: Rev 2</notes>
<info name="serial" value="SWJ-KGT001"/> <info name="serial" value="SWJ-KGT001"/>
<info name="release" value="19990715"/> <info name="release" value="19990715"/>
<info name="alt_title" value="日本プロ麻雀連盟公認 徹萬"/> <info name="alt_title" value="日本プロ麻雀連盟公認 徹萬"/>
@ -1756,12 +1754,11 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</part> </part>
</software> </software>
<!-- wondergate hardware is not emulated yet -->
<software name="mobilewg" supported="partial"> <software name="mobilewg" supported="partial">
<!-- Rev 1 -->
<description>MobileWonderGate (Rev 1)</description> <description>MobileWonderGate (Rev 1)</description>
<year>19??</year> <year>19??</year>
<publisher>&lt;unknown&gt;</publisher> <publisher>&lt;unknown&gt;</publisher>
<notes>wondergate hardware is not emulated yet</notes>
<info name="serial" value="SWJ-SCC001"/> <info name="serial" value="SWJ-SCC001"/>
<part name="cart" interface="wswan_cart"> <part name="cart" interface="wswan_cart">
<feature name="pcb" value="PTS-0110 or PTS-0105" /> <feature name="pcb" value="PTS-0110 or PTS-0105" />
@ -1866,10 +1863,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="niceon"> <software name="niceon">
<!-- Rev 1 -->
<description>Nice On</description> <description>Nice On</description>
<year>1999</year> <year>1999</year>
<publisher>Sammy</publisher> <publisher>Sammy</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-SUM002"/> <info name="serial" value="SWJ-SUM002"/>
<info name="release" value="19990408"/> <info name="release" value="19990408"/>
<info name="alt_title" value="ナイスオン"/> <info name="alt_title" value="ナイスオン"/>
@ -2060,6 +2057,7 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
<description>Ring Infinity (alt)</description> <description>Ring Infinity (alt)</description>
<year>2000</year> <year>2000</year>
<publisher>Kid</publisher> <publisher>Kid</publisher>
<notes>The roms in this are a simple split of mh32m16e119b.u3. It needs to be verified whether this is correct.</notes>
<info name="serial" value="SWJ-KDK001"/> <info name="serial" value="SWJ-KDK001"/>
<info name="release" value="20000810"/> <info name="release" value="20000810"/>
<info name="alt_title" value="リング インフィニティ"/> <info name="alt_title" value="リング インフィニティ"/>
@ -2071,7 +2069,6 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
<feature name="u5" value="ROM (on PTS-0120)" /> <feature name="u5" value="ROM (on PTS-0120)" />
<feature name="slot" value="ws_eeprom" /> <feature name="slot" value="ws_eeprom" />
<dataarea name="rom" size="4194304" width="16" endianness="little"> <dataarea name="rom" size="4194304" width="16" endianness="little">
<!-- these roms are a simple split of mh32m16e119b.u3. Need to be verified -->
<rom name="mh16m16e114b.u4" size="2097152" crc="1bed45b0" sha1="46eff2164d8fccac161b0fd1cde8098e3bc08fd6" offset="000000" status="baddump" /> <rom name="mh16m16e114b.u4" size="2097152" crc="1bed45b0" sha1="46eff2164d8fccac161b0fd1cde8098e3bc08fd6" offset="000000" status="baddump" />
<rom name="mh16m16e115b.u5" size="2097152" crc="baeb4a36" sha1="d5d8220dadc41e5dbaa13ac188d642dacbed68c3" offset="2097152" status="baddump" /> <rom name="mh16m16e115b.u5" size="2097152" crc="baeb4a36" sha1="d5d8220dadc41e5dbaa13ac188d642dacbed68c3" offset="2097152" status="baddump" />
</dataarea> </dataarea>
@ -2212,15 +2209,15 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</part> </part>
</software> </software>
<!--
The Robot Works cartridge has an integrated infrared port for programming an
external robot (the Wonder Borg).
The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped).
-->
<software name="robworks" supported="partial"> <software name="robworks" supported="partial">
<description>Wonder Borg Robot Works</description> <description>Wonder Borg Robot Works</description>
<year>2000</year> <year>2000</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<notes><![CDATA[
The Robot Works cartridge has an integrated infrared port for programming an
external robot (the Wonder Borg).
The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped).
]]></notes>
<info name="serial" value="SWJ-BAN033"/> <info name="serial" value="SWJ-BAN033"/>
<info name="release" value="20000804"/> <info name="release" value="20000804"/>
<info name="alt_title" value="ワンダーボーグ 完"/> <info name="alt_title" value="ワンダーボーグ 完"/>
@ -2240,17 +2237,20 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</part> </part>
</software> </software>
<!--
The Robot Works cartridge has an integrated infrared port for programming an
external robot (the Wonder Borg).
The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped).
-->
<software name="robworks1" cloneof="robworks" supported="partial"> <software name="robworks1" cloneof="robworks" supported="partial">
<!-- Rev 1 -->
<description>Robot Works (Asia)</description> <description>Robot Works (Asia)</description>
<year>2000</year> <year>2000</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<info name="serial" value="SWJ-BAN033"/> <!-- Same ROM as cart SWJ-BAN034 (labeled "Ver.1.5") --> <notes><![CDATA[
Revision from header: Rev 1
Same ROM as cart SWJ-BAN034 (labeled "Ver.1.5")
The Robot Works cartridge has an integrated infrared port for programming an
external robot (the Wonder Borg).
The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped).
]]></notes>
<info name="serial" value="SWJ-BAN033"/>
<info name="release" value="20000804"/> <info name="release" value="20000804"/>
<info name="alt_title" value="ワンダーボーグ 完"/> <info name="alt_title" value="ワンダーボーグ 完"/>
<part name="cart" interface="wswan_cart"> <part name="cart" interface="wswan_cart">
@ -2506,10 +2506,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="sprowres"> <software name="sprowres">
<!-- Rev 1 -->
<description>Shin Nihon Pro Wrestling Toukon Retsuden</description> <description>Shin Nihon Pro Wrestling Toukon Retsuden</description>
<year>1999</year> <year>1999</year>
<publisher>Tomy</publisher> <publisher>Tomy</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-TMY001"/> <info name="serial" value="SWJ-TMY001"/>
<info name="release" value="19990304"/> <info name="release" value="19990304"/>
<info name="alt_title" value="新日本プロレスリング 闘魂烈伝"/> <info name="alt_title" value="新日本プロレスリング 闘魂烈伝"/>
@ -2609,10 +2609,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="sotsugyo"> <software name="sotsugyo">
<!-- Rev 1 -->
<description>Sotsugyou for WonderSwan</description> <description>Sotsugyou for WonderSwan</description>
<year>1999</year> <year>1999</year>
<publisher>Bandai Visual</publisher> <publisher>Bandai Visual</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BVL002"/> <info name="serial" value="SWJ-BVL002"/>
<info name="release" value="19991216"/> <info name="release" value="19991216"/>
<info name="alt_title" value="卒業 フォー ワンダースワン"/> <info name="alt_title" value="卒業 フォー ワンダースワン"/>
@ -2695,10 +2695,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="tanjodeb"> <software name="tanjodeb">
<!-- Rev 1 -->
<description>Tanjou Debut for WonderSwan</description> <description>Tanjou Debut for WonderSwan</description>
<year>2000</year> <year>2000</year>
<publisher>Bandai Visual</publisher> <publisher>Bandai Visual</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BVL003"/> <info name="serial" value="SWJ-BVL003"/>
<info name="release" value="20000224"/> <info name="release" value="20000224"/>
<info name="alt_title" value="誕生 デビュー フォー ワンダースワン"/> <info name="alt_title" value="誕生 デビュー フォー ワンダースワン"/>
@ -2848,10 +2848,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="trumpcl2"> <software name="trumpcl2">
<!-- Rev 1 -->
<description>Trump Collection 2 - Bottom-Up Teki Sekaiisshuu no Tabi</description> <description>Trump Collection 2 - Bottom-Up Teki Sekaiisshuu no Tabi</description>
<year>2000</year> <year>2000</year>
<publisher>Bottom Up</publisher> <publisher>Bottom Up</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BTM002"/> <info name="serial" value="SWJ-BTM002"/>
<info name="release" value="20000928"/> <info name="release" value="20000928"/>
<info name="alt_title" value="トランプコレクション ボトムアップ的トランプ生活"/> <info name="alt_title" value="トランプコレクション ボトムアップ的トランプ生活"/>
@ -2868,10 +2868,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="trumpcol"> <software name="trumpcol">
<!-- Rev 1 -->
<description>Trump Collection - Bottom-Up Teki Trump Seikatsu</description> <description>Trump Collection - Bottom-Up Teki Trump Seikatsu</description>
<year>1999</year> <year>1999</year>
<publisher>Bottom Up</publisher> <publisher>Bottom Up</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BTM001"/> <info name="serial" value="SWJ-BTM001"/>
<info name="release" value="19990701"/> <info name="release" value="19990701"/>
<info name="alt_title" value="トランプコレクション2 ボトムアップ的世界一周の旅"/> <info name="alt_title" value="トランプコレクション2 ボトムアップ的世界一周の旅"/>
@ -2928,10 +2928,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="uzumaki"> <software name="uzumaki">
<!-- Rev 4 -->
<description>Uzumaki - Denshi Kaiki Hen</description> <description>Uzumaki - Denshi Kaiki Hen</description>
<year>2000</year> <year>2000</year>
<publisher>Omage Micott, Inc.</publisher> <publisher>Omage Micott, Inc.</publisher>
<notes>Revision from header: Rev 4</notes>
<info name="serial" value="SWJ-OMM001"/> <info name="serial" value="SWJ-OMM001"/>
<info name="release" value="20000203"/> <info name="release" value="20000203"/>
<info name="alt_title" value="うずまき ~電視怪奇篇~"/> <info name="alt_title" value="うずまき ~電視怪奇篇~"/>
@ -2950,10 +2950,10 @@ The GIZA chip used on a lot of cartridges is a sram voltage switch.
</software> </software>
<software name="vaitzbla"> <software name="vaitzbla">
<!-- Rev 1 -->
<description>Vaitz Blade</description> <description>Vaitz Blade</description>
<year>1999</year> <year>1999</year>
<publisher>Bandai</publisher> <publisher>Bandai</publisher>
<notes>Revision from header: Rev 1</notes>
<info name="serial" value="SWJ-BAN00C"/> <info name="serial" value="SWJ-BAN00C"/>
<info name="release" value="19990624"/> <info name="release" value="19990624"/>
<info name="alt_title" value="ヴァイツブレイド"/> <info name="alt_title" value="ヴァイツブレイド"/>

View File

@ -32,6 +32,7 @@ class SchemaQueries(object):
' id INTEGER PRIMARY KEY,\n' \ ' id INTEGER PRIMARY KEY,\n' \
' shortname TEXT NOT NULL,\n' \ ' shortname TEXT NOT NULL,\n' \
' description TEXT NOT NULL,\n' \ ' description TEXT NOT NULL,\n' \
' notes TEXT NULL,\n' \
' UNIQUE (shortname ASC))' ' UNIQUE (shortname ASC))'
CREATE_SOFTWARE = \ CREATE_SOFTWARE = \
'CREATE TABLE software (\n' \ 'CREATE TABLE software (\n' \
@ -42,6 +43,7 @@ class SchemaQueries(object):
' description TEXT NOT NULL,\n' \ ' description TEXT NOT NULL,\n' \
' year TEXT NOT NULL,\n' \ ' year TEXT NOT NULL,\n' \
' publisher TEXT NOT NULL,\n' \ ' publisher TEXT NOT NULL,\n' \
' notes TEXT NULL,\n' \
' UNIQUE (softwarelist ASC, shortname ASC),\n' \ ' UNIQUE (softwarelist ASC, shortname ASC),\n' \
' FOREIGN KEY (softwarelist) REFERENCES softwarelist (id))' ' FOREIGN KEY (softwarelist) REFERENCES softwarelist (id))'
CREATE_SOFTWARECLONEOF = \ CREATE_SOFTWARECLONEOF = \
@ -505,6 +507,8 @@ class UpdateQueries(object):
ADD_SOFTWARESHAREDFEAT = 'INSERT INTO softwaresharedfeat (software, sharedfeattype, value) SELECT ?, id, ? FROM softwaresharedfeattype WHERE name = ?' ADD_SOFTWARESHAREDFEAT = 'INSERT INTO softwaresharedfeat (software, sharedfeattype, value) SELECT ?, id, ? FROM softwaresharedfeattype WHERE name = ?'
ADD_SOFTWAREPART = 'INSERT INTO softwarepart (software, shortname, interface) VALUES (?, ?, ?)' ADD_SOFTWAREPART = 'INSERT INTO softwarepart (software, shortname, interface) VALUES (?, ?, ?)'
ADD_SOFTWAREPARTFEATURE = 'INSERT INTO softwarepartfeature (part, featuretype, value) SELECT ?, id, ? FROM softwarepartfeaturetype WHERE name = ?' ADD_SOFTWAREPARTFEATURE = 'INSERT INTO softwarepartfeature (part, featuretype, value) SELECT ?, id, ? FROM softwarepartfeaturetype WHERE name = ?'
UPDATE_SOFTWARELIST_NOTES = 'UPDATE softwarelist SET notes = ? WHERE id = ?'
UPDATE_SOFTWARE_NOTES = 'UPDATE software SET notes = ? WHERE id = ?'
# machines # machines
ADD_FEATURETYPE = 'INSERT OR IGNORE INTO featuretype (name) VALUES (?)' ADD_FEATURETYPE = 'INSERT OR IGNORE INTO featuretype (name) VALUES (?)'
@ -773,7 +777,7 @@ class QueryCursor(object):
def get_machine_softwarelists(self, machine): def get_machine_softwarelists(self, machine):
return self.dbcurs.execute( return self.dbcurs.execute(
'SELECT machinesoftwarelist.tag AS tag, machinesoftwareliststatustype.value AS status, softwarelist.shortname AS shortname, softwarelist.description AS description, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \ 'SELECT machinesoftwarelist.tag AS tag, machinesoftwareliststatustype.value AS status, softwarelist.shortname AS shortname, softwarelist.description AS description, softwarelist.notes AS notes, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \
'FROM machinesoftwarelist LEFT JOIN machinesoftwareliststatustype ON machinesoftwarelist.status = machinesoftwareliststatustype.id LEFT JOIN softwarelist ON machinesoftwarelist.softwarelist = softwarelist.id LEFT JOIN software ON softwarelist.id = software.softwarelist ' \ 'FROM machinesoftwarelist LEFT JOIN machinesoftwareliststatustype ON machinesoftwarelist.status = machinesoftwareliststatustype.id LEFT JOIN softwarelist ON machinesoftwarelist.softwarelist = softwarelist.id LEFT JOIN software ON softwarelist.id = software.softwarelist ' \
'WHERE machinesoftwarelist.machine = ? ' \ 'WHERE machinesoftwarelist.machine = ? ' \
'GROUP BY machinesoftwarelist.id', 'GROUP BY machinesoftwarelist.id',
@ -785,14 +789,14 @@ class QueryCursor(object):
def get_softwarelist_details(self, shortname, pattern): def get_softwarelist_details(self, shortname, pattern):
if pattern is not None: if pattern is not None:
return self.dbcurs.execute( return self.dbcurs.execute(
'SELECT softwarelist.id AS id, softwarelist.shortname AS shortname, softwarelist.description AS description, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \ 'SELECT softwarelist.id AS id, softwarelist.shortname AS shortname, softwarelist.description AS description, softwarelist.notes AS notes, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \
'FROM softwarelist LEFT JOIN software ON softwarelist.id = software.softwarelist ' \ 'FROM softwarelist LEFT JOIN software ON softwarelist.id = software.softwarelist ' \
'WHERE softwarelist.shortname = ? AND software.shortname GLOB ? ' \ 'WHERE softwarelist.shortname = ? AND software.shortname GLOB ? ' \
'GROUP BY softwarelist.id', 'GROUP BY softwarelist.id',
(shortname, pattern)) (shortname, pattern))
else: else:
return self.dbcurs.execute( return self.dbcurs.execute(
'SELECT softwarelist.id AS id, softwarelist.shortname AS shortname, softwarelist.description AS description, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \ 'SELECT softwarelist.id AS id, softwarelist.shortname AS shortname, softwarelist.description AS description, softwarelist.notes AS notes, COUNT(software.id) AS total, COUNT(CASE software.supported WHEN 0 THEN 1 ELSE NULL END) AS supported, COUNT(CASE software.supported WHEN 1 THEN 1 ELSE NULL END) AS partiallysupported, COUNT(CASE software.supported WHEN 2 THEN 1 ELSE NULL END) AS unsupported ' \
'FROM softwarelist LEFT JOIN software ON softwarelist.id = software.softwarelist ' \ 'FROM softwarelist LEFT JOIN software ON softwarelist.id = software.softwarelist ' \
'WHERE softwarelist.shortname = ? ' \ 'WHERE softwarelist.shortname = ? ' \
'GROUP BY softwarelist.id', 'GROUP BY softwarelist.id',
@ -836,7 +840,7 @@ class QueryCursor(object):
def get_software_details(self, softwarelist, software): def get_software_details(self, softwarelist, software):
return self.dbcurs.execute( return self.dbcurs.execute(
'SELECT software.id AS id, software.shortname AS shortname, software.supported AS supported, software.description AS description, software.year AS year, software.publisher AS publisher, softwarelist.shortname AS softwarelist, softwarelist.description AS softwarelistdescription, parent.shortname AS parent, parent.description AS parentdescription, parentsoftwarelist.shortname AS parentsoftwarelist, parentsoftwarelist.description AS parentsoftwarelistdescription ' \ 'SELECT software.id AS id, software.shortname AS shortname, software.supported AS supported, software.description AS description, software.year AS year, software.publisher AS publisher, software.notes AS notes, softwarelist.shortname AS softwarelist, softwarelist.description AS softwarelistdescription, parent.shortname AS parent, parent.description AS parentdescription, parentsoftwarelist.shortname AS parentsoftwarelist, parentsoftwarelist.description AS parentsoftwarelistdescription ' \
'FROM software LEFT JOIN softwarelist ON software.softwarelist = softwarelist.id LEFT JOIN softwarecloneof ON software.id = softwarecloneof.id LEFT JOIN software AS parent ON softwarecloneof.parent = parent.id LEFT JOIN softwarelist AS parentsoftwarelist ON parent.softwarelist = parentsoftwarelist.id ' \ 'FROM software LEFT JOIN softwarelist ON software.softwarelist = softwarelist.id LEFT JOIN softwarecloneof ON software.id = softwarecloneof.id LEFT JOIN software AS parent ON softwarecloneof.parent = parent.id LEFT JOIN softwarelist AS parentsoftwarelist ON parent.softwarelist = parentsoftwarelist.id ' \
'WHERE software.softwarelist = (SELECT id FROM softwarelist WHERE shortname = ?) AND software.shortname = ?', 'WHERE software.softwarelist = (SELECT id FROM softwarelist WHERE shortname = ?) AND software.shortname = ?',
(softwarelist, software)) (softwarelist, software))
@ -912,6 +916,9 @@ class UpdateCursor(object):
self.dbcurs.execute(UpdateQueries.ADD_SOFTWARELIST, (shortname, description)) self.dbcurs.execute(UpdateQueries.ADD_SOFTWARELIST, (shortname, description))
return self.dbcurs.lastrowid return self.dbcurs.lastrowid
def update_softwarelist_notes(self, id, notes):
self.dbcurs.execute(UpdateQueries.UPDATE_SOFTWARELIST_NOTES, (notes, id))
def add_softwareinfotype(self, name): def add_softwareinfotype(self, name):
self.dbcurs.execute(UpdateQueries.ADD_SOFTWAREINFOTYPE, (name, )) self.dbcurs.execute(UpdateQueries.ADD_SOFTWAREINFOTYPE, (name, ))
@ -925,6 +932,9 @@ class UpdateCursor(object):
self.dbcurs.execute(UpdateQueries.ADD_SOFTWARE, (softwarelist, shortname, supported, description, year, publisher)) self.dbcurs.execute(UpdateQueries.ADD_SOFTWARE, (softwarelist, shortname, supported, description, year, publisher))
return self.dbcurs.lastrowid return self.dbcurs.lastrowid
def update_software_notes(self, id, notes):
self.dbcurs.execute(UpdateQueries.UPDATE_SOFTWARE_NOTES, (notes, id))
def add_softwarecloneof(self, software, parent): def add_softwarecloneof(self, software, parent):
self.dbcurs.execute(UpdateQueries.ADD_TEMPORARY_SOFTWARECLONEOF, (software, parent)) self.dbcurs.execute(UpdateQueries.ADD_TEMPORARY_SOFTWARECLONEOF, (software, parent))
return self.dbcurs.lastrowid return self.dbcurs.lastrowid

View File

@ -258,6 +258,10 @@ SOFTWARE_PROLOGUE = string.Template(
' <tr><th>Year:</th><td>${year}</td></tr>\n' \ ' <tr><th>Year:</th><td>${year}</td></tr>\n' \
' <tr><th>Publisher:</th><td>${publisher}</td></tr>\n'); ' <tr><th>Publisher:</th><td>${publisher}</td></tr>\n');
SOFTWARE_EPILOGUE = string.Template(
'<h2>Notes</h2>\n' \
'<p><pre>${notes}<p></pre>\n');
SOFTWARE_CLONES_PROLOGUE = string.Template( SOFTWARE_CLONES_PROLOGUE = string.Template(
'<h2 id="heading-clones">Clones</h2>\n' \ '<h2 id="heading-clones">Clones</h2>\n' \
'<table id="tbl-clones">\n' \ '<table id="tbl-clones">\n' \
@ -328,6 +332,10 @@ SOFTWARELIST_PROLOGUE = string.Template(
' </tr>\n' \ ' </tr>\n' \
'</table>\n') '</table>\n')
SOFTWARELIST_EPILOGUE = string.Template(
'<h2>Notes</h2>\n' \
'<p><pre>${notes}<p></pre>\n')
SOFTWARELIST_MACHINE_TABLE_HEADER = string.Template( SOFTWARELIST_MACHINE_TABLE_HEADER = string.Template(
'<h2 id="heading-machines">Machines</h2>\n' \ '<h2 id="heading-machines">Machines</h2>\n' \
'<table id="tbl-machines">\n' \ '<table id="tbl-machines">\n' \

View File

@ -352,6 +352,7 @@ class SoftwareHandler(ElementHandler):
'description': TextAccumulator, 'description': TextAccumulator,
'year': TextAccumulator, 'year': TextAccumulator,
'publisher': TextAccumulator, 'publisher': TextAccumulator,
'notes': TextAccumulator,
'part': SoftwarePartHandler } 'part': SoftwarePartHandler }
def __init__(self, parent, **kwargs): def __init__(self, parent, **kwargs):
@ -389,6 +390,9 @@ class SoftwareHandler(ElementHandler):
self.id = self.dbcurs.add_software(self.softwarelist, self.shortname, self.supported, self.description, self.year, self.publisher) self.id = self.dbcurs.add_software(self.softwarelist, self.shortname, self.supported, self.description, self.year, self.publisher)
if self.cloneof is not None: if self.cloneof is not None:
self.dbcurs.add_softwarecloneof(self.id, self.cloneof) self.dbcurs.add_softwarecloneof(self.id, self.cloneof)
elif name == 'notes':
self.notes = handler.text
self.dbcurs.update_software_notes(self.id, self.notes)
class SoftwareListHandler(ElementHandler): class SoftwareListHandler(ElementHandler):
@ -410,24 +414,34 @@ class SoftwareListHandler(ElementHandler):
locator=self.locator) locator=self.locator)
self.shortname = attrs['name'] self.shortname = attrs['name']
self.description = attrs['description'] self.description = attrs['description']
self.notes = None
self.entries = 0 self.entries = 0
dbcurs = self.dbconn.cursor() dbcurs = self.dbconn.cursor()
self.id = dbcurs.add_softwarelist(self.shortname, self.description) self.id = dbcurs.add_softwarelist(self.shortname, self.description)
dbcurs.close() dbcurs.close()
def endMainElement(self, name): def endMainElement(self, name):
if self.notes:
dbcurs = self.dbconn.cursor()
dbcurs.update_softwarelist_notes(self.id, self.notes)
dbcurs.close()
self.dbconn.commit() self.dbconn.commit()
def startChildElement(self, name, attrs): def startChildElement(self, name, attrs):
if name != 'software': if name == 'notes':
self.setChildHandler(name, attrs, TextAccumulator(self))
elif name == 'software':
self.setChildHandler(name, attrs, SoftwareHandler(self))
else:
raise xml.sax.SAXParseException( raise xml.sax.SAXParseException(
msg=('Expected "software" element but found "%s"' % (name, )), msg=('Expected "software" element but found "%s"' % (name, )),
exception=None, exception=None,
locator=self.locator) locator=self.locator)
self.setChildHandler(name, attrs, SoftwareHandler(self))
def endChildHandler(self, name, handler): def endChildHandler(self, name, handler):
if name == 'software': if name == 'notes':
self.notes = handler.text
elif name == 'software':
if self.entries >= 1023: if self.entries >= 1023:
self.dbconn.commit() self.dbconn.commit()
self.entries = 0 self.entries = 0

View File

@ -689,6 +689,9 @@ class SoftwareListHandler(QueryPageHandler):
yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-software').encode('utf-8') yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-software').encode('utf-8')
yield '<script>make_collapsible(document.getElementById("heading-software"), document.getElementById("tbl-software"));</script>\n'.encode('utf-8') yield '<script>make_collapsible(document.getElementById("heading-software"), document.getElementById("tbl-software"));</script>\n'.encode('utf-8')
if (softwarelist_info['notes']):
yield htmltmpl.SOFTWARELIST_EPILOGUE.substitute(notes=htmlescape(softwarelist_info['notes'])).encode('utf-8')
yield '</body>\n</html>\n'.encode('utf-8') yield '</body>\n</html>\n'.encode('utf-8')
def software_page(self, software_info): def software_page(self, software_info):
@ -733,6 +736,9 @@ class SoftwareListHandler(QueryPageHandler):
yield (' <tr><th>%s:</th><td>%s</td>\n' % (htmlescape(name), htmlescape(value))).encode('utf-8') yield (' <tr><th>%s:</th><td>%s</td>\n' % (htmlescape(name), htmlescape(value))).encode('utf-8')
yield '</table>\n\n'.encode('utf-8') yield '</table>\n\n'.encode('utf-8')
if (software_info['notes']):
yield htmltmpl.SOFTWARE_EPILOGUE.substitute(notes=htmlescape(software_info['notes'])).encode('utf-8')
yield '</body>\n</html>\n'.encode('utf-8') yield '</body>\n</html>\n'.encode('utf-8')
def software_row(self, software_info): def software_row(self, software_info):

View File

@ -196,6 +196,7 @@ public:
std::string_view filename, std::string_view filename,
std::string &listname, std::string &listname,
std::string &description, std::string &description,
std::string &notes,
std::list<software_info> &infolist, std::list<software_info> &infolist,
std::ostream &errors); std::ostream &errors);
@ -236,6 +237,7 @@ private:
void parse_soft_start(const char *tagname, const char **attributes); void parse_soft_start(const char *tagname, const char **attributes);
void parse_part_start(const char *tagname, const char **attributes); void parse_part_start(const char *tagname, const char **attributes);
void parse_data_start(const char *tagname, const char **attributes); void parse_data_start(const char *tagname, const char **attributes);
void parse_main_end(const char *tagname);
void parse_soft_end(const char *name); void parse_soft_end(const char *name);
// internal parsing state // internal parsing state
@ -245,6 +247,7 @@ private:
struct XML_ParserStruct * m_parser; struct XML_ParserStruct * m_parser;
std::string & m_listname; std::string & m_listname;
std::string & m_description; std::string & m_description;
std::string & m_notes;
bool m_data_accum_expected; bool m_data_accum_expected;
std::string m_data_accum; std::string m_data_accum;
software_info * m_current_info; software_info * m_current_info;
@ -262,6 +265,7 @@ softlist_parser::softlist_parser(
std::string_view filename, std::string_view filename,
std::string &listname, std::string &listname,
std::string &description, std::string &description,
std::string &notes,
std::list<software_info> &infolist, std::list<software_info> &infolist,
std::ostream &errors) : std::ostream &errors) :
m_filename(filename), m_filename(filename),
@ -269,6 +273,7 @@ softlist_parser::softlist_parser(
m_errors(errors), m_errors(errors),
m_listname(listname), m_listname(listname),
m_description(description), m_description(description),
m_notes(notes),
m_data_accum_expected(false), m_data_accum_expected(false),
m_current_info(nullptr), m_current_info(nullptr),
m_current_part(nullptr), m_current_part(nullptr),
@ -472,6 +477,7 @@ void softlist_parser::end_handler(void *data, const char *name)
break; break;
case POS_MAIN: case POS_MAIN:
state->parse_main_end(name);
state->m_current_info = nullptr; state->m_current_info = nullptr;
break; break;
@ -563,13 +569,25 @@ void softlist_parser::parse_main_start(const char *tagname, const char **attribu
else else
parse_error("No name defined for item"); parse_error("No name defined for item");
} }
// <notes>
else if (strcmp(tagname, "notes") == 0)
{
m_data_accum_expected = true;
}
else else
unknown_tag(tagname); unknown_tag(tagname);
} }
void softlist_parser::parse_main_end(const char *tagname)
{
if (strcmp(tagname, "notes") == 0)
m_notes = m_data_accum;
}
//------------------------------------------------- //-------------------------------------------------
// parse_main_start - handle tag start within // parse_soft_start - handle tag start within
// a software tag // a software tag
//------------------------------------------------- //-------------------------------------------------
@ -594,6 +612,10 @@ void softlist_parser::parse_soft_start(const char *tagname, const char **attribu
else if (strcmp(tagname, "publisher") == 0) else if (strcmp(tagname, "publisher") == 0)
m_data_accum_expected = true; m_data_accum_expected = true;
// <notes>
else if (strcmp(tagname, "notes") == 0)
m_data_accum_expected = true;
// <info name='' value=''> // <info name='' value=''>
else if (strcmp(tagname, "info") == 0) else if (strcmp(tagname, "info") == 0)
{ {
@ -859,6 +881,10 @@ void softlist_parser::parse_soft_end(const char *tagname)
else if (strcmp(tagname, "publisher") == 0) else if (strcmp(tagname, "publisher") == 0)
m_current_info->m_publisher = m_data_accum; m_current_info->m_publisher = m_data_accum;
// <notes>
else if (strcmp(tagname, "notes") == 0)
m_current_info->m_notes = m_data_accum;
// </part> // </part>
else if (strcmp(tagname, "part") == 0) else if (strcmp(tagname, "part") == 0)
{ {
@ -887,10 +913,11 @@ void parse_software_list(
std::string_view filename, std::string_view filename,
std::string &listname, std::string &listname,
std::string &description, std::string &description,
std::string &notes,
std::list<software_info> &infolist, std::list<software_info> &infolist,
std::ostream &errors) std::ostream &errors)
{ {
detail::softlist_parser(file, filename, listname, description, infolist, errors); detail::softlist_parser(file, filename, listname, description, notes, infolist, errors);
} }

View File

@ -120,6 +120,7 @@ public:
const std::string &parentname() const { return m_parentname; } const std::string &parentname() const { return m_parentname; }
const std::string &year() const { return m_year; } const std::string &year() const { return m_year; }
const std::string &publisher() const { return m_publisher; } const std::string &publisher() const { return m_publisher; }
const std::string &notes() const { return m_notes; }
const std::list<feature_list_item> &other_info() const { return m_other_info; } const std::list<feature_list_item> &other_info() const { return m_other_info; }
const std::list<feature_list_item> &shared_info() const { return m_shared_info; } const std::list<feature_list_item> &shared_info() const { return m_shared_info; }
software_support supported() const { return m_supported; } software_support supported() const { return m_supported; }
@ -137,6 +138,7 @@ private:
std::string m_parentname; std::string m_parentname;
std::string m_year; // Copyright year on title screen, actual release dates can be tracked in external resources std::string m_year; // Copyright year on title screen, actual release dates can be tracked in external resources
std::string m_publisher; std::string m_publisher;
std::string m_notes;
std::list<feature_list_item> m_other_info; // Here we store info like developer, serial #, etc. which belong to the software entry as a whole std::list<feature_list_item> m_other_info; // Here we store info like developer, serial #, etc. which belong to the software entry as a whole
std::list<feature_list_item> m_shared_info; // Here we store info like TV standard compatibility, or add-on requirements, etc. which get inherited std::list<feature_list_item> m_shared_info; // Here we store info like TV standard compatibility, or add-on requirements, etc. which get inherited
// by each part of this software entry (after loading these are stored in partdata->featurelist) // by each part of this software entry (after loading these are stored in partdata->featurelist)
@ -152,6 +154,7 @@ void parse_software_list(
std::string_view filename, std::string_view filename,
std::string &listname, std::string &listname,
std::string &description, std::string &description,
std::string &notes,
std::list<software_info> &infolist, std::list<software_info> &infolist,
std::ostream &errors); std::ostream &errors);

View File

@ -89,7 +89,8 @@ software_list_device::software_list_device(const machine_config &mconfig, const
m_list_type(softlist_type::ORIGINAL_SYSTEM), m_list_type(softlist_type::ORIGINAL_SYSTEM),
m_filter(nullptr), m_filter(nullptr),
m_parsed(false), m_parsed(false),
m_description("") m_description(""),
m_notes("")
{ {
} }
@ -180,6 +181,7 @@ void software_list_device::release()
m_filename.clear(); m_filename.clear();
m_shortname.clear(); m_shortname.clear();
m_description.clear(); m_description.clear();
m_notes.clear();
m_errors.clear(); m_errors.clear();
m_infolist.clear(); m_infolist.clear();
} }
@ -294,7 +296,7 @@ void software_list_device::parse()
{ {
// parse if no error // parse if no error
std::ostringstream errs; std::ostringstream errs;
parse_software_list(file, m_filename, m_shortname, m_description, m_infolist, errs); parse_software_list(file, m_filename, m_shortname, m_description, m_notes, m_infolist, errs);
file.close(); file.close();
m_errors = errs.str(); m_errors = errs.str();
} }

View File

@ -116,6 +116,7 @@ public:
// getters that may trigger a parse // getters that may trigger a parse
const std::string &description() { if (!m_parsed) parse(); return m_description; } const std::string &description() { if (!m_parsed) parse(); return m_description; }
const std::string &notes() { if (!m_parsed) parse(); return m_notes; }
bool valid() { if (!m_parsed) parse(); return !m_infolist.empty(); } bool valid() { if (!m_parsed) parse(); return !m_infolist.empty(); }
const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); } const char *errors_string() { if (!m_parsed) parse(); return m_errors.c_str(); }
const std::list<software_info> &get_info() { if (!m_parsed) parse(); return m_infolist; } const std::list<software_info> &get_info() { if (!m_parsed) parse(); return m_infolist; }
@ -152,6 +153,7 @@ private:
std::string m_filename; std::string m_filename;
std::string m_shortname; std::string m_shortname;
std::string m_description; std::string m_description;
std::string m_notes;
std::string m_errors; std::string m_errors;
std::list<software_info> m_infolist; std::list<software_info> m_infolist;
}; };

View File

@ -1059,16 +1059,18 @@ const char cli_frontend::s_softlist_xml_dtd[] =
"<?xml version=\"1.0\"?>\n" \ "<?xml version=\"1.0\"?>\n" \
"<!DOCTYPE softwarelists [\n" \ "<!DOCTYPE softwarelists [\n" \
"<!ELEMENT softwarelists (softwarelist*)>\n" \ "<!ELEMENT softwarelists (softwarelist*)>\n" \
"\t<!ELEMENT softwarelist (software+)>\n" \ "\t<!ELEMENT softwarelist (notes?, software+)>\n" \
"\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" \ "\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" \
"\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" \ "\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" \
"\t\t<!ELEMENT software (description, year, publisher, info*, sharedfeat*, part*)>\n" \ "\t\t<!ELEMENT notes (#PCDATA)>\n" \
"\t\t<!ELEMENT software (description, year, publisher, notes?, info*, sharedfeat*, part*)>\n" \
"\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" \ "\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" \
"\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" \ "\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" \
"\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" \ "\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" \
"\t\t\t<!ELEMENT description (#PCDATA)>\n" \ "\t\t\t<!ELEMENT description (#PCDATA)>\n" \
"\t\t\t<!ELEMENT year (#PCDATA)>\n" \ "\t\t\t<!ELEMENT year (#PCDATA)>\n" \
"\t\t\t<!ELEMENT publisher (#PCDATA)>\n" \ "\t\t\t<!ELEMENT publisher (#PCDATA)>\n" \
"\t\t\t<!ELEMENT notes (#PCDATA)>\n" \
"\t\t\t<!ELEMENT info EMPTY>\n" \ "\t\t\t<!ELEMENT info EMPTY>\n" \
"\t\t\t\t<!ATTLIST info name CDATA #REQUIRED>\n" \ "\t\t\t\t<!ATTLIST info name CDATA #REQUIRED>\n" \
"\t\t\t\t<!ATTLIST info value CDATA #IMPLIED>\n" \ "\t\t\t\t<!ATTLIST info value CDATA #IMPLIED>\n" \
@ -1116,6 +1118,8 @@ const char cli_frontend::s_softlist_xml_dtd[] =
void cli_frontend::output_single_softlist(std::ostream &out, software_list_device &swlistdev) void cli_frontend::output_single_softlist(std::ostream &out, software_list_device &swlistdev)
{ {
util::stream_format(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), util::xml::normalize_string(swlistdev.description().c_str())); util::stream_format(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlistdev.list_name(), util::xml::normalize_string(swlistdev.description().c_str()));
if (!swlistdev.notes().empty())
util::stream_format(out, "\t\t<notes>%s</notes>\n", util::xml::normalize_string(swlistdev.notes().c_str()));
for (const software_info &swinfo : swlistdev.get_info()) for (const software_info &swinfo : swlistdev.get_info())
{ {
util::stream_format(out, "\t\t<software name=\"%s\"", util::xml::normalize_string(swinfo.shortname().c_str())); util::stream_format(out, "\t\t<software name=\"%s\"", util::xml::normalize_string(swinfo.shortname().c_str()));
@ -1129,6 +1133,8 @@ void cli_frontend::output_single_softlist(std::ostream &out, software_list_devic
util::stream_format(out, "\t\t\t<description>%s</description>\n", util::xml::normalize_string(swinfo.longname().c_str())); util::stream_format(out, "\t\t\t<description>%s</description>\n", util::xml::normalize_string(swinfo.longname().c_str()));
util::stream_format(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str())); util::stream_format(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str()));
util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str())); util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str()));
if (!swinfo.notes().empty())
util::stream_format(out, "\t\t\t<notes>%s</notes>\n", util::xml::normalize_string(swinfo.notes().c_str()));
for (const feature_list_item &flist : swinfo.other_info()) for (const feature_list_item &flist : swinfo.other_info())
util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str())); util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));