summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VP-database.xml464
-rw-r--r--VP-disasm.lua245
-rw-r--r--VP-fontwork.lua93
-rw-r--r--VP-indexwork.lua240
-rw-r--r--VP-isowork.lua163
-rw-r--r--VP-map.lua171
-rw-r--r--VP-miscwork.lua59
-rw-r--r--VP-process.lua305
-rw-r--r--VP-roomwork.lua499
-rw-r--r--VP-slz3-patch.lua33
-rw-r--r--VP-textwork.lua143
11 files changed, 2415 insertions, 0 deletions
diff --git a/VP-database.xml b/VP-database.xml
new file mode 100644
index 0000000..d72f328
--- /dev/null
+++ b/VP-database.xml
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SymbolTable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Symbol Width="4" Data="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" Text=" " />
+ <Symbol Width="8" Data="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" Text=" " />
+ <Symbol Width="3" Data="AAAAgACAAIAAgACAAIAAAAAAAIAAAAAA" Text="!" />
+ <Symbol Width="6" Data="AFAAoACgAAAAAAAAAAAAAAAAAAAAAAAA" Text="&quot;" />
+ <Symbol Width="6" Data="AAAAKAAoAPwAKAAoAFAA/ABQAFAAAAAA" Text="#" />
+ <Symbol Width="6" Data="ACAAcACoAKAAYAAwACgAqACoAHAAIAAA" Text="$" />
+ <Symbol Width="6" Data="AAAARACoAKgAsABoADQAVACUAIgAAAAA" Text="%" />
+ <Symbol Width="7" Data="AAAAMABIAEgAMABgAJQAiACIAHQAAAAA" Text="&amp;" />
+ <Symbol Width="2" Data="AIAAgACAAAAAAAAAAAAAAAAAAAAAAAAA" Text="'" />
+ <Symbol Width="4" Data="ABAAIAAgAEAAQABAAEAAIAAgABAAAAAA" Text="(" />
+ <Symbol Width="4" Data="AIAAQABAACAAIAAgACAAQABAAIAAAAAA" Text=")" />
+ <Symbol Width="6" Data="AAAAAAAgAKgAcABwAKgAIAAAAAAAAAAA" Text="*" />
+ <Symbol Width="6" Data="AAAAAAAAACAAIAD4ACAAIAAAAAAAAAAA" Text="+" />
+ <Symbol Width="2" Data="AAAAAAAAAAAAAAAAAAAAAAAAAIAAgAAA" Text="," />
+ <Symbol Width="2" Data="AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA" Text="." />
+ <Symbol Width="6" Data="AAQACAAIABAAEAAgACAAQABAAIAAAAAA" Text="/" />
+ <Symbol Width="2" Data="AAAAAAAAAAAAgAAAAAAAAACAAAAAAAAA" Text=":" />
+ <Symbol Width="2" Data="AAAAAAAAAAAAgAAAAAAAAAAAAIAAgAAA" Text=";" />
+ <Symbol Width="6" Data="AAAACAAQACAAQACAAEAAIAAQAAgAAAAA" Text="&lt;" />
+ <Symbol Width="6" Data="AAAAAAAAAAAA+AAAAAAA+AAAAAAAAAAA" Text="=" />
+ <Symbol Width="6" Data="AAAAgABAACAAEAAIABAAIABAAIAAAAAA" Text="&gt;" />
+ <Symbol Width="5" Data="AAAAcACIAIgAEAAgACAAAAAAACAAAAAA" Text="?" />
+ <Symbol Width="8" Data="AAAAOABEAJoAqgCqAKoAnABAADwAAAAA" Text="@" />
+ <Symbol Width="8" Data="AAAAGAAYACQAJAAkAH4AQgBCAEIAAAAA" Text="A" />
+ <Symbol Width="8" Data="AAAAfABCAEIAQgB8AEIAQgBCAHwAAAAA" Text="B" />
+ <Symbol Width="8" Data="AAAAOABEAIIAgACAAIIAggBEADgAAAAA" Text="C" />
+ <Symbol Width="8" Data="AAAAeABEAEIAQgBCAEIAQgBEAHgAAAAA" Text="D" />
+ <Symbol Width="7" Data="AAAAfABAAEAAQAB4AEAAQABAAHwAAAAA" Text="E" />
+ <Symbol Width="7" Data="AAAAfABAAEAAQAB4AEAAQABAAEAAAAAA" Text="F" />
+ <Symbol Width="8" Data="AAAAOABEAIIAgACOAIIAggBGADoAAAAA" Text="G" />
+ <Symbol Width="8" Data="AAAAQgBCAEIAQgB+AEIAQgBCAEIAAAAA" Text="H" />
+ <Symbol Width="3" Data="AAAA4ABAAEAAQABAAEAAQABAAOAAAAAA" Text="I" />
+ <Symbol Width="7" Data="AAAABAAEAAQABAAEAAQARABEADgAAAAA" Text="J" />
+ <Symbol Width="7" Data="AAAARABIAFAAYABgAFAAUABIAEQAAAAA" Text="K" />
+ <Symbol Width="6" Data="AAAAQABAAEAAQABAAEAAQABAAHgAAAAA" Text="L" />
+ <Symbol Width="9" Data="AAAAQQBjAGMAVQBVAFUASQBJAEEAAAAA" Text="M" />
+ <Symbol Width="8" Data="AAAAQgBiAGIAUgBSAEoARgBGAEIAAAAA" Text="N" />
+ <Symbol Width="8" Data="AAAAOABEAIIAggCCAIIAggBEADgAAAAA" Text="O" />
+ <Symbol Width="7" Data="AAAAeABEAEQARAB4AEAAQABAAEAAAAAA" Text="P" />
+ <Symbol Width="8" Data="AAAAOABEAIIAggCCAIIAkgBMADoAAAAA" Text="Q" />
+ <Symbol Width="8" Data="AAAAfABCAEIAQgB8AEQAQgBCAEEAAAAA" Text="R" />
+ <Symbol Width="7" Data="AAAAeACEAIAAQAA4AAQAhACEAHgAAAAA" Text="S" />
+ <Symbol Width="7" Data="AAAA/gAQABAAEAAQABAAEAAQABAAAAAA" Text="T" />
+ <Symbol Width="8" Data="AAAAQgBCAEIAQgBCAEIAQgBCADwAAAAA" Text="U" />
+ <Symbol Width="8" Data="AAAAgQBCAEIAQgAkACQAJAAYABgAAAAA" Text="V" />
+ <Symbol Width="9" Data="AACAiICIgIgAVQBVAFUAVQAiACIAAAAA" Text="W" />
+ <Symbol Width="7" Data="AAAAggBEAEQAKAAQACgARABEAIIAAAAA" Text="X" />
+ <Symbol Width="7" Data="AAAAggBEAEQAKAAQABAAEAAQABAAAAAA" Text="Y" />
+ <Symbol Width="7" Data="AAAA/AAEAAgAEAAgACAAQACAAPwAAAAA" Text="Z" />
+ <Symbol Width="4" Data="AHAAQABAAEAAQABAAEAAQABAAEAAcAAA" Text="[" />
+ <Symbol Width="4" Data="AOAAIAAgACAAIAAgACAAIAAgACAA4AAA" Text="]" />
+ <Symbol Width="5" Data="AEAAIAAAAAAAAAAAAAAAAAAAAAAAAAAA" Text="`" />
+ <Symbol Width="4" Data="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw" Text="_" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcAAIAHgAiACIAHgAAAAA" Text="a" />
+ <Symbol Width="6" Data="AAAAgACAAIAA8ACIAIgAiACIAPAAAAAA" Text="b" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcACIAIAAgACIAHAAAAAA" Text="c" />
+ <Symbol Width="6" Data="AAAACAAIAAgAeACIAIgAiACIAHgAAAAA" Text="d" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcACIAPgAgACIAHAAAAAA" Text="e" />
+ <Symbol Width="4" Data="AAAAIABAAEAA4ABAAEAAQABAAEAAAAAA" Text="f" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAeACQAPAAgADwAIgAcAAA" Text="g" />
+ <Symbol Width="6" Data="AAAAgACAAIAAsADIAIgAiACIAIgAAAAA" Text="h" />
+ <Symbol Width="3" Data="AAAAQAAAAAAAQABAAEAAQABAAEAAAAAA" Text="i" />
+ <Symbol Width="3" Data="AAAAQAAAAAAAQABAAEAAQABAAEAAQACA" Text="j" />
+ <Symbol Width="6" Data="AAAAgACAAIAAkACgAMAAoACQAIgAAAAA" Text="k" />
+ <Symbol Width="3" Data="AAAAQABAAEAAQABAAEAAQABAAEAAAAAA" Text="l" />
+ <Symbol Width="9" Data="AAAAAAAAAAAAWgBtAEkASQBJAEkAAAAA" Text="m" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAsADIAIgAiACIAIgAAAAA" Text="n" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcACIAIgAiACIAHAAAAAA" Text="o" />
+ <Symbol Width="6" Data="AAAAAAAAAAAA8ACIAIgAiACIAPAAgACA" Text="p" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAeACIAIgAiACIAHgACAAI" Text="q" />
+ <Symbol Width="4" Data="AAAAAAAAAAAAoADAAIAAgACAAIAAAAAA" Text="r" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcACIAEAAMACIAHAAAAAA" Text="s" />
+ <Symbol Width="4" Data="AAAAAABAAEAA4ABAAEAAQABAACAAAAAA" Text="t" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAiACIAIgAiACYAGgAAAAA" Text="u" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAiACIAFAAUAAgACAAAAAA" Text="v" />
+ <Symbol Width="8" Data="AAAAAAAAAAAAkgCqAKoAqgBEAEQAAAAA" Text="w" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAiABQACAAIABQAIgAAAAA" Text="x" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAiACIAFAAUAAgACAAQACA" Text="y" />
+ <Symbol Width="5" Data="AAAAAAAAAAAA8AAQACAAQACAAPAAAAAA" Text="z" />
+ <Symbol Width="3" Data="AGAAQABAAEAAQADAAEAAQABAAEAAYAAA" Text="{" />
+ <Symbol Width="3" Data="AEAAQABAAEAAQABAAEAAQABAAEAAQABA" Text="|" />
+ <Symbol Width="3" Data="AMAAQABAAEAAQABgAEAAQABAAEAAwAAA" Text="}" />
+ <Symbol Width="5" Data="AGgAsAAAAAAAAAAAAAAAAAAAAAAAAAAA" Text="~" />
+ <Symbol Width="6" Data="AAAAAAAAAGAAYAAAAAAAAABgAGAAAAAA" Text=":" />
+ <Symbol Width="9" Data="AAAAGAAYACQAJAAkAEIAfgBCAIEAAAAA" Text="A" />
+ <Symbol Width="9" Data="AAAAfgBBAEEAQQB+AEEAQQBBAH4AAAAA" Text="B" />
+ <Symbol Width="9" Data="AAAAPABCAIEAgACAAIAAgQBCADwAAAAA" Text="C" />
+ <Symbol Width="9" Data="AAAAfABCAEEAQQBBAEEAQQBCAHwAAAAA" Text="D" />
+ <Symbol Width="9" Data="AAAAfwBAAEAAQAB+AEAAQABAAH8AAAAA" Text="E" />
+ <Symbol Width="8" Data="AAAAfgBAAEAAQAB4AEAAQABAAEAAAAAA" Text="F" />
+ <Symbol Width="9" Data="AAAAHAAiAEEAQABHAEEAQQAjAB0AAAAA" Text="G" />
+ <Symbol Width="9" Data="AAAAQQBBAEEAQQB/AEEAQQBBAEEAAAAA" Text="H" />
+ <Symbol Width="7" Data="AAAABAAEAAQABAAEAIQAhACEAHgAAAAA" Text="J" />
+ <Symbol Width="9" Data="AAAAggCEAIgAkACoAMgAhACCAIEAAAAA" Text="K" />
+ <Symbol Width="8" Data="AAAAQABAAEAAQABAAEAAQABAAH8AAAAA" Text="L" />
+ <Symbol Width="11" Data="AADAYMBgQFFAUUBRQEpASkBEQEQAAAAA" Text="M" />
+ <Symbol Width="9" Data="AAAAQQBhAFEAUQBJAEUARQBDAEEAAAAA" Text="N" />
+ <Symbol Width="9" Data="AAAAfgBBAEEAQQB+AEQAQgBBAEEAAAAA" Text="R" />
+ <Symbol Width="9" Data="AAAAPABCAEEAIAAcAAIAQQAhAB4AAAAA" Text="S" />
+ <Symbol Width="6" Data="AAgAEAAgACAAQABAAEAAIAAgABAACAAA" Text="(" />
+ <Symbol Width="6" Data="AIAAQAAgACAAEAAQABAAIAAgAEAAgAAA" Text=")" />
+ <Symbol Width="6" Data="ADgAIAAgACAAIAAgACAAIAAgACAAOAAA" Text="[" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAAAD4AAAAAAAAAAAAAAAA" Text="-" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiACIAIgAiACIAHAAAAAA" Text="0" />
+ <Symbol Width="6" Data="AAAAIADgACAAIAAgACAAIAAgACAAAAAA" Text="1" />
+ <Symbol Width="6" Data="AAAAcACIAIgACAAQACAAQACAAPgAAAAA" Text="2" />
+ <Symbol Width="6" Data="AAAAcACIAIgACAAwAAgAiACIAHAAAAAA" Text="3" />
+ <Symbol Width="6" Data="AAAAEAAwADAAUABQAJAA+AAQABAAAAAA" Text="4" />
+ <Symbol Width="6" Data="AAAA+ACAAIAA8ACIAAgAiACIAHAAAAAA" Text="5" />
+ <Symbol Width="6" Data="AAAAMABIAIAA8ACIAIgAiACIAHAAAAAA" Text="6" />
+ <Symbol Width="6" Data="AAAA+AAIAAgAEAAQABAAIAAgACAAAAAA" Text="7" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiABwAIgAiACIAHAAAAAA" Text="8" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiACIAHgACACQAGAAAAAA" Text="9" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiACIAIgAiACIAIgAcAAA" Text="◎" />
+ <Symbol Width="6" Data="AAAAIABgACAAIAAgACAAIAAgACAAIAAA" Text="①" />
+ <Symbol Width="6" Data="AAAAcACIAIgACAAQABAAIABAAIAA+AAA" Text="②" />
+ <Symbol Width="6" Data="AAAAcACIAIgACAAwAAgACACIAIgAcAAA" Text="③" />
+ <Symbol Width="6" Data="AAAAMAAwAFAAUACQAJAAkAD4ABAAEAAA" Text="④" />
+ <Symbol Width="6" Data="AAAA+ACAAIAAgADwAAgACAAIAIgAcAAA" Text="⑤" />
+ <Symbol Width="6" Data="AAAAcACIAIAAgADwAIgAiACIAIgAcAAA" Text="⑥" />
+ <Symbol Width="6" Data="AAAA+AAIABAAEAAgACAAIAAgACAAIAAA" Text="⑦" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiABwAIgAiACIAIgAcAAA" Text="⑧" />
+ <Symbol Width="6" Data="AAAAcACIAIgAiACIAHgACACIAIgAcAAA" Text="⑨" />
+ <Symbol Width="8" Data="AAAACAB4AAgACAAIAAgACAAIAAgAAAAA" Text="1" />
+ <Symbol Width="8" Data="AAAAPABCAIIAAgAMADAAQACAAP4AAAAA" Text="2" />
+ <Symbol Width="8" Data="AAAAfACCAIIAAgAcAAIAggCCAHwAAAAA" Text="3" />
+ <Symbol Width="8" Data="AAAADAAUABQAJABEAIQA/wAEAAQAAAAA" Text="4" />
+ <Symbol Width="8" Data="AAAA/gCAAIAAvADCAAIAggBCADwAAAAA" Text="5" />
+ <Symbol Width="8" Data="AAAAPABCAIAAvADCAIIAggCCAHwAAAAA" Text="6" />
+ <Symbol Width="8" Data="AAAAfgACAAQABAAEAAgACAAIABAAAAAA" Text="7" />
+ <Symbol Width="8" Data="AAAAfACCAIIAggB8AIIAggCCAHwAAAAA" Text="8" />
+ <Symbol Width="8" Data="AAAAeACEAIIAggCGAHoAAgCEAHgAAAAA" Text="9" />
+ <Symbol Width="8" Data="AAAAAAAAAAAAAAAAAAAAAABgAGAAAAAA" Text="." />
+ <Symbol Width="3" Data="AAAAwADAAMAAwADAAIAAAAAAAMAAwAAA" Text="ǃ" />
+ <Symbol Width="6" Data="AEgAkADYAAAAAAAAAAAAAAAAAAAAAAAA" Text="“" />
+ <Symbol Width="6" Data="ANgASACQAAAAAAAAAAAAAAAAAAAAAAAA" Text="”" />
+ <Symbol Width="12" Data="AAAADgARABEAAgAEAAQAAAAEAAQAAAAA" Text="?" />
+ <Symbol Width="12" Data="AAAAAAAEAAQABIA/AAQABAAEAAAAAAAA" Text="+" />
+ <Symbol Width="12" Data="AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAA" Text="-" />
+ <Symbol Width="12" Data="AAQABMB/AAQABOD/AA4AFYAkYMQABAAA" Text="未" />
+ <Symbol Width="12" Data="AABAYICQAJEAksBkIAkgESAhwEAAAAAA" Text="%" />
+ <Symbol Width="12" Data="IABAAIAAAAEAAgAEAAgAEAAgAEAAgAAA" Text="/" />
+ <Symbol Width="12" Data="AAAAAIAkABUADgAEAA4AFYAkAAAAAAAA" Text="*" />
+ <Symbol Width="12" Data="AAAAAAAAwH8AAAAAwH8AAAAAAAAAAAAA" Text="=" />
+ <Symbol Width="12" Data="AAAABAAEAAQABAAEAAAAAAAEAAQAAAAA" Text="!" />
+ <Symbol Width="6" Data="AAAAiACIAFAAUAD4ACAA+AAgACAAAAAA" Text="¥" />
+ <Symbol Width="5" Data="AHAAiAAAAAAAAAAAAAAAAAAAAAAAAAAA" Text="^" />
+ <Symbol Width="5" Data="AAAAAAAAAAAAYABgAAAAAAAAAAAAAAAA" Text="·" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAYABgAAAAAAAAAAAAAAAA" Text="・" />
+ <Symbol Width="6" Data="AHgAcABgAGAAQABAAEAAYABgAHAAeAAA" Text="【" />
+ <Symbol Width="6" Data="APAAcAAwADAAEAAQABAAMAAwAHAA8AAA" Text="】" />
+ <Symbol Width="12" Data="AAAAAAAAAADAzMDMAAAAAAAAAAAAAAAA" Text="…" />
+ <Symbol Width="11" Data="AAAAAIB/AAgACAAIAAgACAAIwP8AAAAA" Text="エ" />
+ <Symbol Width="10" Data="ABAAEIAfgCCAQACBAAEAAgAEABgAYAAA" Text="ク" />
+ <Symbol Width="11" Data="AAAAfwABAAEAAgACAAQACgARgCBAwAAA" Text="ス" />
+ <Symbol Width="11" Data="AACAfwAAAADA/wAEAAQABAAEAAgAMAAA" Text="テ" />
+ <Symbol Width="10" Data="AAAAwAAggACAAIAAAAEAAgAEABgA4AAA" Text="ン" />
+ <Symbol Width="11" Data="AAAAYAAQQABAwIAgAAEAAgAEABgAYAAA" Text="シ" />
+ <Symbol Width="8" Data="AAAAAAAAAAAA/AAEAPwABAAEAPwABAAA" Text="ョ" />
+ <Symbol Width="10" Data="AAAAAID/gACAAIAAAAEAAQACAAwAcAAA" Text="フ" />
+ <Symbol Width="10" Data="AAAAAAAAAAQABAD/AAwAFAAkAMQADAAA" Text="ォ" />
+ <Symbol Width="12" Data="AAAAAAAAAAAAQMA/AAAAAAAAAAAAAAAA" Text="ー" />
+ <Symbol Width="8" Data="AEAASgBKAEAAcABMAEAAQABAAEAAQAAA" Text="ド" />
+ <Symbol Width="10" Data="AAAAfwAAAACA/4AAgAAAAQABAAYAOAAA" Text="ラ" />
+ <Symbol Width="11" Data="QAFAAQAAgP+AAIAAgACAAIAAgP+AAAAA" Text="ゴ" />
+ <Symbol Width="11" Data="AAEAAcD/AAMABQAJABEAIQDBAAEABwAA" Text="オ" />
+ <Symbol Width="11" Data="QAFAAQAAgP+AAIAAAAEAAQACAAwAcAAA" Text="ブ" />
+ <Symbol Width="12" Data="AATg/yCSQCLAwwAAwH8ABAAEAATg/wAA" Text="空" />
+ <Symbol Width="12" Data="4C7gLqDq4C6gaaBo4KugquAroCmgKgAA" Text="欄" />
+ <Symbol Width="12" Data="4C8AIeBPIEngzyBJ4E8AQQBFAEPgXAAA" Text="便" />
+ <Symbol Width="12" Data="IBgg4SAhIPkgISBxIGkgoSAgICBgIAAA" Text="利" />
+ <Symbol Width="12" Data="gD+AIIAggD8AAAAA4PsgiiCKIIrg+wAA" Text="品" />
+ <Symbol Width="12" Data="gD8AAQAKAATg/0AEgAQABAAEAAQAHAAA" Text="予" />
+ <Symbol Width="12" Data="ACIAQuCTIGQgQCDyICEgqCCoIKjAIAAA" Text="約" />
+ <Symbol Width="12" Data="ACAAIMB/QESAhAAEAAoACgARgCBgwAAA" Text="欠" />
+ <Symbol Width="12" Data="gAGAPgAV4P8AFYAk4P+AJIA/gCSAPwAA" Text="番" />
+ <Symbol Width="12" Data="AATg/yCAAADAfwAEACTAJwAkAFzghwAA" Text="定" />
+ <Symbol Width="12" Data="gFKA+oBSoCbA+oCqgPqAIoD6oCLgIgAA" Text="靴" />
+ <Symbol Width="11" Data="AADA/0AAgAAACQAKAAgACAAQABAAIAAA" Text="ア" />
+ <Symbol Width="10" Data="AAAAQABAAEAAQIBAgEAAQQBCAEwAcAAA" Text="レ" />
+ <Symbol Width="8" Data="AEAAQABAAEAAcABMAEAAQABAAEAAQAAA" Text="ト" />
+ <Symbol Width="10" Data="gAAAAQACAAQADAA0AMQABAAEAAQABAAA" Text="イ" />
+ <Symbol Width="12" Data="ACjA3kCSQJ5AksDeAAAAEgASICLgwwAA" Text="兜" />
+ <Symbol Width="12" Data="4H8AQABAwH9ASIBIgEQARQBCgI1gsAAA" Text="反" />
+ <Symbol Width="12" Data="QCBAIOD7QABAEEBSQCFAIEBQQIDAAAAA" Text="対" />
+ <Symbol Width="11" Data="AAAAgMCPAIAAgACAAIAAiACIwIcAAAAA" Text="に" />
+ <Symbol Width="12" Data="ACEA+eBRQPtAqUD5QKmA6ICoQOkgigAA" Text="敵" />
+ <Symbol Width="10" Data="AAiACQD+ABCAPQBGAIoAEgAgACCAHwAA" Text="を" />
+ <Symbol Width="12" Data="4P8ACAAIABAAEMA/QFBAkEAQQBDAHwAA" Text="石" />
+ <Symbol Width="12" Data="ACQAJABEwEQAxwBEAEQARABEIETgRwAA" Text="化" />
+ <Symbol Width="9" Data="AAQABAD/AAQAAgA+AEMAgQCAAEAAPgAA" Text="さ" />
+ <Symbol Width="12" Data="AAAAIQAhACHg/wAhACEAJgAgACCAHwAA" Text="せ" />
+ <Symbol Width="10" Data="AAAAfAAIABAAPgBBgICAAIAYACUAHgAA" Text="る" />
+ <Symbol Width="12" Data="AHHgXyBQAHTgV6BZoHWgUoBSoJTgmAAA" Text="腕" />
+ <Symbol Width="12" Data="gCFA8iAkwPMAoOD3IKXg9yAlIPVgJQAA" Text="輪" />
+ <Symbol Width="8" Data="AAAAAAAAAAAAAAAAAAAAYACQAJAAYAAA" Text="。" />
+ <Symbol Width="12" Data="gP+AAIAAgH8AQABAwP9AgEAAgAAABwAA" Text="弓" />
+ <Symbol Width="6" Data="AHgAQABAAEAAQABAAEAAQABAAAAAAAAA" Text="「" />
+ <Symbol Width="12" Data="ACHgLwBB4E8gyeBPAEEARQBCgEVgWAAA" Text="使" />
+ <Symbol Width="12" Data="4H8gRCBE4H8gRCBE4H8gRCBEIITghAAA" Text="用" />
+ <Symbol Width="12" Data="AAAAAAABgADA/yAAwP+AAAABAAAAAAAA" Text="⇒" />
+ <Symbol Width="12" Data="AAAAAAAAACAAQOD/AEAAIAAAAAAAAAAA" Text="←" />
+ <Symbol Width="12" Data="AAQADgAVAAQABAAEAAQABAAEAAQABAAA" Text="↑" />
+ <Symbol Width="12" Data="AAQABAAEAAQABAAEAAQABAAVAA4ABAAA" Text="↓" />
+ <Symbol Width="12" Data="AAAAAAAAgABAAOD/QACAAAAAAAAAAAAA" Text="→" />
+ <Symbol Width="12" Data="ABHg/wARAASAP4AkgCTg/wAKgDFgwAAA" Text="英" />
+ <Symbol Width="12" Data="wPcAAcD3QAJA8uAPAPDAB0D0QJTA9wAA" Text="語" />
+ <Symbol Width="12" Data="AATAfwAEgD8ABOD/QAqAMgDRgBxgcAAA" Text="表" />
+ <Symbol Width="12" Data="AADA90AAQPBAAMD3AAQA9ACUIJTg9wAA" Text="記" />
+ <Symbol Width="11" Data="AADADwDyQARACQAJAAgACAAIAASAAwAA" Text="で" />
+ <Symbol Width="10" Data="AAgA/wAIgP8ABAAEAH4AggCAAIAAfAAA" Text="き" />
+ <Symbol Width="11" Data="ACAAIID5QCAAQQBBAEEAj4CRQBEADgAA" Text="な" />
+ <Symbol Width="11" Data="AAAAgICAgIBAgECAQIBAgEBQAFAAIAAA" Text="い" />
+ <Symbol Width="12" Data="AAQABOD/ABEAEQARAAoABAAKgDFgwAAA" Text="文" />
+ <Symbol Width="12" Data="AATAfwAR4P+AIIA/gCCAPwAE4P8ABAAA" Text="章" />
+ <Symbol Width="12" Data="AADg/8B/wH+APwAfAB8ADgAOAAQAAAAA" Text="▼" />
+ <Symbol Width="10" Data="AAAAPgBBgICAgICAgICAgABBAD4AAAAA" Text="○" />
+ <Symbol Width="12" Data="AA6AMUBAQEAggCCAIIBAQEBAgDEADgAA" Text="〇" />
+ <Symbol Width="12" Data="gKigAID44KuA+KCooPhAIED4wCAgIQAA" Text="戦" />
+ <Symbol Width="12" Data="gELgLwABwAdA5MAnQCRAJMAnAFDgjwAA" Text="道" />
+ <Symbol Width="11" Data="AAQABMB/AAQABAAVgBRAJEBEAAQABAAA" Text="ホ" />
+ <Symbol Width="12" Data="ACEAIQA9AEeARUCpIBkAEQARACEAQQAA" Text="外" />
+ <Symbol Width="12" Data="wEdAJMAFQAXg7yAooCugKqArAFDgjwAA" Text="過" />
+ <Symbol Width="12" Data="AATAfwAOgDVgxIAk4PuAIMBxoKqAIAAA" Text="森" />
+ <Symbol Width="12" Data="APGAosD3IKnA90ClwPcAEYDSQBQgaAAA" Text="験" />
+ <Symbol Width="12" Data="AATg/yCAwH8ACIAQQH8ABMB/AATg/wAA" Text="室" />
+ <Symbol Width="12" Data="ABHg/wAR4PsgiuD7IISgvyCVII5glQAA" Text="蘭" />
+ <Symbol Width="11" Data="AADADwDyAAQACAAIAAgACAAIAASAAwAA" Text="て" />
+ <Symbol Width="12" Data="AAAAAIAgABEACgAEAAoAEYAgAAAAAAAA" Text="✕" />
+ <Symbol Width="7" Data="AAAAeAAAAAAA/AAEAAQACAAIABAAIAAA" Text="ラ" />
+ <Symbol Width="8" Data="AAAAAAAAAAIABAAIADgAyAAIAAgACAAA" Text="ィ" />
+ <Symbol Width="9" Data="AAAAAAAAAAAAIgCSAEIABAAEAAgAMAAA" Text="ッ" />
+ <Symbol Width="9" Data="ABAAEAAfACEAQQCZAAYAAgAFABgA4AAA" Text="夕" />
+ <Symbol Width="12" Data="AAIAAuB/AEAAQgBCAEKAREBEwIggnwAA" Text="広" />
+ <Symbol Width="7" Data="AAAAQAAgAAAAhABEAAgACAAQACAAQAAA" Text="ツ" />
+ <Symbol Width="10" Data="AAAAEACIgEiAQIAAAAEAAQACAAwAMAAA" Text="ツ" />
+ <Symbol Width="12" Data="AAAAAAAAAACAZUBmQARABEAEQAQAAAAA" Text="ʼn" />
+ <Symbol Width="11" Data="QAlACQAIgP8ACAAqACmASICIAAgACAAA" Text="ボ" />
+ <Symbol Width="12" Data="4P8ABAAEwH9ARMB/QETg/0BAQEDAQAAA" Text="再" />
+ <Symbol Width="10" Data="AAAAAAAAAAAAAAB+AAEAAQABAAIAHAAA" Text="っ" />
+ <Symbol Width="12" Data="AAAAH4AkQEQgRCCEIIggiECQgGAAAwAA" Text="の" />
+ <Symbol Width="12" Data="AAEA9cBHAHUAUeDXALGAI0AlIEkAgQAA" Text="殊" />
+ <Symbol Width="6" Data="AAAACAAIAAgAUAAwABAAKAAoAEAAgAAA" Text="メ" />
+ <Symbol Width="12" Data="oACgIAAgwCdA+IAgACEAIgAgACDAHwAA" Text="ゼ" />
+ <Symbol Width="12" Data="AATg/yCSwHtAyMB7AErA+0AoQEiAmQAA" Text="窮" />
+ <Symbol Width="12" Data="AAAAAAAIABQAIgBBgIBAACAAAAAAAAAA" Text="ヘ" />
+ <Symbol Width="8" Data="AAAAEABQAFAAUABQAFIAUgCUAJgAkAAA" Text="ル" />
+ <Symbol Width="12" Data="ADwABAAEAAQACgAKABEAEYAgQEAggAAA" Text="入" />
+ <Symbol Width="12" Data="wEdAJMAHQATA54AkoCRAJiAsAFDgjwAA" Text="退" />
+ <Symbol Width="12" Data="4PsgiuD7IIrg+yCAIJ8gkSCfIJFgnwAA" Text="間" />
+ <Symbol Width="12" Data="ACHAV4CC4O9AJMD3QCTAp4CioCTg6AAA" Text="鏡" />
+ <Symbol Width="12" Data="AAgACMAPQBCAMIDIAAUAAgAEABgA4AAA" Text="タ" />
+ <Symbol Width="12" Data="ACHgrwChwCcA8eAvQGTAZ0CkwCdAJAAA" Text="精" />
+ <Symbol Width="12" Data="ABHAfwAEgD8ABOD/AATg/wAKgDFgwAAA" Text="美" />
+ <Symbol Width="12" Data="4E4gIuAOgAjg7oAiwCeAIuAvQFTgjwAA" Text="選" />
+ <Symbol Width="12" Data="oOCAoODvgKCA5KCkoK5A5MAEQKEgogAA" Text="賊" />
+ <Symbol Width="8" Data="AAAAAAAAAAAAgAB+AAAAAAAAAAAAAAAA" Text="ー" />
+ <Symbol Width="12" Data="4PsgIuD7IKrgq4Da4IuAjOD7gIjg+wAA" Text="醒" />
+ <Symbol Width="12" Data="4P0gJUAlgP1AJSAlIP0gJcBFAEUAmQAA" Text="那" />
+ <Symbol Width="9" Data="AAAAAAAAAAAAAAB8ABAAEAAQAP4AAAAA" Text="ェ" />
+ <Symbol Width="12" Data="AABARIAkABEACsBkAAoAEYAkQEQAAAAA" Text="※" />
+ <Symbol Width="12" Data="APLAk0CUgPqAIUAmIDjAp0CkQLTA5wAA" Text="路" />
+ <Symbol Width="12" Data="AAQACgARgCBg3wAEgD8ABIAkABXAfwAA" Text="金" />
+ <Symbol Width="12" Data="AARAREBEQERARMB/AAQghCCEIITg/wAA" Text="出" />
+ <Symbol Width="12" Data="4C8gSKCaoGrgTyD5YC1greCvIKhgKAAA" Text="綱" />
+ <Symbol Width="12" Data="gH+AQIB/gECAf4BAgH8AEgASICLgwwAA" Text="見" />
+ <Symbol Width="12" Data="AAQABAAEAAQACgAKABEAEYAgQEAggAAA" Text="人" />
+ <Symbol Width="12" Data="AATg/wAEwH8AAMB/QETAfwBAAEAAgAAA" Text="声" />
+ <Symbol Width="11" Data="QAFAYQAQQABAwIAgAAEAAgAEABgAYAAA" Text="ジ" />
+ <Symbol Width="12" Data="AAAABAAKAAoAEQARgCBAQEBA4P8AAAAA" Text="△" />
+ <Symbol Width="12" Data="AALgfwBAAELAQwBCAELAX0BQQJDAnwAA" Text="店" />
+ <Symbol Width="12" Data="oCKAIOD3wCGgcgBh4KdAokAigCFgJgAA" Text="楼" />
+ <Symbol Width="12" Data="ACHAVwCBwHdAJcD3QCXAp4CjQDUg6QAA" Text="錬" />
+ <Symbol Width="12" Data="AAgACIAQQCCg/wAAgD+AIIAggCCAPwAA" Text="台" />
+ <Symbol Width="6" Data="AAAACAAIAAgACAAQABAAIAAgAEAAgAAA" Text="ノ" />
+ <Symbol Width="11" Data="AAAAAEABQBkAJABCAIGAAEAAAAAAAAAA" Text="ベ" />
+ <Symbol Width="12" Data="wCEAIeAvIPnALyApwCmgOuDOgBLgFwAA" Text="墟" />
+ <Symbol Width="6" Data="AAAAAAAAAAAA+AAIACgAMAAgACAAQAAA" Text="ァ" />
+ <Symbol Width="12" Data="QCBAIOD3QCBAcEBiQKFAoEAgQCDAIAAA" Text="村" />
+ <Symbol Width="12" Data="ACAAIID8QCJAIiAiIEIgQgBCAJQAjAAA" Text="か" />
+ <Symbol Width="12" Data="AAAAPAAEgAiACIA+wFGgkICgAMEABgAA" Text="み" />
+ <Symbol Width="12" Data="4C+AIuDvoCrgbwBgwKcAoOAvQCUgKQAA" Text="標" />
+ <Symbol Width="6" Data="AGAAIABAAAAAAAAAAAAAAAAAAAAAAAAA" Text="´" />
+ <Symbol Width="11" Data="gABAAYAAgP+AAIAAAAEAAQACAAwAcAAA" Text="プ" />
+ <Symbol Width="12" Data="QERAJIAkAATAf0AAQADAf0AAQADAfwAA" Text="当" />
+ <Symbol Width="11" Data="AAAAIAAgwCdA+IAgACEAIgAgACDAHwAA" Text="セ" />
+ <Symbol Width="5" Data="AAAAAAAAABAAEAAgAGAAoAAgACAAIAAA" Text="ィ" />
+ <Symbol Width="12" Data="AALg7aBIoEpA7QBA4E8gaeDPIAngDwAA" Text="瑠" />
+ <Symbol Width="12" Data="AATg/4AkgD+AJMB/AATg/0AygNFgHAAA" Text="裏" />
+ <Symbol Width="12" Data="oACgBAAEwH9AQEBAQECAAIAAAAMAHAAA" Text="ヴ" />
+ <Symbol Width="11" Data="QBFAEQAggD+AQICAAAEAAQACAAwAcAAA" Text="グ" />
+ <Symbol Width="10" Data="AACA/4CAgICAgICAgICAgID/gIAAAAAA" Text="ロ" />
+ <Symbol Width="12" Data="AETgjgAk4ERA30BAQERAX0BEQEfAXAAA" Text="術" />
+ <Symbol Width="12" Data="AAAAAAAAAAAAAPD/AAAAAAAAAAAAAAAA" Text="―" />
+ <Symbol Width="12" Data="AAQABAAEAATABwAEAAQABAAEAATg/wAA" Text="上" />
+ <Symbol Width="12" Data="ACEAJWAloPUgJyAtYCUANQDEIATgBwAA" Text="地" />
+ <Symbol Width="12" Data="gCAAEeD/AABAeEBKQHpASkB6QEjAWAAA" Text="前" />
+ <Symbol Width="10" Data="ADgABgBAAEAAXgBhgMCAgIAAAAEAHgAA" Text="ら" />
+ <Symbol Width="12" Data="AAIAAuD/AAIADgASABIADgACAAQAGAAA" Text="す" />
+ <Symbol Width="12" Data="QCEgIeAvgOiAKKAuoCpAKsDSQBUgIgAA" Text="城" />
+ <Symbol Width="3" Data="AEAAIACAAEAAAAAAAAAAAAAAAAAAAAAA" Text="¨" />
+ <Symbol Width="12" Data="gD+AIMB/QEDAf0BAwH9AQMB/gCBgwAAA" Text="員" />
+ <Symbol Width="9" Data="ACAAIAAgABMAHAAwAEAAgACAAEAAPwAA" Text="と" />
+ <Symbol Width="6" Data="ABAAkACQAJAAkACQABAAIAAgAEAAgAAA" Text="り" />
+ <Symbol Width="9" Data="AAAAAQABAAEAYgAaAAQACgARACAAwAAA" Text="メ" />
+ <Symbol Width="11" Data="AAAABAAEAATA/wAEAAQACAAIABAAYAAA" Text="ナ" />
+ <Symbol Width="12" Data="gACAgOCPgICAgICAgICAh8CIoIgAhwAA" Text="は" />
+ <Symbol Width="12" Data="AAgACOD/ABAAEAAQwD8AIgBCAILgPwAA" Text="左" />
+ <Symbol Width="12" Data="AALgfwBAQF+gSMBfIGXAXwBFIIngkQAA" Text="廃" />
+ <Symbol Width="11" Data="AACAPwABAAYAGMD/AAgAEAAQAAiABwAA" Text="そ" />
+ <Symbol Width="12" Data="AEIAIgAEQIigXwAAAADAT0BIQIjAjwAA" Text="治" />
+ <Symbol Width="9" Data="AAAAAAAAAAAA/wABABIAFAAQACAAQAAA" Text="ァ" />
+ <Symbol Width="8" Data="AAAAAgACAAIABAAEAAgAEAAgAMAAAAAA" Text="ノ" />
+ <Symbol Width="12" Data="ADEA4QAhAPkAIgByAGqAokAkwCQgLwAA" Text="私" />
+ <Symbol Width="12" Data="AAQARIBPQFQgZCBIIKggkKCZQGKgAQAA" Text="ぬ" />
+ <Symbol Width="12" Data="AALgfwBAIFzARUBI4F1AROBVAIjglwAA" Text="庭" />
+ <Symbol Width="10" Data="AAAAAAAAAAAAAAB8AAQABAAEAP8AAAAA" Text="ュ" />
+ <Symbol Width="12" Data="4CcAVACM4HcgVSB1QFXAdIBEQHkgygAA" Text="飯" />
+ <Symbol Width="12" Data="AITgRyAJAAGAImDMAADAf0BKQErg/wAA" Text="盗" />
+ <Symbol Width="9" Data="AAAAAAD/AAEAAQD/AAEAAQABAP8AAQAA" Text="ヨ" />
+ <Symbol Width="12" Data="4Pvg+yCK4PsggCCAIJ8gkSCRIJ9ggAAA" Text="問" />
+ <Symbol Width="12" Data="wH8ABOD/IISANQAA4P8ABAAHgAQABAAA" Text="雫" />
+ <Symbol Width="8" Data="AAAAAAB8AAQACAAIABAAGAAkAEIAgAAA" Text="ス" />
+ <Symbol Width="12" Data="wAdA9MAnQCTA90AkwCeAMoDioATgGAAA" Text="現" />
+ <Symbol Width="12" Data="ACHAJwDx4C9AIEAw4O9AJEAiQCDAYAAA" Text="待" />
+ <Symbol Width="8" Data="AAAAgQBCACQAGAAYABgAJABCAIEAAAAA" Text="×" />
+ <Symbol Width="12" Data="AATg/yCEwH8ABMB/AATg/wAKgDFgwAAA" Text="実" />
+ <Symbol Width="12" Data="AAQABCAGQPaAFQAVgCSAJEBEIIQADAAA" Text="水" />
+ <Symbol Width="12" Data="AAQABOD/AAgACIAPgAiAEIAQgCAAQwAA" Text="タ" />
+ <Symbol Width="8" Data="AAAAAAAAAAAAAAAAAAAAAACAAEAAIAAA" Text="、" />
+ <Symbol Width="6" Data="AEAAQAB4AEgAiACoABAAGAAoACAAQAAA" Text="夂" />
+ <Symbol Width="12" Data="wPdABMD3QATg8yAMIPcgBKD3IJDA8AAA" Text="謁" />
+ <Symbol Width="12" Data="AAgACOD/ABAAEQAhwCcAYQChACHgLwAA" Text="在" />
+ <Symbol Width="12" Data="ABHg/wARAATg/wAEwAdACEAIQBCAYQAA" Text="芳" />
+ <Symbol Width="8" Data="AAAAAAAIACQAJAAkACIAQgBCAIIAAAAA" Text="ハ" />
+ <Symbol Width="11" Data="AACAAwB8AAQABMD/AAQABAAEAAgAMAAA" Text="チ" />
+ <Symbol Width="12" Data="AADAf0BAQEBAQEBAQEBAQEBAwH8AAAAA" Text="口" />
+ <Symbol Width="12" Data="4CEg/UBJgElA/SABIAEg/cCFAIUA/QAA" Text="部" />
+ <Symbol Width="12" Data="4P8ACAAI4P8gkSCfIJEgnyCRIJHg/wAA" Text="面" />
+ <Symbol Width="12" Data="AATg/wAEwH9AUUBKQF9AREBfQETARAAA" Text="南" />
+ <Symbol Width="12" Data="ACEAIeBPIEkgySBJ4E8AQQBBAEEAQQAA" Text="仲" />
+ <Symbol Width="12" Data="4H8ARMBfQFDAX0BQwF8AQkCSIKIABgAA" Text="原" />
+ <Symbol Width="12" Data="oACgfgAAAADA/wAEAAQABAAEAAgAMAAA" Text="デ" />
+ <Symbol Width="8" Data="ACAAIAD8AIQAhACEAAQACAAIABAAIAAA" Text="ウ" />
+ <Symbol Width="12" Data="AEAAoABAAAAAAAAAAAAAAAAAAAAAAAAA" Text="゜" />
+ <Symbol Width="12" Data="gPFAkqClAMDAo4CQ4JcAkODnQIKghwAA" Text="陰" />
+ <Symbol Width="12" Data="AACAAwA8ACAAIMA/ACIAIgAiACLg/wAA" Text="丘" />
+ <Symbol Width="12" Data="oACgIAAhwP8AIQAhACEAAQABAAIAHAAA" Text="ザ" />
+ <Symbol Width="12" Data="AAAAAAAAAAAAeCCEwAMAAAAAAAAAAAAA" Text="~" />
+ <Symbol Width="9" Data="AAAAggCCAIIAggCCAIIAhAAEABgAYAAA" Text="リ" />
+ <Symbol Width="12" Data="wH9ARMB/QETAfwAKgDFg0QARACEAQQAA" Text="界" />
+ <Symbol Width="12" Data="AADg/wAEAAQABMB/AASABEAEAATg/wAA" Text="玉" />
+ <Symbol Width="12" Data="ABHg/wARAATg/wAIABDAP0DQQBDAHwAA" Text="若" />
+ <Symbol Width="12" Data="AAAAAAAhgCCAIEAgQCBAQEBAQIAAAAAA" Text="ハ" />
+ <Symbol Width="12" Data="AEDgLyACIAIg4iAiICQgJMAoAFDgjwAA" Text="辺" />
+ <Symbol Width="12" Data="ACQAJMB/AEQAhAAEgD8ABAAEAATg/wAA" Text="生" />
+ <Symbol Width="8" Data="AAQAJAAkAP4AJAAkACQACAAIABAAIAAA" Text="サ" />
+ <Symbol Width="12" Data="AAng/wBpwKCA+4Co4PuAqMD5oAKAqAAA" Text="蘇" />
+ <Symbol Width="7" Data="AAAAAAD4AAgACAAIAAgAEAAQACAAQAAA" Text="フ" />
+ <Symbol Width="12" Data="gAMAPAAEwH8ABAAE4P8ABAAEAAQADAAA" Text="手" />
+ <Symbol Width="11" Data="AACAfwAIAAgACMD/AAgACAAIAAiABwAA" Text="モ" />
+ <Symbol Width="7" Data="AAAAAAD4AIgAiACIAIgAiACIAPgAiAAA" Text="ロ" />
+ <Symbol Width="12" Data="AAAAIQAh4P8AIQAhACEAAQABAAIAHAAA" Text="サ" />
+ <Symbol Width="12" Data="AAAACAAIAAgAEIAQgBBAIMAjIPwgAAAA" Text="ム" />
+ <Symbol Width="12" Data="AADg/wAiACJAeoBKAMsAMgASICLgwwAA" Text="死" />
+ <Symbol Width="12" Data="ABHg/wARgD+AIIA/gCCAPwAE4P8ABAAA" Text="草" />
+ <Symbol Width="12" Data="AAQACgARgCBg3wAEAASAPwAEAATAfwAA" Text="全" />
+ <Symbol Width="12" Data="wCdAJMAnQPTgLwAi4CegKqDEIAlAAgAA" Text="場" />
+ <Symbol Width="11" Data="QBFAEQAQgP+AEIAQgBCAIIAggEAAhwAA" Text="ガ" />
+ <Symbol Width="12" Data="AEEAQcD3QBFAIUBR4OcAUYBCQEQgSAAA" Text="袂" />
+ <Symbol Width="12" Data="QACgAEAgACGAIIAgQCBAQEBAQIAAAAAA" Text="パ" />
+ <Symbol Width="5" Data="AAAAYAAQAAAAYAAQAAAAwAAgABAAAAAA" Text="ミ" />
+ <Symbol Width="12" Data="gETgXwBDgORASKBXAEDAb0DIQAjADwAA" Text="塔" />
+ <Symbol Width="12" Data="ACAAIAD3gCiAMIBggGCAoICgoCBAIAAA" Text="れ" />
+ <Symbol Width="12" Data="gCeAJID8gKSApoClgKSApIAkoCjgKAAA" Text="帆" />
+ <Symbol Width="11" Data="AAAAAMD/QACAAAABACIAFAAIAAQABAAA" Text="マ" />
+ <Symbol Width="12" Data="gD+AIIA/gCDg/wBIwH9ASoBZgOpgDAAA" Text="最" />
+ <Symbol Width="8" Data="AAAAEAAQABAAIAAgACgARABEAP4AAgAA" Text="ム" />
+ <Symbol Width="12" Data="4P8ABAAEoL+gpKC/oKSgpKC/IIDg/wAA" Text="画" />
+ <Symbol Width="12" Data="gCFAUiCEwHMAIOD3ICEgqWCpADEA4QAA" Text="鈴" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAAAD4ACAAIAAgAPgAAAAA" Text="ェ" />
+ <Symbol Width="12" Data="AAAAAAAIAAgAHwARACIADAACAAAAAAAA" Text="々" />
+ <Symbol Width="12" Data="AAAABAAkACQAJCAkICRAJIBEAEUAhgAA" Text="ル" />
+ <Symbol Width="12" Data="AAQABOD/IIQghCCE4P8ABAAEAAQABAAA" Text="中" />
+ <Symbol Width="8" Data="AAAAIAAgAD4A4gAkACQAKAAgACAAHgAA" Text="セ" />
+ <Symbol Width="12" Data="QEiAJOD/oKCAP4AggD+AIIA/IBLg4wAA" Text="覚" />
+ <Symbol Width="7" Data="AAAA+AAgACAAIAD8ACAAIAAgACAAHAAA" Text="モ" />
+ <Symbol Width="12" Data="AEQAJOAPIJggTyAJIA8gSSBPIIDAgAAA" Text="洵" />
+ <Symbol Width="6" Data="AEAAQAB4AEgAiACIAAgAEAAQACAAQAAA" Text="ク" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAKACoAIgAEAAQACAAQAAA" Text="ッ" />
+ <Symbol Width="7" Data="ACAAIAD8ACQAJAAkACQARABEAEQAmAAA" Text="カ" />
+ <Symbol Width="9" Data="AAAAAQCCAIIARABEAEQAKAAoABAAAAAA" Text="V" />
+ <Symbol Width="12" Data="ACIAKsBKQEtAzkBaQErASgBIIEjgTwAA" Text="他" />
+ <Symbol Width="12" Data="IEQgROB/AADgeSBJ4HkgSeB5IElgmgAA" Text="崩" />
+ <Symbol Width="12" Data="AATg/yCAACTAPwBEAATg/wAEAAQABAAA" Text="牢" />
+ <Symbol Width="12" Data="AAgACOD/AAgAEAAQwD9AUECQQBDAHwAA" Text="右" />
+ <Symbol Width="12" Data="oACgAAB/AAEAAgACAAQACgARgCBAwAAA" Text="ズ" />
+ <Symbol Width="12" Data="AAQABAAEwH8ABAAE4P8AAgACAAIAAgAA" Text="キ" />
+ <Symbol Width="12" Data="4P8ABAAEAAQABMB/AAQABAAEAATg/wAA" Text="王" />
+ <Symbol Width="6" Data="AEAAQABAAEAAYABQAEgAQABAAEAAQAAA" Text="ト" />
+ <Symbol Width="12" Data="gCOAcqBU4PtAUoBRYJYAAMB/QErg/wAA" Text="盤" />
+ <Symbol Width="12" Data="AAAAAAAAAACAAMD/AAAAAAAAAAAAAAAA" Text="一" />
+ <Symbol Width="12" Data="oASgBAAEwH8ABAAE4P8AAgACAAIAAgAA" Text="ギ" />
+ <Symbol Width="12" Data="AAgAUQAigBRACOD/IAQABIAkgCRARAAA" Text="糸" />
+ <Symbol Width="12" Data="ACHApwDxAKHgL0Aw4O9AIEAkQCLAIAAA" Text="特" />
+ <Symbol Width="7" Data="AAAAeAAAAAAA/AAQABAAEAAgACAAQAAA" Text="テ" />
+ <Symbol Width="7" Data="AAQACAAIABAAMABQAJAAEAAQABAAEAAA" Text="イ" />
+ <Symbol Width="12" Data="4C+gKuCvALTgr6AqoC8gIqBSIE/AgAAA" Text="燭" />
+ <Symbol Width="12" Data="oACgAAAgACGAIIAgQCBAQEBAQIAAAAAA" Text="バ" />
+ <Symbol Width="11" Data="AAQABMB/QEBAQEBAQECAAIAAAAMAHAAA" Text="ウ" />
+ <Symbol Width="12" Data="4E+AIoAC4I+gSqAK4AwgSOBPIIjgjwAA" Text="酒" />
+ <Symbol Width="12" Data="ACGgJ0Dx4C8AIcAzAObAK0AgQCCAYQAA" Text="拷" />
+ <Symbol Width="10" Data="gAKAggCAAIcA+ACAAIAAgACAAIAAfwAA" Text="ビ" />
+ <Symbol Width="12" Data="ACDAV0CEwHdAJMD3ICXApICkQCcg7AAA" Text="銀" />
+ <Symbol Width="12" Data="wH9AQMB/AEDgf4BIQF8AQsBfAILgvwAA" Text="屋" />
+ <Symbol Width="12" Data="ACDAJ0D0QCTAJ0A0QOTAJwAgACDgbwAA" Text="担" />
+ <Symbol Width="11" Data="ACAAIAD8ACCAJwAgAEAAQABIAIjAhwAA" Text="た" />
+ <Symbol Width="10" Data="ABAAEID/ABAAIAA/gGCAQIAAAAEAHgAA" Text="ち" />
+ <Symbol Width="12" Data="AEHgLwAAwIdARMAHAAEAQUBFIIkAgwAA" Text="涼" />
+ <Symbol Width="12" Data="4P8ABAAEAAQAB8AEAAQABAAEAAQABAAA" Text="下" />
+ <Symbol Width="12" Data="wEAAJwAE4IeARIAEgATgXwBAQIggkAAA" Text="浜" />
+ <Symbol Width="7" Data="AAAAQABAAEAAQABEAEQASABIAFAAYAAA" Text="レ" />
+ <Symbol Width="12" Data="AEDgRyDxIBEgISBRIOEgUSBCIELARAAA" Text="初" />
+ <Symbol Width="12" Data="ABHg/wARwH9ASuD/IIiAH4BoAAcAfAAA" Text="夢" />
+ <Symbol Width="12" Data="AEjgLwAQwI9ASkAK4B9ASkBK4I/AgAAA" Text="海" />
+ <Symbol Width="12" Data="ACDgJyD0ICTgJ4A0gOSAJEAkQCggaAAA" Text="択" />
+ <Symbol Width="12" Data="ACHgL6AqoPrgLwAh4C+gMsDMQBQgBwAA" Text="壊" />
+ <Symbol Width="12" Data="AATg/yCAgD8ACkB1gA6AckAOIHIADAAA" Text="家" />
+ <Symbol Width="12" Data="AATg/wAiwCNAQkBFgMSASgBBgEJgTAAA" Text="夜" />
+ <Symbol Width="12" Data="AATg/yCAACDALwBCwM9ASMBPQEjATwAA" Text="宿" />
+ <Symbol Width="12" Data="AAQABMB/AAQABOD/AAgAEYAQwCNAfAAA" Text="去" />
+ <Symbol Width="12" Data="AAIAggBE4AcgCQABACGAIoBCQEQgiAAA" Text="次" />
+ <Symbol Width="11" Data="AADAf0BAQEBAQEBAgACAAAABAAYAGAAA" Text="ワ" />
+ <Symbol Width="11" Data="AAAAAAAAABgAJABCAIGAAEAAAAAAAAAA" Text="へ" />
+ <Symbol Width="12" Data="AAQABgAFgASABIAEAAUABAAMABwAGAAA" Text="♪" />
+ <Symbol Width="8" Data="ABAAEAAQAP4AEAAQABAAEAAgACAAQAAA" Text="ナ" />
+ <Symbol Width="7" Data="AAAA/AAEACgAMAAgACAAIABAAEAAgAAA" Text="ア" />
+ <Symbol Width="12" Data="ABHg/4AggD+AIOD/ABGAJGDfAATAfwAA" Text="基" />
+ <Symbol Width="12" Data="AATAf4AgABHg/wAAgD+AIIA/gCCAPwAA" Text="音" />
+ <Symbol Width="12" Data="ACFAQoCWQCHgTwDCwENARoBKgEFgTgAA" Text="後" />
+ <Symbol Width="12" Data="AARARIAkAATAfwAEAATg/wAEAAQABAAA" Text="半" />
+ <Symbol Width="7" Data="AAAAgABAAEQABAAEAAgACAAQACAAwAAA" Text="ン" />
+ <Symbol Width="8" Data="AAAAeAAGAAAAcAAMAAAAAADwAA4AAAAA" Text="ミ" />
+ <Symbol Width="12" Data="AAHA8wAB4PdAAOD3QABA8kCRQJDA8AAA" Text="詩" />
+ <Symbol Width="12" Data="AEEAQeD3IBXgJyBFIOXgVwBBAEEAQQAA" Text="神" />
+
+ <Symbol Width="10" Data="AAAAAAAAAAAAd4AIgH8AiICIAHcAAAAA" Text="æ" />
+ <Symbol Width="6" Data="AAAAQAAgAAAAcAAIAHgAiACIAHgAAAAA" Text="à" />
+ <Symbol Width="6" Data="AAAAIABQAAAAcAAIAHgAiACIAHgAAAAA" Text="â" />
+ <Symbol Width="6" Data="AAAAAAAAAAAAcACIAIAAgACIAHAAIABA" Text="ç" />
+ <Symbol Width="6" Data="AAAAQAAgAAAAcACIAPgAgACIAHAAAAAA" Text="è" />
+ <Symbol Width="6" Data="AAAAIABQAAAAcACIAPgAgACIAHAAAAAA" Text="ê" />
+ <Symbol Width="6" Data="AAAAEAAgAAAAcACIAPgAgACIAHAAAAAA" Text="é" />
+ <Symbol Width="6" Data="AAAAAABQAAAAcACIAPgAgACIAHAAAAAA" Text="ë" />
+ <Symbol Width="4" Data="AAAAQACgAAAAQABAAEAAQABAAEAAAAAA" Text="î" />
+ <Symbol Width="4" Data="AAAAAACgAAAAQABAAEAAQABAAEAAAAAA" Text="ï" />
+ <Symbol Width="10" Data="AAAAAAAAAAAAd4CIgI8AiICIAHcAAAAA" Text="œ" />
+ <Symbol Width="6" Data="AAAAIABQAAAAcACIAIgAiACIAHAAAAAA" Text="ô" />
+ <Symbol Width="6" Data="AAAAQAAgAAAAiACIAIgAiACYAGgAAAAA" Text="ù" />
+ <Symbol Width="6" Data="AAAAIABQAAAAiACIAIgAiACYAGgAAAAA" Text="û" />
+ <Symbol Width="6" Data="AAAAAABQAAAAiACIAIgAiACYAGgAAAAA" Text="ü" />
+</SymbolTable>
diff --git a/VP-disasm.lua b/VP-disasm.lua
new file mode 100644
index 0000000..204b280
--- /dev/null
+++ b/VP-disasm.lua
@@ -0,0 +1,245 @@
+local function rd(self, addr)
+ self.fin:seek(addr * 4)
+ return self.fin:readU32()
+end
+
+local function rdn(self)
+ local r = self:rd(self.PC)
+ self.PC = self.PC + 1
+ return r
+end
+
+local opcodes_names = {
+-- 0x.0 0x.1 0x.2 0x.3 0x.4 0x.5 0x.6 0x.7 0x.8 0x.9 0x.a 0x.b 0x.c 0x.d 0x.e 0x.f
+ "SETV", "SETV", nil, nil, nil, nil, nil, nil, "MULG0","ADDG0","PSH", nil, nil, "PSH1?",nil, -- 0x0.
+ nil, nil, "PSH2?","PSHI", "CALL", "JMP", "JMPZ", "RET", "SETD", "PSH3?",nil, nil, nil, nil, nil, nil, -- 0x1.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x2.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x3.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x4.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x5.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x6.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0x7.
+ "STTRG",nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "SSTOP",nil, nil, nil, -- 0x8.
+ nil, nil, "TBOX", "TBOX2",nil, nil, nil, nil, "TBOX3",nil, nil, nil, nil, nil, "SETRM","CHGRM",-- 0x9.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xa.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xb.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xc.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xd.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xe.
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, -- 0xf.
+}
+
+local opcodes_imms = {
+-- 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0
+ 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, -- 1
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, -- 2
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -- 3
+ 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 5
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 6
+ 0, 2, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 7
+ 3, 0, 1, 2, 0, 4, 1, 1, 1, 0, 2, 0, 1, 0, 0, 2, -- 8
+ 0, 0, 3, 3, 3, 0, 0, 0, 3, 0, 0, 0, 0, 1, 1, 2, -- 9
+ 2, 2, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -- a
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- b
+ 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -- c
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -- d
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- e
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- f
+}
+
+-- 0 = nothing
+-- 1 = low8
+-- 2 = low16
+-- 3 = low23
+-- 4 = high8
+-- 5 = var_idx
+-- 6 = var_idx2
+-- 7 = low8 + high8
+
+local opcodes_self_vals = {
+-- 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ 5, 5, 0, 0, 0, 0, 0, 0, 3, 3, 5, 0, 0, 2, 0, -- 0
+ 0, 0, 3, 0, 3, 3, 3, 0, 6, 0, 0, 0, 0, 0, 0, 0, -- 1
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 2
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 3
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 5
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 6
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 7
+ 2, 2, 2, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0, 2, 1, 0, -- 8
+ 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 7, 2, 0, -- 9
+ 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, -- a
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, -- b
+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- c
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- d
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- e
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- f
+}
+
+local opcodes_nparams = {
+-- 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 1, 0, 0, 1, 0, -- 0
+ 0, 0, 1, 1, 1, 1, 2, 0, 2, 1, 1, 0, 0, 0, 0, 0, -- 1
+ 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, -- 2
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -- 3
+ 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 5
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 6
+ 0, 0, 1, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, -- 7
+ 4, 1, 2, 4, 0, 5, 2, 2, 2, 0, 3, 0, 1, 1, 1, 5, -- 8
+ 0, 0, 7, 7, 6, 0, 0, 0, 7, 0, 0, 0, 0, 3, 2, 4, -- 9
+ 6, 2, 2, 6, 0, 0, 0, 0, 2, 1, 0, 1, 0, 0, 0, 0, -- a
+ 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, -- b
+ 2, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -- c
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 1, 0, 0, -- d
+ 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- e
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- f
+}
+
+local opcodes_known = {
+-- 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ true, true, false, false, false, false, false, false, true, true, true, false, false, true, false, -- 0
+ false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, -- 1
+ false, true, true, true, true, true, true, true, true, true, true, false, false, false, true, false, -- 2
+ false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, -- 3
+ false, true, true, true, true, true, false, false, false, true, false, false, false, false, false, false, -- 4
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 5
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 6
+ true, true, true, true, true, true, true, false, true, false, false, true, true, false, true, false, -- 7
+ true, true, true, true, false, true, true, true, true, true, true, false, true, true, true, true, -- 8
+ false, true, true, true, true, false, false, false, true, false, false, false, false, true, true, true, -- 9
+ true, true, true, true, false, false, false, false, true, true, false, true, false, false, false, false, -- a
+ true, false, true, false, false, false, false, false, true, false, false, true, false, false, true, false, -- b
+ true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, -- c
+ false, false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, -- d
+ true, false, false, false, false, false, true, false, false, false, false, true, false, false, false, false, -- e
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- f
+}
+
+local opcodes_fromstack = {
+-- 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 0
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 1
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 2
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 3
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 4
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 5
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- 6
+ false, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, -- 7
+ true, true, true, true, false, true, true, true, true, false, true, false, true, false, true, true, -- 8
+ false, false, true, true, true, false, false, false, true, false, false, false, false, true, true, true, -- 9
+ true, true, true, true, false, false, false, false, true, true, false, true, false, false, false, false, -- a
+ false, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, -- b
+ true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, -- c
+ false, false, false, false, false, false, false, false, false, true, true, false, false, true, false, false, -- d
+ false, false, false, false, false, false, true, false, false, false, false, true, false, false, false, false, -- e
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- f
+}
+
+local function disasm_opcode(self)
+ self.oPC = self.PC
+ self.opcode = self:rdn()
+ self.code = shr(self.opcode, 24)
+ self.imm8 = andB(self.opcode, 0xff)
+ self.imm16 = andB(self.opcode, 0xffff)
+ self.imm23 = andB(self.opcode, 0x7fffff)
+ self.high8 = andB(shr(self.opcode, 8), 0xff)
+ self.idx2 = shr(shl(self.opcode, 9), 12)
+ self.flags = {}
+ self.flags.is_local = andB(self.opcode, 0x800000) ~= 0
+ self.flags.from_stack = andB(self.opcode, 0x100000) ~= 0
+
+ self.out:write(string.format("%08X %08X ", self.oPC, self.opcode))
+
+ if self.code == 0 then
+ self.out:write("OPCODE00?!")
+ return
+ end
+
+ local name = opcodes_names[self.code]
+
+ if name then
+ self.out:write(string.format("%-8s", name))
+ elseif opcodes_known[self.code] then
+ self.out:write(string.format("OP_%02X ", self.code))
+ else
+ self.out:write(string.format("UNK%02X ", self.code))
+ end
+
+ if self.flags.from_stack and opcodes_fromstack[self.code] then
+ for i = 1, opcodes_nparams[self.code] do
+ self.out:write("POP()")
+ if i ~= opcodes_nparams[self.code] then self.out:write(", ") end
+ end
+ else
+ local nargs = opcodes_nparams[self.code]
+ local sv = opcodes_self_vals[self.code]
+ if false then
+ -- 0 = nothing
+ -- 1 = low8
+ -- 2 = low16
+ -- 3 = low23
+ -- 4 = high8
+ -- 5 = var_idx
+ -- 6 = var_idx2
+ -- 7 = low8 + high8
+ elseif sv == 1 then
+ self.out:write(string.format("%02X", self.imm8))
+ nargs = nargs - 1
+ elseif sv == 2 then
+ self.out:write(string.format("%04X", self.imm16))
+ nargs = nargs - 1
+ elseif sv == 3 then
+ self.out:write(string.format("%08X", self.imm23))
+ nargs = nargs - 1
+ elseif sv == 4 then
+ self.out:write(string.format("%02X", self.high8))
+ nargs = nargs - 1
+ elseif sv == 5 then
+ self.out:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.imm16))
+ nargs = nargs - 1
+ elseif sv == 6 then
+ self.out:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.idx2))
+ nargs = nargs - 1
+ elseif sv == 7 then
+ self.out:write(string.format("%02X, %02X", self.imm8, self.high8))
+ nargs = nargs - 2
+ end
+
+ if sv ~= 0 and nargs ~= 0 then
+ self.out:write(", ")
+ end
+
+ for i = 1, opcodes_imms[self.code] do
+ self.out:write(string.format("%08X", self:rdn()))
+ if i ~= opcodes_imms[self.code] then self.out:write(", ") end
+ nargs = nargs - 1
+ end
+
+ if not opcodes_fromstack[self.code] then
+ for i = 1, nargs do
+ self.out:write("POP()")
+ if i ~= nargs then self.out:write(", ") end
+ end
+ end
+ end
+
+ if self.hooks[self.code] then self.hooks[self.code](self.oPC) end
+end
+
+local function disasm(self)
+ while self.PC ~= self.EPC do
+ self:disasm_opcode()
+ self.out:write("\n")
+ for padPC = self.oPC + 1, self.PC - 1 do
+ self.out:write(string.format(" %08X\n", self:rd(padPC)))
+ end
+ end
+end
+
+function logic_disasm(logic, o, hooks)
+ local dobj = { rd = rd, rdn = rdn, disasm_opcode = disasm_opcode, disasm = disasm, PC = 0, fin = logic, out = o, EPC = logic:getsize() / 4, hooks = hooks }
+ dobj:disasm()
+end
diff --git a/VP-fontwork.lua b/VP-fontwork.lua
new file mode 100644
index 0000000..4029227
--- /dev/null
+++ b/VP-fontwork.lua
@@ -0,0 +1,93 @@
+function put_extra_glyph(width, data)
+ local idx = width .. "-" .. data
+ if not extra_glyphs_file then extra_glyphs_file = Output "extra-glyphs.xml" end
+ if extra_glyphs[idx] then return end
+ extra_glyphs_file:write(' <Symbol Width="' .. width .. '" Data="' .. data .. '" Text="Unknown" />\n')
+ extra_glyphs[idx] = true
+end
+
+function resolve_font(font)
+ local r = {}
+
+ for k, v in pairs(font) do
+ local idx = v.Width .. "-" .. v.Data
+ local g = glyphes[idx]
+ if not g then
+ put_extra_glyph(v.Width, v.Data)
+ r[k] = "<??>"
+ else
+ r[k] = g.attr.Text
+ end
+ end
+
+ return r
+end
+
+function extract_font(fname, h)
+ local n_glyphes = h:readU32()
+ local height = h:readU32()
+ local widths = {}
+
+ for i = 1, n_glyphes do
+ widths[i] = h:readU8()
+ end
+
+ local o
+ local r = {}
+
+ if dump_glyph then
+ dump_mkdir(fname)
+ end
+
+ for i = 1, n_glyphes do
+ if dump_mode and dump_glyph then
+ o = Output(fname .. string.format("/%03i-%02i.glyph", i, widths[i]))
+ o:copyfrom(h, height * 2)
+ o:destroy()
+ h:seek(-height * 2, SEEK_CUR)
+ o = Output(fname .. string.format("/%03i-%02i.raw", i, widths[i]))
+ local bits
+ for j = 1, height do
+ bits = h:readU16()
+ for k = 1, height do -- should be widths[i]
+ bits = shl(bits, 1)
+ local bit = andB(bits, 65536) ~= 0
+ o:writeU8(bit and 0xff or 0)
+ end
+ end
+ o:destroy()
+ h:seek(-height * 2, SEEK_CUR)
+ end
+ local b = Buffer(true)
+ b:copyfrom(h, height * 2)
+ if widths[i] ~= 0 then
+ r[i] = { Data = Base64Encode(b), Width = widths[i] }
+ else
+ -- Verify this is only padding
+ local Data = Base64Encode(b)
+ if Data ~= "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" then
+ error("Font not consistant.")
+ end
+ end
+ b:destroy()
+ end
+
+ return r
+end
+
+function add_glyph(font, char)
+ local idx = font.idx
+ font.ilookup[idx] = char
+ font.clookup[char] = idx
+ font.idx = font.idx + 1
+ return idx
+end
+
+function load_glyphes()
+ local tglyphes = xml.LoadHandle(Input "VP-database.xml")[1]
+ glyphes = {}
+ for k, v in ipairs(tglyphes) do
+ glyphes[v.attr.Width .. "-" .. v.attr.Data] = v
+ glyphes[v.attr.Text] = v
+ end
+end
diff --git a/VP-indexwork.lua b/VP-indexwork.lua
new file mode 100644
index 0000000..a6bc08c
--- /dev/null
+++ b/VP-indexwork.lua
@@ -0,0 +1,240 @@
+local makepfs_sig = {
+ 0x4d, 0x61, 0x6b, 0x65, 0x50, 0x66, 0x73, 0x20,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x31,
+ 0x2e, 0x32, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+}
+
+function load_psp_index(cdutil)
+ local pspval1_ent = cdutil:findpath "/PSP_GAME/USRDIR/PSPVAL1.PFS"
+ if not pspval1_ent then error "VP-PSP iso seems wrong..." end
+ local pspval1 = cdutil:cdfile(pspval1_ent)
+
+ for k, v in ipairs(makepfs_sig) do
+ if pspval1:readU8() ~= v then error "Wrong MakePfs signature." end
+ end
+ num_entries = pspval1:readU32()
+ num_files = num_entries
+
+ local idx_pos = pspval1:readU32()
+ local index = {}
+
+ pspval1:seek(2048 * idx_pos + 4)
+ local last_sector = 1
+ for i = 1, num_entries - 1 do
+ local sector = pspval1:readU32()
+ local abssector = pspval1_ent.Sector + sector
+ index[i] = { sector = abssector, cd = cdutil }
+ if i ~= 1 then
+ index[i - 1].size = sector - last_sector
+ end
+ last_sector = sector
+ end
+ index[num_entries - 1].size = idx_pos - last_sector
+
+ for i = 1, num_entries - 1 do
+ if index[i].size == 0 then index[i] = nil else log("Entry " .. i .. ", sector " .. index[i].sector .. ", nsectors = " .. index[i].size) end
+ end
+
+ return index
+end
+
+function load_index(cdutil)
+ if got_psp then return load_psp_index(cdutil) end
+ local vp_sec, cfat, csiz, fat, siz, fkey, skey, fkey_pos, skey_pos
+
+ vp_sec = 150
+ cfat = cdutil:cdfile(vp_sec, num_entries * 4)
+ csiz = cdutil:cdfile(vp_sec + num_entries * 4 / 2048, num_entries)
+ fat = Buffer(true)
+ siz = Buffer(true)
+ fkey = Buffer(true)
+ skey = Buffer(true)
+ cfat:seek(num_entries * 4 - fkey_size)
+ csiz:seek(num_entries - skey_size)
+ fkey:copyfrom(cfat, fkey_size)
+ skey:copyfrom(csiz, skey_size)
+ cfat:seek(0)
+ csiz:seek(0)
+
+ fkey_pos = 0
+ skey_pos = 0
+
+ print "Decrypting index..."
+ for i = 0, (num_entries * 4 - 1) do
+ fat:writeU8(xorB(cfat:readU8(), fkey:readU8()))
+ fkey_pos = fkey_pos + 1
+ if fkey_pos == fkey_size then
+ fkey_pos = 0
+ fkey:seek(0)
+ end
+ end
+
+ for i = 0, (num_entries - 1) do
+ siz:writeU8(xorB(csiz:readU8(), skey:readU8()))
+ skey_pos = skey_pos + 1
+ if skey_pos == skey_size then
+ skey_pos = 0
+ skey:seek(0)
+ end
+ end
+
+ cfat:destroy()
+ csiz:destroy()
+ fkey:seek(0)
+ skey:seek(0)
+
+ print "Done."
+
+ local o, m, s, f, size_high, size
+
+ local fr = fat:readU32()
+ local sr = siz:readU8()
+ local index = {}
+ for i = 1, (num_entries - 1) do
+ m = fat:readU8()
+ s = fat:readU8()
+ f = fat:readU8()
+ size_high = fat:readU8()
+ sector = from_MSF(m, s, f)
+ size = siz:readU8() + size_high * 256
+ if (sector ~= 4294967146) then
+ log("Entry " .. i .. ", sector " .. sector .. ", nsectors = " .. size)
+ index[i] = { sector = sector, size = size, cd = cdutil }
+ end
+ end
+ fat:destroy()
+ siz:destroy()
+
+ return index, fkey, skey, fr, sr
+end
+
+function add_file(cindex, iso, file, i)
+ local size_full = math.ceil(file:getsize() / 2048)
+ local dest_sector = iso:putfile(file)
+ local _, m, s, f = to_MSF(dest_sector)
+ local size_high = math.floor(size_full / 256)
+ local size = size_full - size_high * 256
+ log("Putting file " .. i .. " at " .. dest_sector .. " - size = " .. size_full)
+ cindex.fat:wseek(i * 4)
+ cindex.siz:wseek(i)
+ cindex.fat:writeU8(m)
+ cindex.fat:writeU8(s)
+ cindex.fat:writeU8(f)
+ cindex.fat:writeU8(size_high)
+ cindex.siz:writeU8(size)
+end
+
+function close_index(cindex, iso)
+ for i = cindex.fat:getsize(), (num_entries * 4 - 1) do
+ cindex.fat:writeU8(0)
+ end
+
+ for i = cindex.siz:getsize(), (num_entries - 1) do
+ cindex.siz:writeU8(0)
+ end
+
+ local fkey_pos = 0
+ local skey_pos = 0
+ local cfat = Buffer(true)
+ local csiz = Buffer(true)
+ cindex.fat:seek(0)
+ cindex.siz:seek(0)
+ cindex.fkey:seek(0)
+ cindex.skey:seek(0)
+
+ for i = 0, (num_entries * 4 - 1) do
+ cfat:writeU8(xorB(cindex.fat:readU8(), cindex.fkey:readU8()))
+ fkey_pos = fkey_pos + 1
+ if fkey_pos == fkey_size then
+ fkey_pos = 0
+ cindex.fkey:seek(0)
+ end
+ end
+
+ for i = 0, (num_entries - 1) do
+ csiz:writeU8(xorB(cindex.siz:readU8(), cindex.skey:readU8()))
+ skey_pos = skey_pos + 1
+ if skey_pos == skey_size then
+ skey_pos = 0
+ cindex.skey:seek(0)
+ end
+ end
+
+ iso:putfile(cfat, -1, 150)
+ iso:putfile(csiz, -1, 160)
+
+ cfat:destroy()
+ csiz:destroy()
+end
+
+function psp_add_file(cindex, iso, file, i)
+ local size_full = math.ceil(file:getsize() / 2048)
+ local dest_sector = iso:putfile(file)
+ cindex.index[i] = { size = size_fill, sector = dest_sector }
+ log("Putting file " .. i .. " at " .. dest_sector .. " - size = " .. size_full)
+end
+
+function copyfile(path, name, dirtree, iso, cdutil)
+ local dirent = cdutil:findpath(path .. "/" .. name)
+ if not dirent then error("Failing finding path " .. path .. "/" .. name) end
+ iso:createfile(dirtree, name, cdutil:cdfile(dirent), dirent):setbasicsxa()
+end
+
+function psp_close_index(cindex, iso, cdutil)
+ local index_sec = iso:getdispsect()
+ local indexfile = Buffer(true)
+ local indexhead = Buffer(true)
+ indexhead:write "MakePfs Version1.20"
+ indexhead:writeU8(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(num_files)
+ indexhead:writeU32(index_sec - pspval1_sec)
+ indexhead:writeU32(0)
+ for i = indexhead:getsize(), 2047 do
+ indexhead:writeU8(0x98)
+ end
+ iso:putfile(indexhead, -1, pspval1_sec)
+ indexfile:writeU32(1)
+ local last_entry = nil
+ for i = 1, num_files - 1 do
+ if cindex.index[i] then
+ last_entry = cindex.index[i].sector - pspval1_sec
+ indexfile:writeU32(last_entry)
+ else
+ indexfile:writeU32(last_entry)
+ end
+ end
+ local more_bytes = alignment(indexfile:getsize(), 2048)
+ for i = 1, more_bytes do
+ indexfile:writeU8(0x98)
+ end
+ iso:putfile(indexfile)
+ psp_dirtrees.PSPVAL1.size = (iso:getdispsect() - pspval1_sec) * 2048
+
+ indexfile:destroy()
+ indexhead:destroy()
+
+ local cp = function(path, name, dirtree) copyfile(path, name, dirtree, iso, cdutil) end
+ for _, f in ipairs { "Field_master.prx", "Camp_master.prx", "MiniMap_master.prx", "WldMap_master.prx", "GodCamp_master.prx", "moviepac.dat" } do
+ cp("/PSP_GAME/USRDIR", f, psp_dirtrees.USRDIR)
+ end
+end
+
+function prepare_index(iso, fkey, skey, fr, sr)
+ if got_psp then
+ return { add_file = psp_add_file, close_index = psp_close_index, index = { } }
+ end
+
+ local false_sect = {}
+ for i = 1, 13 do
+ iso:createsector(false_sect, MODE2_FORM1)
+ end
+ local ret = { fat = Buffer(true), siz = Buffer(true), fkey = fkey, skey = skey, add_file = add_file, close_index = close_index }
+ ret.fat:writeU32(fr)
+ ret.siz:writeU8(sr)
+
+ return ret
+end
diff --git a/VP-isowork.lua b/VP-isowork.lua
new file mode 100644
index 0000000..4b9efb2
--- /dev/null
+++ b/VP-isowork.lua
@@ -0,0 +1,163 @@
+load "VP-slz3-patch.lua"
+
+function apply_hacks(hacks, file)
+ local k, v, i, h
+
+ for k, v in pairs(hacks) do
+ for i, h in ipairs(v) do
+ file[k + i - 1] = h
+ end
+ end
+end
+
+function prepare_out(file_out)
+ if got_psp then
+ local x = Output "VP-FR.iso"
+ x:destroy()
+ globals[3] = dvdabstract(file_out or "VP-FR.iso", true)
+ else
+ globals[3] = Output(file_out or "VP-FR.bin")
+ end
+ local iso = isobuilder(globals[3])
+ return iso
+end
+
+function startup(file_in, file_in2, iso_out)
+ if not loadmodule then error("This can only be used with lua-interface...") end
+ loadmodule "lualibs"
+ loadmodule "luahandle"
+ loadmodule "luacd"
+ loadmodule "luaslz"
+ loadmodule "luahttp"
+ loadmodule "luaxml"
+-- globals[1] = cdabstract(file_in or "VP-SQUISH.bin")
+ globals[1] = dvdabstract(file_in or "VP-PSP-EUR.iso")
+ local cdutil = cdutils(globals[1])
+ if file_in2 then
+ globals[2] = cdabstract(file_in2)
+ local cdutil2 = cdutils(globals[2])
+ end
+ return cdutil, cdutil2, iso_out
+end
+
+anti_cd_swap_hack = {
+ [0x278C] = { 0x00, 0x00, 0x00, 0x00 },
+ [0x27A0] = { 0x00, 0x00, 0x00, 0x00 },
+ [0x27B4] = { 0x21, 0x10, 0x00, 0x00 },
+ [0x2820] = { 0x00, 0x00, 0x00, 0x00 },
+}
+
+function iso_identify(cdutil)
+ local slusdirentuscd1 = cdutil:findpath "/SLUS_011.56;1"
+ local slusdirentuscd2 = cdutil:findpath "/SLUS_011.79;1"
+ local slusdirentjpcd1 = cdutil:findpath "/SLPM_863_79;1"
+ local slusdirentjpcd2 = cdutil:findpath "/SLPM_863_80;1"
+ local slusdirentsquished = cdutil:findpath "/VALKYRIE.EXE;1"
+ local pspdata = cdutil:findpath "/UMD_DATA.BIN"
+ if pspdata then
+ local pspdataf = cdutil:cdfile(pspdata)
+ local umddata = pspdataf:read()
+ if umddata == "ULUS-10107|400F6E7A41D6C586|0001|G" then
+ got_us = true
+ elseif umddata == "ULES-00724|2A9CD5DEEA986357|0001|G" then
+ got_eu = true
+ elseif umddata == "ULJM-05101|7862BF3F2632E5B5|0001|G" then
+ got_jp = true
+ else
+ error "Wrong PSP iso."
+ end
+
+ got_psp = true
+ end
+
+ if slusdirentuscd1 and got_cd1 then error "Got twice CD1." end
+ if slusdirentuscd2 and got_cd2 then error "Got twice CD2." end
+
+ if slusdirentuscd1 or slusdirentuscd2 then got_us = true end
+ if slusdirentjpcd1 or slusdirentjpcd2 then got_jp = true end
+ if slusdirentuscd1 or slusdirentjpcd1 then got_cd1 = true end
+ if slusdirentuscd2 or slusdirentjpcd2 then got_cd2 = true end
+
+ if slusdirentsquished then
+ got_cd1 = true
+ got_cd2 = true
+ -- let's fallback...
+ got_us = true
+ end
+
+ if not slusent then
+ slusent = slusdirentuscd1 or slusdirentuscd2 or slusdirentjpcd1 or slusdirentjpcd2 or slusdirentsquished
+ end
+
+ if got_us and got_jp then error "2 isos must from the same version of the game." end
+end
+
+function build_basic(iso, cdutil, iso_full)
+ local cp = function(path, name, dirtree) copyfile(path, name, dirtree, iso, cdutil) end
+ iso:foreword(cdutil)
+ local pvd = createpvd(cdutil)
+ pvd.volid = "VP-FR"
+ local root = iso:setbasics(pvd)
+ dirent = cdutil:findpath "/"
+ root:setbasicsxa()
+ root:fromdir(dirent)
+ if got_psp then
+ root:setdvdmode()
+ psp_dirtrees.root = root
+ psp_dirtrees.PSP_GAME = iso:createdir(root, "PSP_GAME", 1, cdutil:findpath "/PSP_GAME")
+ psp_dirtrees.PSP_GAME:setbasicsxa()
+ psp_dirtrees.SYSDIR = iso:createdir(psp_dirtrees.PSP_GAME, "SYSDIR", 1, cdutil:findpath "/PSP_GAME/SYSDIR")
+ psp_dirtrees.SYSDIR:setbasicsxa()
+ psp_dirtrees.USRDIR = iso:createdir(psp_dirtrees.PSP_GAME, "USRDIR", 1, cdutil:findpath "/PSP_GAME/USRDIR")
+ psp_dirtrees.USRDIR:setbasicsxa()
+--[[
+ psp_dirtrees.kmodule = iso:createdir(psp_dirtrees.USRDIR, "kmodule", 1, cdutil:findpath "/PSP_GAME/USRDIR/kmodule")
+ psp_dirtrees.kmodule:setbasicsxa()
+--]]
+ cp("", "UMD_DATA.BIN", root)
+ cp("/PSP_GAME/SYSDIR", "EBOOT.BIN", psp_dirtrees.SYSDIR)
+ cp("/PSP_GAME/SYSDIR", "BOOT.BIN", psp_dirtrees.SYSDIR)
+ for _, f in ipairs { "PARAM.SFO", "ICON0.PNG", "PIC0.PNG", "PIC1.PNG" } do
+ cp("/PSP_GAME", f, psp_dirtrees.PSP_GAME)
+ end
+--[[
+ for _, prx in ipairs { "audiocodec.prx", "libatrac3plus.prx", "mpeg.prx", "mpegbase.prx", "psmf.prx", "sc_sascore.prx", "videocodec.prx" } do
+ cp("/PSP_GAME/USRDIR/kmodule", prx, psp_dirtrees.kmodule)
+ end
+]]--
+ for _, prx in ipairs { "Title_master.prx", "Staff_master.prx", "Battle_master.prx" } do
+ cp("/PSP_GAME/USRDIR", prx, psp_dirtrees.USRDIR)
+ end
+ pspval1_sec = iso:getdispsect()
+ local dummy = Buffer()
+ dummy:writeU8(0)
+ local dirent = cdutil:findpath "/PSP_GAME/USRDIR/PSPVAL1.PFS"
+ psp_dirtrees.PSPVAL1 = iso:createfile(psp_dirtrees.USRDIR, "PSPVAL1.PFS", dummy, dirent)
+ psp_dirtrees.PSPVAL1:setbasicsxa()
+ dummy:destroy()
+ else
+ local systemcnfstring = "BOOT=cdrom:\\VP-FR.EXE;1\r\nTCB=4\r\nEVENT=16\r\nSTACK=801fff00\r\n"
+ local systemcnf = Buffer()
+ local slus = Buffer(true)
+ slus:copyfrom(cdutil:cdfile(slusdirent))
+ slus:seek(0)
+ systemcnf:write(systemcnfstring)
+ local dirent = cdutil:findpath("/SYSTEM.CNF;1")
+ iso:createfile(root, "SYSTEM.CNF", systemcnf, dirent):setbasicsxa()
+ if iso_full then
+ apply_hacks(anti_cd_swap_hack, slus)
+ end
+ apply_hacks(slz3_patch, slus)
+ slus:seek(0)
+ iso:createfile(root, "VP-FR.EXE", slus, slusdirent):setbasicsxa()
+ slus:seek(0)
+ local readme = Buffer()
+ readme:write("Readme...")
+ iso:createfile(root, "README.TXT", readme, dirent):setbasicsxa()
+ local cursect = iso:getdispsect()
+ local falsesect = {}
+ for i = cursect, 149 do
+ iso:createsector(falsesect, MODE2_FORM1)
+ end
+ end
+end
diff --git a/VP-map.lua b/VP-map.lua
new file mode 100644
index 0000000..415ca97
--- /dev/null
+++ b/VP-map.lua
@@ -0,0 +1,171 @@
+VP_maintypes = {
+ "VIDEOS",
+ "SOUNDS",
+ "GFX",
+ "MAIN",
+ "GAME",
+}
+
+VP_map = { }
+
+VP_map_spans = {
+ { idx_s = 3604, idx_e = 4732, data = { dir = "GAME/ROOMS", ext = "arm", ftype = "arcroom", }, },
+}
+
+VP_map_spans = {
+ { idx_s = 3721, idx_e = 4849, data = { dir = "GAME/ROOMS", ext = "arm", ftype = "arcroom", }, },
+}
+
+VP_map_spans = {
+ { idx_s = 9, idx_e = 131, data = { dir = "SOUNDS/ATK+DEATH", ext = "wag" }, },
+ { idx_s = 132, idx_e = 365, data = { dir = "SOUNDS/SUMMONS+NAMES", ext = "wag" }, },
+ { idx_s = 366, idx_e = 417, data = { dir = "SOUNDS/FINISH", ext = "wag" }, },
+ { idx_s = 418, idx_e = 617, data = { dir = "SOUNDS/ENDS", ext = "wag" }, },
+ { idx_s = 619, idx_e = 897, data = { dir = "SOUNDS/FAILED+MAGICS", ext = "wag" }, },
+ { idx_s = 898, idx_e = 1020, data = { dir = "SOUNDS/BOSS", ext = "wag" }, },
+ { idx_s = 1022, idx_e = 1525, data = { dir = "GFX/FRIENDS+FOES", ext = "agx", ftype = "arcgfx" }, },
+ { idx_s = 1526, idx_e = 1637, data = { dir = "SOUNDS/COMBATTALKS", ext = "wag" }, },
+ { idx_s = 1639, idx_e = 1661, data = { dir = "GFX/UNKNOWN01", ext = "agx", ftype = "arcgfx", }, },
+ { idx_s = 1662, idx_e = 1687, data = { dir = "SOUNDS/UNKNOWN01", ext = "wag" }, },
+ { idx_s = 1688, idx_e = 1698, data = { dir = "GFX/UNKNOWN02", ext = "agx", ftype = "arcgfx", }, },
+ { idx_s = 1700, idx_e = 1704, data = { dir = "GFX/UNKNOWN03", ext = "agx", ftype = "arcgfx", }, },
+ { idx_s = 1705, idx_e = 1805, data = { dir = "SOUNDS/UNKNOWN02", ext = "wag" }, },
+ { idx_s = 1806, idx_e = 1810, data = { dir = "GFX/UNKNOWN04", ext = "agx", ftype = "arcgfx", }, },
+ { idx_s = 1811, idx_e = 1823, data = { dir = "SOUNDS/MAGIC01", ext = "wag" }, },
+ { idx_s = 1826, idx_e = 1837, data = { dir = "SOUNDS/MAGIC02", ext = "wag" }, },
+ { idx_s = 1840, idx_e = 1852, data = { dir = "SOUNDS/MAGIC03", ext = "wag" }, },
+ { idx_s = 1855, idx_e = 1866, data = { dir = "SOUNDS/MAGIC04", ext = "wag" }, },
+ { idx_s = 1869, idx_e = 1880, data = { dir = "SOUNDS/MAGIC05", ext = "wag" }, },
+ { idx_s = 1883, idx_e = 1894, data = { dir = "SOUNDS/MAGIC06", ext = "wag" }, },
+ { idx_s = 1897, idx_e = 1908, data = { dir = "SOUNDS/MAGIC07", ext = "wag" }, },
+ { idx_s = 1911, idx_e = 1923, data = { dir = "SOUNDS/MAGIC08", ext = "wag" }, },
+ { idx_s = 1926, idx_e = 1938, data = { dir = "SOUNDS/MAGIC09", ext = "wag" }, },
+ { idx_s = 1941, idx_e = 1953, data = { dir = "SOUNDS/MAGIC10", ext = "wag" }, },
+ { idx_s = 1956, idx_e = 1967, data = { dir = "SOUNDS/MAGIC11", ext = "wag" }, },
+ { idx_s = 1970, idx_e = 1982, data = { dir = "SOUNDS/MAGIC12", ext = "wag" }, },
+ { idx_s = 1985, idx_e = 1985, data = { dir = "SOUNDS/MAGIC13", ext = "wag" }, },
+ { idx_s = 1988, idx_e = 2017, data = { dir = "GFX/UNKNOWN05", ext = "agx", ftype = "arcgfx", }, },
+ { idx_s = 2018, idx_e = 2095, data = { dir = "SOUNDS/DEATHS", ext = "wag" }, },
+ { idx_s = 2096, idx_e = 2097, data = { dir = "SOUNDS/UNKNOWN03", ext = "wag", }, },
+ { idx_s = 2098, idx_e = 2172, data = { dir = "SOUNDS/VICTORY", ext = "wag", }, },
+
+ { idx_s = 3604, idx_e = 4732, data = { dir = "GAME/ROOMS", ext = "arm", ftype = "arcroom", }, },
+
+ { idx_s = 4766, idx_e = 4793, data = { dir = "GFX/CDCHANGE", ext = "tim" }, },
+ { idx_s = 4808, idx_e = 4846, data = { dir = "GFX/PORTRAITS", ext = "tim" }, },
+ { idx_s = 4847, idx_e = 4859, data = { dir = "GFX/BGX", ext = "tim" }, },
+}
+
+VP_map = {
+ [ 1] = { dir = "MAIN/OVERLAY" },
+ [ 2] = { dir = "MISC", ext = "txt" },
+ [ 3] = { dir = "MISC", ext = "txt" },
+ [ 4] = { dir = "MAIN/SOUNDS", ext = "wag" },
+ [ 5] = { dir = "MAIN/GFX" },
+
+ [ 618] = { dir = "SOUNDS/MISC", ext = "wag" },
+ [1021] = { dir = "SOUNDS/MISC", ext = "wag" },
+
+ -- unknow file in the middle of gfx bloc - is it an overlay ?
+ [1490] = { },
+
+ [1824] = { dir = "GFX/MAGIC01", ext = "agx", ftype = "arcgfx", },
+ [1838] = { dir = "GFX/MAGIC02", ext = "agx", ftype = "arcgfx", },
+ [1853] = { dir = "GFX/MAGIC03", ext = "agx", ftype = "arcgfx", },
+ [1867] = { dir = "GFX/MAGIC04", ext = "agx", ftype = "arcgfx", },
+ [1881] = { dir = "GFX/MAGIC05", ext = "agx", ftype = "arcgfx", },
+ [1895] = { dir = "GFX/MAGIC06", ext = "agx", ftype = "arcgfx", },
+ [1909] = { dir = "GFX/MAGIC07", ext = "agx", ftype = "arcgfx", },
+ [1924] = { dir = "GFX/MAGIC08", ext = "agx", ftype = "arcgfx", },
+ [1939] = { dir = "GFX/MAGIC09", ext = "agx", ftype = "arcgfx", },
+ [1954] = { dir = "GFX/MAGIC10", ext = "agx", ftype = "arcgfx", },
+ [1968] = { dir = "GFX/MAGIC11", ext = "agx", ftype = "arcgfx", },
+ [1983] = { dir = "GFX/MAGIC12", ext = "agx", ftype = "arcgfx", },
+ [1986] = { dir = "GFX/MAGIC13", ext = "agx", ftype = "arcgfx", },
+
+--
+-- Videos
+--
+
+-- Intro
+ [ 8] = { dir = "VIDEOS/MISC", ext = "str" },
+-- Magics
+ [1825] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1839] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1854] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1868] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1882] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1896] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1910] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1940] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1955] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1969] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1984] = { dir = "VIDEOS/MAGIC", ext = "str" },
+ [1987] = { dir = "VIDEOS/MAGIC", ext = "str" },
+-- Small level videos
+ [3507] = { dir = "VIDEOS/LEVEL01", ext = "str" },
+ [3509] = { dir = "VIDEOS/LEVEL02", ext = "str" },
+ [3510] = { dir = "VIDEOS/LEVEL02", ext = "str" },
+ [3512] = { dir = "VIDEOS/LEVEL03", ext = "str" },
+ [3515] = { dir = "VIDEOS/LEVEL04", ext = "str" },
+ [3516] = { dir = "VIDEOS/LEVEL04", ext = "str" },
+ [3518] = { dir = "VIDEOS/LEVEL05", ext = "str" },
+ [3521] = { dir = "VIDEOS/LEVEL06", ext = "str" },
+ [3523] = { dir = "VIDEOS/LEVEL07", ext = "str" },
+ [3525] = { dir = "VIDEOS/LEVEL08", ext = "str" },
+ [3526] = { dir = "VIDEOS/LEVEL08", ext = "str" },
+ [3527] = { dir = "VIDEOS/LEVEL08", ext = "str" },
+ [3528] = { dir = "VIDEOS/LEVEL08", ext = "str" },
+ [3530] = { dir = "VIDEOS/LEVEL09", ext = "str" },
+ [3531] = { dir = "VIDEOS/LEVEL09", ext = "str" },
+ [3532] = { dir = "VIDEOS/LEVEL09", ext = "str" },
+ [3534] = { dir = "VIDEOS/LEVEL10", ext = "str" },
+ [3535] = { dir = "VIDEOS/LEVEL10", ext = "str" },
+ [3536] = { dir = "VIDEOS/LEVEL10", ext = "str" },
+ [3537] = { dir = "VIDEOS/LEVEL10", ext = "str" },
+ [3538] = { dir = "VIDEOS/LEVEL10", ext = "str" },
+ [3541] = { dir = "VIDEOS/LEVEL11", ext = "str" },
+ [3544] = { dir = "VIDEOS/LEVEL12", ext = "str" },
+ [3547] = { dir = "VIDEOS/LEVEL13", ext = "str" },
+ [3550] = { dir = "VIDEOS/LEVEL14", ext = "str" },
+ [3553] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3554] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3555] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3556] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3557] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3558] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3559] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3560] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3561] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3562] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3563] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3564] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3565] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3566] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3567] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3568] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3569] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3570] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+ [3571] = { dir = "VIDEOS/LEVEL15", ext = "str" },
+-- Misc fullscreens
+ [3574] = { dir = "VIDEOS/MISC", ext = "str" },
+ [3575] = { dir = "VIDEOS/MISC", ext = "str" },
+ [3578] = { dir = "VIDEOS/MISC", ext = "str" },
+ [4864] = { dir = "VIDEOS/MISC", ext = "str" },
+ [4865] = { dir = "VIDEOS/MISC", ext = "str" },
+ [4866] = { dir = "VIDEOS/MISC", ext = "str" },
+}
+
+VP_map_gen = {}
+
+for _, v in pairs(VP_map_spans) do
+ for i = v.idx_s, v.idx_e do
+ VP_map_gen[i] = v.data
+ end
+end
+
+for k, v in pairs(VP_map) do
+ VP_map_gen[k] = v
+end
+
+VP_map = VP_map_gen
diff --git a/VP-miscwork.lua b/VP-miscwork.lua
new file mode 100644
index 0000000..31f7e92
--- /dev/null
+++ b/VP-miscwork.lua
@@ -0,0 +1,59 @@
+function process_arcgfx(fname, h, size, ext)
+ log("Processing " .. fname .. "." .. ext)
+ if dump_mode then
+ o = Output(fname .. "." .. ext)
+ o:copyfrom(h, size)
+ o:destroy()
+ h:seek(-size, SEEK_CUR)
+ end
+ log("Extracting " .. fname .. " - format 'arcgfx'")
+ dump_mkdir(fname)
+ local nfiles = h:readU32()
+ local extra = h:readU32()
+ local ret
+ if dump_mode then
+ o = Output(fname .. "/--extra.bin")
+ o:writeU32(extra)
+ o:destroy()
+ o = Output(fname .. string.format("/0000-%08X", extra))
+ o:writeU32(extra)
+ o:destroy()
+ else
+ ret = Buffer(true)
+ ret:writeU32(nfiles)
+ ret:writeU32(extra)
+ end
+
+ index = {}
+ for i = 1, nfiles do
+ index[i] = {}
+ index[i].extra = h:readU32()
+ index[i].size = h:readU32()
+ end
+
+ local tell
+ local outfile = {}
+ for i = 1, nfiles do
+ tell = h:tell()
+ outfile[i] = process_single_file(fname .. string.format("/%04i-%08X", i, index[i].extra), h, index[i].size, ext)
+ h:seek(tell + index[i].size)
+ end
+
+ if not dump_mode then
+ for i = 1, nfiles do
+ local alignment_bytes = alignment(outfile[i]:getsize(), 4)
+ for j = 1, alignment_bytes do
+ outfile[i]:writeU8(0)
+ end
+ ret:writeU32(index[i].extra)
+ ret:writeU32(outfile[i]:getsize())
+ end
+ for i = 1, nfiles do
+ ret:copyfrom(outfile[i])
+ outfile[i]:destroy()
+ end
+ end
+
+-- return ret
+end
+
diff --git a/VP-process.lua b/VP-process.lua
new file mode 100644
index 0000000..c4f65e2
--- /dev/null
+++ b/VP-process.lua
@@ -0,0 +1,305 @@
+load "VP-map.lua"
+load "VP-disasm.lua"
+load "VP-isowork.lua"
+load "VP-indexwork.lua"
+load "VP-fontwork.lua"
+load "VP-roomwork.lua"
+load "VP-miscwork.lua"
+load "VP-textwork.lua"
+
+restrict = {
+-- [3610] = true,
+-- [3611] = true,
+-- [3612] = true,
+-- [3613] = true,
+-- [3614] = true,
+-- [3615] = true,
+ [3610 + 125] = true,
+}
+
+--dump_glyph = true
+
+--dump_mode = true
+
+activate_debug_room = true
+
+slusent = nil
+got_cd1 = false
+got_cd2 = false
+got_us = false
+got_jp = false
+got_psp = false
+pspval1_sec = nil
+psp_dirtrees = {}
+
+all_txts = {}
+all_sha1 = {}
+all_origins = {}
+
+current_file = nil
+
+extra_glyphs_file = nil
+extra_glyphs = {}
+
+globals = {}
+
+biggest_pad = 0
+lookup_rooms = nil
+
+num_entries = 5120
+fkey_size = 256
+skey_size = 16
+num_files = 4866
+
+log_file = nil
+
+if not dump_mode then
+ load "rooms-txt.lua"
+ load "rooms.lua"
+end
+
+function new_pad(pad)
+ if pad > biggest_pad then biggest_pad = pad end
+end
+
+function dump_mkdir(dir) if dump_mode then mkdir(dir) end end
+
+function log(str)
+ print(str)
+ log_file:write(str .. "\n")
+end
+
+function alignment(size, align)
+ local ret = math.floor(size / align)
+ ret = size - ret * align
+ ret = align - ret
+ if ret == align then ret = 0 end
+ return ret
+end
+
+function process_single_file(fname, h, size, ext, handler)
+ local sig = h:readU32()
+ h:seek(-4, SEEK_CUR)
+ local is_slz = sig == 0x005a4c53 or sig == 0x015a4c53 or sig == 0x025a4c53 or sig == 0x035a4c53
+ local is_tim = sig == 0x00000010
+ local eof = false
+ if is_slz then
+ log("Processing " .. fname .. "." .. ext .. ".slz")
+ if dump_mode then
+ o = Output(fname .. "." .. ext .. ".slz")
+ o:copyfrom(h, size)
+ o:destroy()
+ h:seek(-size, SEEK_CUR)
+ end
+ local num, esiz, stype = 1
+ log("Extracting " .. fname .. ".slz")
+ local ret = Buffer(true)
+ while not eof do
+ local snum
+ snum = string.format("-%02i", num)
+ if num ~= 1 then
+ log("... file " .. num .. " to " .. fname .. snum .. "." .. ext)
+ end
+ o = Buffer(true)
+ local tell = h:tell()
+ esiz, stype = slz_decomp(h, o)
+ eof = esiz == 0
+ h:seek(tell + esiz)
+ local single_file_out = process_single_file(fname .. snum, o, o:getsize(), ext, handler)
+ if not dump_mode then
+ local single_file_compressed
+ if not got_psp then
+ single_file_compressed = Buffer(true)
+ ucl_compress(single_file_out, single_file_compressed)
+ else
+ single_file_compressed = single_file_out
+ end
+ if single_file_compressed:getsize() >= single_file_out:getsize() then
+ ret:writeU32(0x005a4c53)
+ ret:writeU32(single_file_out:getsize())
+ ret:writeU32(single_file_out:getsize())
+ local alignment_bytes = alignment(single_file_out:getsize(), 4)
+ for i = 1, alignment_bytes do
+ single_file_out:writeU8(0)
+ end
+ if eof then
+ ret:writeU32(0)
+ else
+ ret:writeU32(single_file_out:getsize() + 16)
+ end
+ ret:copyfrom(single_file_out)
+ single_file_out:destroy()
+ if single_file_out ~= single_file_compressed then
+ single_file_compressed:destroy()
+ end
+ else
+ ret:writeU32(0x035a4c53)
+ ret:writeU32(single_file_compressed:getsize())
+ ret:writeU32(single_file_out:getsize())
+ local alignment_bytes = alignment(single_file_compressed:getsize(), 4)
+ for i = 1, alignment_bytes do
+ single_file_compressed:writeU8(0)
+ end
+ if eof then
+ ret:writeU32(0)
+ else
+ ret:writeU32(single_file_compressed:getsize() + 16)
+ end
+ ret:copyfrom(single_file_compressed)
+ single_file_compressed:destroy()
+ single_file_out:destroy()
+ end
+ end
+ o:destroy()
+ num = num + 1
+ end
+ return ret
+ else
+ if is_tim and ext ~= "tim" and not handler then
+ ext = ext .. ".magic.tim"
+ end
+ log("Processing " .. fname .. "." .. ext)
+ if dump_mode then
+ o = Output(fname .. "." .. ext)
+ local tell = h:tell()
+ o:copyfrom(h, size)
+ h:seek(tell)
+ o:destroy()
+ end
+ local ret
+ if handler then
+ ret = handler(fname, h, size, ext)
+ end
+ if not ret and not dump_mode then
+ ret = Buffer(true)
+ local tell = h:tell()
+ ret:copyfrom(h, size)
+ h:seek(tell)
+ end
+ return ret
+ end
+end
+
+script_types = {
+ room = {
+ header = {
+ 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x00
+ },
+ translated = { "-", "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "!",
+ "O", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "!",
+ "◎", "①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "ǃ",
+ "O", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "!", " " },
+ size = 0x33,
+ },
+}
+
+function do_dump(i)
+ if not restrict then return true end
+
+ return restrict[i]
+end
+
+function process_files(index, map, iso, iso_full, cindex)
+ print("Processing files...")
+ local file_in, sig, is_slz, o, mode, dir, ftype
+ for i = 1, (num_entries - 1) do
+ if index[i] and ((not dump_mode) or do_dump(i)) then
+ if map[i] then
+ mode = map[i].mode
+ dir = map[i].dir
+ ext = map[i].ext
+ ftype = map[i].ftype
+ else
+ mode = MODE2_FORM1
+ dir = "UNKNOWN"
+ ext = "out"
+ ftype = nil
+ end
+ if not mode then mode = MODE2_FORM1 end
+ if not ext then ext = "out" end
+ if not dir then dir = "UNKNOWN" end
+ file_in = index[i].cd:cdfile(index[i].sector, index[i].size * sec_sizes[mode])
+ dump_mkdir("DUMP/" .. dir)
+ current_file = i
+ local file_out
+ if not dump_mode and not do_dump(i) then
+ file_out = file_in
+ elseif not ftype then
+ file_out = process_single_file("DUMP/" .. dir .. string.format("/%04i", i), file_in, file_in:getsize(), ext)
+ elseif ftype == "arcgfx" then
+ file_out = process_arcgfx("DUMP/" .. dir .. string.format("/%04i", i), file_in, file_in:getsize(), ext)
+ elseif ftype == "arcroom" then
+ file_out = process_arcroom("DUMP/" .. dir .. string.format("/%04i", i), file_in, file_in:getsize(), ext)
+ else
+ error("Unknow ftype: " .. ftype)
+ end
+ if not file_out then file_out = file_in end
+ file_in:seek(0)
+ if not dump_mode then cindex:add_file(iso, file_out, i) end
+ file_in:destroy()
+ if file_out ~= file_in then file_out:destroy() end
+ end
+ end
+end
+
+function main(...)
+ local cd, cd2, iso_out = startup(...)
+ iso_identify(cd)
+ if cd2 then iso_identify(cd2) end
+ local false_sect = Buffer(true)
+ false_sect:writeU8(0)
+ load_glyphes()
+ dump_mkdir "DUMP"
+ log_file = Output "log.txt"
+ local index, fkey, skey, fr, sr = load_index(cd)
+ if cd2 then
+ local index2 = load_index(cd2)
+ for k, v in pairs(index2) do
+ if not index[k] then index[k] = v end
+ end
+ end
+ for k, v in pairs(VP_maintypes) do
+ dump_mkdir("DUMP/" .. v)
+ end
+ local iso_full = true
+ for i = 1, (num_files - 1) do
+ if not index[i] then iso_full = false end
+ end
+ local iso, cindex
+ if not dump_mode then
+ iso = prepare_out(iso_out)
+ build_basic(iso, cd, iso_full)
+ cindex = prepare_index(iso, fkey, skey, fr, sr)
+ else
+ lookup_rooms = Output "DUMP/GAME/rooms.lua"
+ lookup_rooms:write "rooms_lookup = {\n"
+ end
+ process_files(index, VP_map, iso, iso_full, cindex)
+ if dump_mode then
+ local o = Output "DUMP/GAME/rooms.xml"
+ o:write('<roomscripts>\n')
+ for k, v in ipairs(all_txts) do
+ local origin = all_origins[k]
+ if string.len(origin) > 50 then origin="MULTIPLE" end
+ o:write('\n<ptr n="' .. k .. '" room="' .. origin .. '"/>\n' .. v.txt .. "\n")
+ end
+ o:write('</roomscripts>\n')
+ o:destroy()
+ lookup_rooms:write "}\n"
+ lookup_rooms:destroy()
+ else
+ cindex:close_index(iso, cd)
+ if not got_psp then
+ for i = 1, 148 do
+ false_sect:seek(0)
+ iso:putfile(false_sect, MODE2)
+ end
+ end
+ iso:close()
+ end
+ log("Biggest pad = " .. biggest_pad)
+ log_file:destroy()
+end
diff --git a/VP-roomwork.lua b/VP-roomwork.lua
new file mode 100644
index 0000000..d1eabfe
--- /dev/null
+++ b/VP-roomwork.lua
@@ -0,0 +1,499 @@
+function process_current_room_script()
+ local script, font, scriptfile, fontfile, nptrs
+ room_idx = current_file - 3610
+ if not rooms_lookup[room_idx] then return nil, nil end
+
+ script = Buffer(true)
+ scriptfile = Buffer(true)
+ fontfile = Buffer(true)
+ font = { idx = 1, ilookup = {}, clookup = {} }
+ for k, v in ipairs(script_types.room.translated) do
+ add_glyph(font, v)
+ end
+ for i = 1, script_types.room.size do
+ script:writeU8(script_types.room.header[i])
+ end
+ scriptfile:writeU16(0)
+ scriptfile:writeU16(3)
+ nptrs = 0
+ for pidx, pval in ipairs(rooms_lookup[room_idx]) do
+ nptrs = nptrs + 1
+ local ptr = rooms_txts[pval]
+ scriptfile:writeU16(script:getsize())
+ for k, v in ipairs(ptr) do
+ if type(v) == "string" then
+ local str = v
+ local char
+ local gidx
+ while str:len() ~= 0 do
+ char, str = get_next_utf8(str)
+ gidx = font.clookup[char] or add_glyph(font, char)
+ if gidx < 0x80 then
+ script:writeU8(gidx)
+ else
+ local high = shl(gidx, 7)
+ local low = andB(gidx, 127) + 0x80
+ script:writeU8(low)
+ script:writeU8(high)
+ end
+ end
+ elseif type(v) == "table" then
+ local code = v[1]
+ local high = 0x80
+ local low = 0x80 + code
+ script:writeU8(low)
+ script:writeU8(high)
+ if v[2] then script:writeU8(v[2]) end
+ if v[3] then script:writeU8(v[3]) end
+ if v[4] then error "Wrong script..." end
+ else
+ error("Wrong script...")
+ end
+ end
+ script:writeU8(0)
+ end
+ scriptfile:copyfrom(script)
+ script:destroy()
+
+ local npadding = alignment(#font.ilookup, 4)
+
+ fontfile:writeU32(#font.ilookup + npadding)
+ fontfile:writeU32(12)
+
+ for _, glyph in ipairs(font.ilookup) do
+ if not glyphes[glyph] then error("No glyph in database for " .. glyph) end
+ fontfile:writeU8(glyphes[glyph].attr.Width)
+ end
+ for i = 1, npadding do
+ fontfile:writeU8(0)
+ end
+
+ for _, glyph in ipairs(font.ilookup) do
+ Base64DecodeBin(glyphes[glyph].attr.Data, fontfile)
+ end
+ for i = 1, npadding do
+ for j = 1, 6 do fontfile:writeU32(0) end
+ end
+
+ return scriptfile, fontfile, nptrs + 2
+end
+
+function insert_script(old, new, nptrs)
+ local size_1 = old:readU32()
+ local u1 = old:readU32()
+ local u2 = old:readU32()
+ local n_ptrs = old:readU32()
+ local u3 = old:readU32()
+ local u4 = old:readU32()
+ local u5 = old:readU32()
+
+ local ret = Buffer(true)
+
+ ret:writeU32(size_1)
+ ret:writeU32(u1)
+ ret:writeU32(u2)
+ if nptrs ~= n_ptrs then error("Script inconsistancy! Got " .. nptrs .. " instead of " .. n_ptrs) end
+ ret:writeU32(nptrs)
+ ret:writeU32(u3)
+ ret:writeU32(u4)
+ ret:writeU32(u5)
+ if got_us and current_file == (3610 + 125) and activate_debug_room then
+ ret:copyfrom(old, 0x1158 * 4)
+ ret:writeU32(0x9e000000)
+ old:readU32()
+ ret:copyfrom(old, size_1 - 0x1159 * 4)
+ else
+ ret:copyfrom(old, size_1)
+ end
+ ret:copyfrom(new)
+
+ return ret
+end
+
+function process_arcroom(fname, h, size, ext)
+ log("Processing " .. fname .. "." .. ext)
+ local o
+
+ if dump_mode then
+ o = Output(fname .. "." .. ext)
+ o:copyfrom(h, size)
+ o:destroy()
+ h:seek(-size, SEEK_CUR)
+ end
+ log("Processing " .. fname .. " - format 'arcroom'")
+ dump_mkdir(fname)
+
+ local nfiles = h:readU32()
+ local offset = h:readU32()
+
+ if nfiles * 8 + 8 ~= offset then
+ error("Bad archive format.")
+ end
+
+ local ret
+
+ if not dump_mode then
+ ret = Buffer(true)
+ ret:writeU32(nfiles)
+ ret:writeU32(offset)
+ end
+
+ index = {}
+ for i = 1, nfiles do
+ index[i] = {}
+ index[i].ftype = h:readU32()
+ index[i].size = h:readU32()
+ end
+
+ local tell
+ local outfile = {}
+ local script = nil
+ local font = nil
+ local nptrs
+ if not dump_mode then
+ script, font, nptrs = process_current_room_script()
+ end
+ for i = 1, nfiles do
+ tell = h:tell()
+ local handler = nil
+ local counter = 1
+ if dump_mode and index[i].ftype == 4 then
+ log("Preparing to dump script...")
+ script = Buffer(true)
+ font = Buffer(true)
+ handler = function(fname, h, size, ext)
+ if counter == 1 then
+ log("Taking script...")
+ script:copyfrom(h)
+ elseif counter == 2 then
+ log("Taking font...")
+ font:copyfrom(h)
+ else
+ error("Too many files.")
+ end
+ counter = counter + 1
+ end
+ elseif index[i].ftype == 4 and script and font then
+ old_script = Buffer(true)
+ handler = function(fname, h, size, ext)
+ local ret
+ if counter == 1 then
+ log("Putting script...")
+ ret = insert_script(h, script, nptrs)
+ elseif counter == 2 then
+ log("Putting font...")
+ ret = Buffer(true)
+ ret:copyfrom(font)
+ else
+ error("Too many files.")
+ end
+ counter = counter + 1
+ return ret
+ end
+ end
+ outfile[i] = process_single_file(fname .. string.format("/%04i-%08X", i, index[i].ftype), h, index[i].size, "room", handler)
+ if handler then
+ if counter ~= 3 then error("Didn't get enough files; got " .. (counter - 1) .. " instead of 2.") end
+ if dump_mode then
+ extract_room_script(fname .. string.format("/%04i", i), script, font)
+ end
+ script:destroy()
+ font:destroy()
+ end
+ h:seek(tell + index[i].size)
+ end
+
+ if not dump_mode then
+ for i = 1, nfiles do
+ local alignment_bytes = alignment(outfile[i]:getsize(), 4)
+ for j = 1, alignment_bytes do
+ outfile[i]:writeU8(0)
+ end
+ ret:writeU32(index[i].ftype)
+ ret:writeU32(outfile[i]:getsize())
+ end
+ for i = 1, nfiles do
+ ret:copyfrom(outfile[i])
+ outfile[i]:destroy()
+ end
+ end
+
+ return ret
+end
+
+room_logic_check = {
+ [0x0090] = { 0x18000000, 0x00000008 }, [0x009B] = { 0x98100000, 0x17000000 },
+ [0x033C] = { 0x18000000, 0x0000002C }, [0x03BC] = { 0x92100000, 0x150003E1 }, [0x03C7] = { 0x94100000, 0x150003E1 }, [0x03D3] = { 0x93100000, 0x150003E1 }, [0x03DF] = { 0x92100000, 0x150003E1 },
+ [0x03E2] = { 0x18000000, 0x00000018 }, [0x03F0] = { 0x1400033C, 0x7E000000 },
+ [0x03F5] = { 0x18000000, 0x00000018 }, [0x0403] = { 0x1400033C, 0x7E000000 },
+ [0x0408] = { 0x18000000, 0x00000018 }, [0x0416] = { 0x1400033C, 0x7E000000 },
+-- [0x041B] = { 0x18000000, 0x00000020 }, [0x042B] = { 0x1400033C, 0x7E000000 },
+-- [0x0432] = { 0x18000000, 0x00000020 }, [0x0442] = { 0x1400033C, 0x7E000000 },
+-- [0x0449] = { 0x18000000, 0x00000020 }, [0x0459] = { 0x1400033C, 0x7E000000 },
+}
+
+function check_opcode(script, PC, supposed)
+ script:seek(PC * 4)
+ local r = script:readU32()
+ if r ~= supposed then error(string.format("Error for script: opcode %04X is %08X but was supposed to be %08X", PC, r, supposed)) end
+end
+
+function check_room_logic(script)
+ for offset, v in pairs(room_logic_check) do
+ local PC = offset - 1
+ for suboffset, supposed in ipairs(v) do
+ check_opcode(script, PC + suboffset, supposed)
+ end
+ end
+end
+
+function extract_room_script(fname, script, font)
+ log("Processing script " .. fname)
+ dump_mkdir(fname)
+ dump_mkdir(fname .. "/EXTRA")
+ local font = extract_font(fname .. "/FONT", font)
+ local lookup = resolve_font(font)
+ local size_1 = script:readU32()
+ local logic_offset = script:readU32()
+ local u1 = script:readU32()
+ local n_ptrs = script:readU32()
+ local u3 = script:readU32()
+ local u4 = script:readU32()
+ local u5 = script:readU32()
+
+ if logic_offset ~= 0 then error("Unhandled logic offset " .. logic_offset) end
+
+ local o
+ o = Output(fname .. "/EXTRA/00-head1-" .. string.format("%08X", u1) .. ".bin")
+ o:writeU32(u1)
+ o:destroy()
+ o = Output(fname .. "/EXTRA/00-head2-" .. string.format("%08X-%08X-%08X", u3, u4, u5) .. ".bin")
+ o:writeU32(u3)
+ o:writeU32(u4)
+ o:writeU32(u5)
+ o:destroy()
+ o = Output(fname .. "/EXTRA/01-head1.bin")
+ o:writeU32(u1)
+ o:destroy()
+ o = Output(fname .. "/EXTRA/01-head2.bin")
+ o:writeU32(u3)
+ o:writeU32(u4)
+ o:writeU32(u5)
+ o:destroy()
+ o = Output(fname .. "/EXTRA/02-part1.bin")
+ o:copyfrom(script, size_1)
+ o:destroy()
+ script:seek(-size_1, SEEK_CUR)
+ local logic = Buffer(true)
+ logic:copyfrom(script, size_1)
+
+ local ptrs = {}
+ local ptr_start = 1
+
+ for i = 1, n_ptrs do
+ ptrs[i] = script:readU16()
+ end
+
+ local ptrs_contents, ptrs_raws = {}, {}
+ local tell = script:tell()
+ ptrs_contents[1] = ""
+ ptrs_contents[2] = ""
+ ptrs_raws[1] = ""
+ ptrs_raws[2] = ""
+ ptr_start = 3
+
+ local header = script_types.room.header
+ for i = 1, script_types.room.size do
+ if script:readU8() ~= header[i] then error("Script header file of type 'room' not according to its header") end
+ end
+
+ for i = ptr_start, n_ptrs do
+ ptrs_contents[i] = ""
+ ptrs_raws[i] = ""
+ if tell + ptrs[i] ~= script:tell() then error("Script consistancy failure for pointer " .. i .. " - we're at " .. script:tell() .. " and " .. (tell + ptrs[i]) .. " was expected.") end
+ while true do
+ local r, rr = extract_char(script, lookup)
+ if not r then break end
+ ptrs_contents[i] = ptrs_contents[i] .. r
+ ptrs_raws[i] = ptrs_raws[i] .. rr
+ end
+ end
+
+ o = Output(fname .. "/EXTRA/logic.txt")
+ check_room_logic(logic)
+ local textboxes = { }
+ local rd_opcode = function(PC)
+ logic:seek(PC * 4)
+ return logic:readU32()
+ end
+ local add_textbox = function(txtptr, txtbox)
+ if txtptr < 0 then return end
+ o:write("\n")
+ if ptrs_raws[txtptr + ptr_start] then
+ o:write(ptrs_raws[txtptr + ptr_start])
+ if textboxes[txtptr + ptr_start] then
+ o:write("\n****SUSPECT****PTR ALREADY RECORDED****: " .. (txtptr + ptr_start))
+ end
+ textboxes[txtptr + ptr_start] = txtbox
+ else
+ error("****SUSPECT****PTR TOO LARGE****: " .. (txtptr + ptr_start))
+ end
+ end
+ local txt_process = function(PC)
+ local opcode = rd_opcode(PC)
+ local txtptr
+ local x, y, width, height
+ if andB(opcode, 0x00100000) ~= 0 then
+ local psh1 = rd_opcode(PC - 1)
+ local psh2 = rd_opcode(PC - 2)
+ local psh3 = rd_opcode(PC - 3)
+ local psh4 = rd_opcode(PC - 4)
+ local psh5 = rd_opcode(PC - 5)
+ local psh6 = rd_opcode(PC - 6)
+
+ if andB(psh1, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh2, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh3, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh4, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh5, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh6, 0xff000000) ~= 0x12000000 then return end
+
+ local arg1 = andB(psh1, 0x7fffff)
+ local arg2 = andB(psh2, 0x7fffff)
+ local arg3 = andB(psh3, 0x7fffff)
+ local arg4 = andB(psh4, 0x7fffff)
+ local arg5 = andB(psh5, 0x7fffff)
+ local arg6 = andB(psh6, 0x7fffff)
+
+ txtptr = arg6 + 1 - ptr_start
+
+ x = arg5
+ y = arg4
+ width = arg3
+ height = arg2
+ else
+ txtptr = andB(opcode, 0xff) + 1 - ptr_start
+ local arg1 = rd_opcode(PC + 1)
+ local arg2 = rd_opcode(PC + 2)
+ x = andB(arg1, 0xffff)
+ y = shr(arg1, 16)
+ width = andB(arg2, 0xffff)
+ height = shr(arg2, 16)
+ end
+ add_textbox(txtptr, {
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ })
+ end
+ local process_subtxt = function(PC)
+ local psh1 = rd_opcode(PC - 1)
+ local psh2 = rd_opcode(PC - 2)
+ local psh3 = rd_opcode(PC - 3)
+ local psh4 = rd_opcode(PC - 4)
+ local psh5 = rd_opcode(PC - 5)
+ local psh6 = rd_opcode(PC - 6)
+
+ if andB(psh1, 0xff000000) ~= 0x12000000 and andB(psh1, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh2, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh3, 0xff000000) ~= 0x12000000 and andB(psh3, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh4, 0xff000000) ~= 0x12000000 and andB(psh4, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh5, 0xff000000) ~= 0x12000000 and andB(psh5, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh6, 0xff000000) ~= 0x12000000 and andB(psh6, 0xff000000) ~= 0x0B000000 then return end
+
+ local arg1 = andB(psh1, 0x7fffff)
+ local arg2 = andB(psh2, 0x7fffff)
+ local arg3 = andB(psh3, 0x7fffff)
+ local arg4 = andB(psh4, 0x7fffff)
+ local arg5 = andB(psh5, 0x7fffff)
+ local arg6 = andB(psh6, 0x7fffff)
+
+ if andB(psh1, 0xff000000) == 0x0B000000 then arg1 = nil end
+ if andB(psh3, 0xff000000) == 0x0B000000 then arg3 = nil end
+ if andB(psh4, 0xff000000) == 0x0B000000 then arg4 = nil end
+ if andB(psh5, 0xff000000) == 0x0B000000 then arg5 = nil end
+ if andB(psh6, 0xff000000) == 0x0B000000 then arg6 = nil end
+
+ local txtptr = arg2 + 1 - ptr_start
+ add_textbox(txtptr, {
+ x = arg6 or "var",
+ y = arg5 or "var",
+ width = arg4 or "var",
+ height = arg3 or "var",
+ })
+ end
+ local process_subtxt2 = function(PC)
+ local psh1 = rd_opcode(PC - 1)
+ local psh2 = rd_opcode(PC - 2)
+ local psh3 = rd_opcode(PC - 3)
+ local psh4 = rd_opcode(PC - 4)
+ local psh5 = rd_opcode(PC - 5)
+
+ if andB(psh1, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh2, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh3, 0xff000000) ~= 0x22000000 then return end
+ if andB(psh4, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh5, 0xff000000) ~= 0xCB000000 then return end
+
+ local txtptr = andB(psh5, 0xff) + 1 - ptr_start
+ add_textbox(txtptr, {
+ typ = "fixed",
+ })
+ end
+ local call_process = function(PC)
+ local opcode = rd_opcode(PC)
+ if opcode == 0x1400033C or opcode == 0x140003E2 or opcode == 0x140003F5 or opcode == 0x14000408 then process_subtxt(PC) end
+ if opcode == 0x14000090 then process_subtxt2(PC) end
+ end
+ logic_disasm(logic, o, {
+ -- ret
+ [0x17] = function(PC) o:write("\n-----------------------------------------------------\n") end,
+ -- txtbox1
+ [0x92] = txt_process,
+ -- txtbox2
+ [0x93] = txt_process,
+ -- txtbox3
+ [0x94] = txt_process,
+ -- txtbox4
+ [0x98] = txt_process,
+ -- *sigh*
+ [0x14] = call_process,
+ } )
+
+ o:destroy()
+ logic:destroy()
+
+ for i = ptr_start, n_ptrs do
+ if textboxes[i] then
+ local tb = textboxes[i]
+ if tb.typ == "fixed" then
+ ptrs_contents[i] = '<window type="fixed"/>\n' .. ptrs_contents[i]
+ elseif tb.typ == "auto" then
+ ptrs_contents[i] = '<window type="auto"/>\n' .. ptrs_contents[i]
+ else
+ ptrs_contents[i] = '<window x="' .. tb.x .. '" y="' .. tb.y .. '" width="' .. tb.width .. '" height="' .. tb.height .. '"/>\n' .. ptrs_contents[i]
+ end
+ else
+ ptrs_contents[i] = '<nowindowdetected/>\n' .. ptrs_contents[i]
+ end
+ end
+
+ -- WARNING -- only for rooms
+ local ptrs_idx = process_ptrs(ptrs_contents, ptr_start, n_ptrs)
+
+ local o = Output(fname .. "-script.txt")
+ o:write("template:room\n")
+
+ for i = ptr_start, n_ptrs do
+ o:write(ptrs_idx[i] .. "\n")
+ end
+
+ lookup_rooms:write(" [" .. current_file - 3610 .. "] = { ")
+ for i = ptr_start, n_ptrs do
+ lookup_rooms:write(ptrs_idx[i] .. ", ")
+ end
+ lookup_rooms:write "},\n"
+
+ o:destroy()
+end
diff --git a/VP-slz3-patch.lua b/VP-slz3-patch.lua
new file mode 100644
index 0000000..cebcddc
--- /dev/null
+++ b/VP-slz3-patch.lua
@@ -0,0 +1,33 @@
+slz3_patch = {
+ [0x002b5c] = { 0xe7, 0x48, 0x00, 0x08, 0x21, 0x20, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ [0x002b6b] = { 0x00 },
+ [0x002b9c] = { 0x21, 0x28, 0x00, 0x02, 0x03 },
+ [0x002ba3] = { 0x92, 0xd6, 0xab },
+ [0x01b500] = { 0x21, 0xc8, 0xe0, 0x03, 0x21, 0x40, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x24, 0xff, 0x00, 0x0e, 0x3c,
+ 0x46, 0x00, 0x11, 0x04, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xe0, 0x11, 0x01, 0x00, 0x0b, 0x24,
+ 0x00, 0x00, 0x89, 0x90, 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0xa9, 0xa0, 0xf8, 0xff, 0x00, 0x10,
+ 0x01, 0x00, 0xa5, 0x24, 0x3d, 0x00, 0x11, 0x04, 0x40, 0x58, 0x0b, 0x00, 0x3b, 0x00, 0x11, 0x04,
+ 0x21, 0x58, 0x6f, 0x01, 0x05, 0x00, 0xe0, 0x15, 0xff, 0xff, 0x6b, 0x25, 0x37, 0x00, 0x11, 0x04,
+ 0x40, 0x58, 0x0b, 0x00, 0xf7, 0xff, 0x00, 0x10, 0x21, 0x58, 0x6f, 0x01, 0xff, 0xff, 0x6b, 0x25,
+ 0x05, 0x00, 0x60, 0x15, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x11, 0x04, 0x21, 0x58, 0x40, 0x01,
+ 0x0e, 0x00, 0x00, 0x10, 0x21, 0x60, 0xe0, 0x01, 0xff, 0xff, 0x6b, 0x25 },
+ [0x01b57e] = { 0x89, 0x90, 0x00, 0x5a, 0x0b, 0x00, 0x01, 0x00, 0x84, 0x24, 0x21, 0x58, 0x69, 0x01, 0x01, 0x00,
+ 0x69, 0x25, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x08 },
+ [0x01b59a] = { 0x20, 0x03, 0x01, 0x00, 0x2c, 0x31, 0x42, 0x58, 0x0b, 0x00, 0x01, 0x00, 0x6b, 0x25, 0x21, 0x50,
+ 0x60, 0x01, 0x1f },
+ [0x01b5ae] = { 0x11, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
+ 0x00, 0x10, 0x03, 0x00, 0xec, 0x25, 0x0a, 0x00, 0xe0, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x8c, 0x25, 0x16, 0x00, 0x11, 0x04, 0x40, 0x60, 0x0c, 0x00, 0x14, 0x00, 0x11, 0x04, 0x21, 0x60,
+ 0x8f, 0x01, 0xfb, 0xff, 0xe0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x05, 0x00,
+ 0x8c, 0x25, 0x0e, 0x00, 0x11, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xec, 0x25, 0x01, 0x05,
+ 0x69, 0x2d, 0x23, 0x60, 0x89, 0x01, 0x23, 0x68, 0xab, 0x00, 0x00, 0x00, 0xa9, 0x91, 0x01, 0x00,
+ 0xad },
+ [0x01b610] = { 0x00, 0x00, 0xa9, 0xa0, 0x00, 0x00 },
+ [0x01b618] = { 0xff, 0xff, 0x8c, 0x25, 0xfa, 0xff, 0x80, 0x15, 0x01, 0x00, 0xa5, 0x24, 0xba, 0xff, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x48, 0x0e, 0x01, 0x03, 0x00, 0x20, 0x15, 0x00, 0x00, 0x89, 0x90,
+ 0x01, 0x00, 0x84, 0x24, 0x25, 0x40, 0x2e, 0x01, 0xc2, 0x79, 0x08 },
+ [0x01b644] = { 0x40, 0x40, 0x08, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x01, 0x00, 0xef, 0x31, 0x00, 0x00, 0x00, 0x08 },
+ [0x01b758] = { 0x02, 0x00, 0x02, 0x24, 0x21, 0x18, 0xe0, 0x00, 0x08, 0x00, 0xa7, 0x8c, 0x43, 0x9e, 0x43, 0x10,
+ 0x10, 0x00, 0xa5, 0x24, 0x21, 0x20, 0xa0, 0x00, 0x21, 0x28, 0xc0 },
+ [0x01b774] = { 0x40, 0xab, 0x00, 0x08, 0x01, 0x00, 0x02, 0x24 },
+}
diff --git a/VP-textwork.lua b/VP-textwork.lua
new file mode 100644
index 0000000..2d3f56c
--- /dev/null
+++ b/VP-textwork.lua
@@ -0,0 +1,143 @@
+function get_next_utf8(str)
+ local ret = ""
+ local n
+ local b
+
+ n = str:sub(1, 1)
+ ret = ret .. n
+ str = str:sub(2)
+ b = n:byte()
+ if b <= 0x7f then return ret, str end
+
+ if b >= 0x80 and b <= 0xc1 then error("Wrong UTF-8 sequence.") end
+
+ n = str:sub(1, 1)
+ ret = ret .. n
+ str = str:sub(2)
+ if b <= 0xdf then return ret, str end
+
+ n = str:sub(1, 1)
+ ret = ret .. n
+ str = str:sub(2)
+ if b <= 0xef then return ret, str end
+
+ n = str:sub(1, 1)
+ ret = ret .. n
+ str = str:sub(2)
+ if b <= 0xf4 then return ret, str end
+
+ error("Wrong UTF-8 sequence.")
+end
+
+function dump_special(script, code)
+ if code == 0 then
+ return "\n", "\n"
+ elseif code == 1 then
+ return "\n<new/>\n", "\n"
+ elseif code == 3 then
+ local speed = script:readU8()
+ if speed == 255 then
+ return '<rspd/>', ""
+ else
+ return '<st spd="' .. speed .. '"/>', ""
+ end
+ elseif code == 5 then
+ return '<start/>', ""
+ elseif code == 7 then
+ local rep = script:readU8()
+ if rep == 1 then
+ return '<rrep/>', ""
+ else
+ return '<st rep="' .. rep ..'"/>', ""
+ end
+ elseif code == 8 then
+ local siz = script:readU8()
+ if siz == 1 then
+ return '<rsiz/>', ""
+ else
+ return '<st siz="' .. siz ..'"/>', ""
+ end
+ elseif code == 19 then
+ local arg1, arg2
+ arg1 = script:readU8()
+ arg2 = script:readU8()
+ if arg1 == 255 and arg2 == 255 then
+ return '<dport/>', ""
+ else
+ return '<port a1="' .. arg1 .. '" a2="' .. arg2 .. '"/>', ""
+ end
+ elseif code == 14 then
+ return '<var n="' .. script:readU8() .. '"/>', ""
+ elseif code == 4 then
+ return '<st clr="' .. script:readU8() .. '"/>', ""
+ else
+ local a1, a2
+ if code == 3 or code == 4 or code == 7 or code == 8 or code == 14 then
+ a1 = script:readU8()
+ return '<u1 c="' .. code .. '" a="' .. a1 .. '"/>', ""
+ elseif code == 6 or code == 12 or code == 17 or code == 19 then
+ a1 = script:readU8()
+ a2 = script:readU8()
+ return '<u2 c="' .. code .. '" a1="' .. a1 .. '" a2="' .. a2 .. '"/>', ""
+ else
+ return '<uk c="' .. code .. '"/>', ""
+ end
+ end
+ error "Should not end up there"
+end
+
+function extract_char(script, lookup)
+ local
+ c = script:readU8()
+ if c == 0 then return nil end
+ if c >= 0x80 then c = (c - 0x80) + (script:readU8() * 128) end
+
+ if c >= 0x4000 then
+ return dump_special(script, c - 0x4000)
+ else
+ local l = lookup[c]
+ if not l and not sloppy_extract then error("Lookup failed for character " .. c) end
+ if not l then
+ return '<failed value="' .. c .. '"/>', ""
+ else
+ return l, l
+ end
+ end
+ error "Should not end up there"
+end
+
+function get_txt_idx(txt)
+ local sha1 = SHA1(txt)
+ return all_sha1[sha1]
+end
+
+function add_txt_idx(txt)
+ local idx
+ idx = #all_txts + 1
+ local sha1 = SHA1(txt)
+ all_sha1[sha1] = idx
+ all_txts[idx] = {
+ sha1 = sha1,
+ txt = txt,
+ }
+ if all_origins[idx] then error("Something's inconsistant") end
+ all_origins[idx] = "" .. (current_file - 3610)
+ return idx
+end
+
+function process_ptrs(ptrs_contents, ptr_begin, ptr_end)
+ local r = {}
+
+ for i = ptr_begin, ptr_end do
+ local idx = get_txt_idx(ptrs_contents[i])
+ if not idx then
+ idx = add_txt_idx(ptrs_contents[i])
+ else
+ if not all_origins[idx] then error("Something's inconsistant") end
+ all_origins[idx] = all_origins[idx] .. "," .. (current_file - 3610)
+ end
+ r[i] = idx
+ end
+ return r
+end
+