Font.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. namespace FF8
  9. {
  10. public class Font
  11. {
  12. private Texture2D sysfnt; //21x10 characters; char is always 12x12
  13. private TextureHandler sysfntbig; //21x10 characters; char is always 24x24; 2 files side by side; sysfnt00 is same as sysfld00, but sysfnt00 is missing sysfnt01
  14. private Texture2D menuFont;
  15. #region CharTable
  16. //private static readonly Dictionary<byte, string> chartable = new Dictionary<byte, string>
  17. //{
  18. // //Commented out special bytes so they are passed through and I can see them in the dump file. Then I can figure out what to do with them.
  19. // {0x00, "\0"},// pos:-32, col:0, row:-1 -- is end of a string. MSG files have more than one string sepperated by \0
  20. // {0x01, ""},// pos:-31, col:0, row:0 -- //some strings start with 0x01 unsure if it does anything.
  21. // {0x02, "\n"},// pos:-30, col:0, row:0 -- new line
  22. // //{0x03, ""},// pos:-29, col:0, row:0 -- special character. {0x03,0x40 = [Angelo's Name]}
  23. // //{0x04, ""},// pos:-28, col:0, row:0 --
  24. // //{0x05, ""},// pos:-27, col:0, row:0 --
  25. // //{0x06, ""},// pos:-26, col:0, row:0 --
  26. // //{0x07, ""},// pos:-25, col:0, row:0 --
  27. // //{0x08, ""},// pos:-24, col:0, row:0 --
  28. // //{0x09, ""},// pos:-23, col:0, row:0 --
  29. // //{0x0A, ""},// pos:-22, col:0, row:0 --
  30. // //{0x0B, ""},// pos:-21, col:0, row:0 --
  31. // //{0x0C, ""},// pos:-20, col:0, row:0 -- <MAGBYTE>
  32. // //{0x0D, ""},// pos:-19, col:0, row:0 --
  33. // //{0x0E, ""},// pos:-18, col:0, row:0 -- <$>
  34. // //{0x0F, ""},// pos:-17, col:0, row:0 --
  35. // //{0x10, ""},// pos:-16, col:0, row:0 --
  36. // //{0x11, ""},// pos:-15, col:0, row:0 --
  37. // //{0x12, ""},// pos:-14, col:0, row:0 --
  38. // //{0x13, ""},// pos:-13, col:0, row:0 --
  39. // //{0x14, ""},// pos:-12, col:0, row:0 --
  40. // //{0x15, ""},// pos:-11, col:0, row:0 --
  41. // //{0x16, ""},// pos:-10, col:0, row:1 --
  42. // //{0x17, ""},// pos:-9, col:0, row:0 --
  43. // //{0x18, ""},// pos:-8, col:0, row:0 --
  44. // //{0x19, ""},// pos:-7, col:0, row:0 --
  45. // //{0x1A, ""},// pos:-6, col:0, row:0 --
  46. // //{0x1B, ""},// pos:-5, col:0, row:0 --
  47. // //{0x1C, ""},// pos:-4, col:0, row:0 --
  48. // //{0x1D, ""},// pos:-3, col:0, row:0 --
  49. // //{0x1E, ""},// pos:-2, col:0, row:0 --
  50. // //{0x1F, ""},// pos:-1, col:0, row:0 --
  51. // {0x20, " "},// pos:0, col:1, row:1 -- Start of font texture
  52. // {0x21, "0"},// pos:1, col:2, row:1 --
  53. // {0x22, "1"},// pos:2, col:3, row:1 --
  54. // {0x23, "2"},// pos:3, col:4, row:1 --
  55. // {0x24, "3"},// pos:4, col:5, row:1 --
  56. // {0x25, "4"},// pos:5, col:6, row:1 --
  57. // {0x26, "5"},// pos:6, col:7, row:1 --
  58. // {0x27, "6"},// pos:7, col:8, row:1 --
  59. // {0x28, "7"},// pos:8, col:9, row:1 --
  60. // {0x29, "8"},// pos:9, col:10, row:1 --
  61. // {0x2A, "9"},// pos:10, col:11, row:1 --
  62. // {0x2B, "%"},// pos:11, col:12, row:2 --
  63. // {0x2C, "/"},// pos:12, col:13, row:2 --
  64. // {0x2D, ":"},// pos:13, col:14, row:2 --
  65. // {0x2E, "!"},// pos:14, col:15, row:2 --
  66. // {0x2F, "?"},// pos:15, col:16, row:2 --
  67. // {0x30, "…"},// pos:16, col:17, row:2 --
  68. // {0x31, "+"},// pos:17, col:18, row:2 --
  69. // {0x32, "-"},// pos:18, col:19, row:2 --
  70. // {0x33, "="},// pos:19, col:20, row:2 --
  71. // {0x34, "*"},// pos:20, col:21, row:2 --
  72. // {0x35, "&amp;"},//& pos:21, col:1, row:2 -- temporarly set to this so i could have formatting on pastebin
  73. // {0x36, "「"},// pos:22, col:2, row:2 --
  74. // {0x37, "」"},// pos:23, col:3, row:2 --
  75. // {0x38, "("},// pos:24, col:4, row:2 --
  76. // {0x39, ")"},// pos:25, col:5, row:2 --
  77. // {0x3A, "·"},// pos:26, col:6, row:2 --
  78. // {0x3B, "."},// pos:27, col:7, row:2 --
  79. // {0x3C, ","},// pos:28, col:8, row:2 --
  80. // {0x3D, "~"},// pos:29, col:9, row:2 --
  81. // {0x3E, "“"},// pos:30, col:10, row:2 --
  82. // {0x3F, "”"},// pos:31, col:11, row:2 --
  83. // {0x40, "'"},// pos:32, col:12, row:3 --
  84. // {0x41, "#"},// pos:33, col:13, row:3 --
  85. // {0x42, "$"},// pos:34, col:14, row:3 --
  86. // {0x43, "`"},// pos:35, col:15, row:3 --
  87. // {0x44, "_"},// pos:36, col:16, row:3 --
  88. // {0x45, "A"},// pos:37, col:17, row:3 --
  89. // {0x46, "B"},// pos:38, col:18, row:3 --
  90. // {0x47, "C"},// pos:39, col:19, row:3 --
  91. // {0x48, "D"},// pos:40, col:20, row:3 --
  92. // {0x49, "E"},// pos:41, col:21, row:3 --
  93. // {0x4A, "F"},// pos:42, col:1, row:3 --
  94. // {0x4B, "G"},// pos:43, col:2, row:3 --
  95. // {0x4C, "H"},// pos:44, col:3, row:3 --
  96. // {0x4D, "I"},// pos:45, col:4, row:3 --
  97. // {0x4E, "J"},// pos:46, col:5, row:3 --
  98. // {0x4F, "K"},// pos:47, col:6, row:3 --
  99. // {0x50, "L"},// pos:48, col:7, row:3 --
  100. // {0x51, "M"},// pos:49, col:8, row:3 --
  101. // {0x52, "N"},// pos:50, col:9, row:3 --
  102. // {0x53, "O"},// pos:51, col:10, row:3 --
  103. // {0x54, "P"},// pos:52, col:11, row:3 --
  104. // {0x55, "Q"},// pos:53, col:12, row:4 --
  105. // {0x56, "R"},// pos:54, col:13, row:4 --
  106. // {0x57, "S"},// pos:55, col:14, row:4 --
  107. // {0x58, "T"},// pos:56, col:15, row:4 --
  108. // {0x59, "U"},// pos:57, col:16, row:4 --
  109. // {0x5A, "V"},// pos:58, col:17, row:4 --
  110. // {0x5B, "W"},// pos:59, col:18, row:4 --
  111. // {0x5C, "X"},// pos:60, col:19, row:4 --
  112. // {0x5D, "Y"},// pos:61, col:20, row:4 --
  113. // {0x5E, "Z"},// pos:62, col:21, row:4 --
  114. // {0x5F, "a"},// pos:63, col:1, row:4 --
  115. // {0x60, "b"},// pos:64, col:2, row:4 --
  116. // {0x61, "c"},// pos:65, col:3, row:4 --
  117. // {0x62, "d"},// pos:66, col:4, row:4 --
  118. // {0x63, "e"},// pos:67, col:5, row:4 --
  119. // {0x64, "f"},// pos:68, col:6, row:4 --
  120. // {0x65, "g"},// pos:69, col:7, row:4 --
  121. // {0x66, "h"},// pos:70, col:8, row:4 --
  122. // {0x67, "i"},// pos:71, col:9, row:4 --
  123. // {0x68, "j"},// pos:72, col:10, row:4 --
  124. // {0x69, "k"},// pos:73, col:11, row:4 --
  125. // {0x6A, "l"},// pos:74, col:12, row:5 --
  126. // {0x6B, "m"},// pos:75, col:13, row:5 --
  127. // {0x6C, "n"},// pos:76, col:14, row:5 --
  128. // {0x6D, "o"},// pos:77, col:15, row:5 --
  129. // {0x6E, "p"},// pos:78, col:16, row:5 --
  130. // {0x6F, "q"},// pos:79, col:17, row:5 --
  131. // {0x70, "r"},// pos:80, col:18, row:5 --
  132. // {0x71, "s"},// pos:81, col:19, row:5 --
  133. // {0x72, "t"},// pos:82, col:20, row:5 --
  134. // {0x73, "u"},// pos:83, col:21, row:5 --
  135. // {0x74, "v"},// pos:84, col:1, row:5 --
  136. // {0x75, "w"},// pos:85, col:2, row:5 --
  137. // {0x76, "x"},// pos:86, col:3, row:5 --
  138. // {0x77, "y"},// pos:87, col:4, row:5 --
  139. // {0x78, "z"},// pos:88, col:5, row:5 --
  140. // {0x79, "À"},// pos:89, col:6, row:5 --
  141. // {0x7A, "Á"},// pos:90, col:7, row:5 --
  142. // {0x7B, "Â"},// pos:91, col:8, row:5 --
  143. // {0x7C, "Ä"},// pos:92, col:9, row:5 --
  144. // {0x7D, "Ç"},// pos:93, col:10, row:5 --
  145. // {0x7E, "È"},// pos:94, col:11, row:5 --
  146. // {0x7F, "É"},// pos:95, col:12, row:6 --
  147. // {0x80, "Ê"},// pos:96, col:13, row:6 --
  148. // {0x81, "Ë"},// pos:97, col:14, row:6 --
  149. // {0x82, "Ì"},// pos:98, col:15, row:6 --
  150. // {0x83, "Í"},// pos:99, col:16, row:6 --
  151. // {0x84, "Î"},// pos:100, col:17, row:6 --
  152. // {0x85, "Ï"},// pos:101, col:18, row:6 --
  153. // {0x86, "Ñ"},// pos:102, col:19, row:6 --
  154. // {0x87, "Ò"},// pos:103, col:20, row:6 --
  155. // {0x88, "Ó"},// pos:104, col:21, row:6 --
  156. // {0x89, "Ô"},// pos:105, col:1, row:6 --
  157. // {0x8A, "Ö"},// pos:106, col:2, row:6 --
  158. // {0x8B, "Ù"},// pos:107, col:3, row:6 --
  159. // {0x8C, "Ú"},// pos:108, col:4, row:6 --
  160. // {0x8D, "Û"},// pos:109, col:5, row:6 --
  161. // {0x8E, "Ü"},// pos:110, col:6, row:6 --
  162. // {0x8F, "Œ"},// pos:111, col:7, row:6 --
  163. // {0x90, "Ʀ"},// pos:112, col:8, row:6 --
  164. // {0x91, "à"},// pos:113, col:9, row:6 --
  165. // {0x92, "á"},// pos:114, col:10, row:6 --
  166. // {0x93, "â"},// pos:115, col:11, row:6 --
  167. // {0x94, "ä"},// pos:116, col:12, row:7 --
  168. // {0x95, "ç"},// pos:117, col:13, row:7 --
  169. // {0x96, "è"},// pos:118, col:14, row:7 --
  170. // {0x97, "é"},// pos:119, col:15, row:7 --
  171. // {0x98, "ê"},// pos:120, col:16, row:7 --
  172. // {0x99, "ë"},// pos:121, col:17, row:7 --
  173. // {0x9A, "ì"},// pos:122, col:18, row:7 --
  174. // {0x9B, "í"},// pos:123, col:19, row:7 --
  175. // {0x9C, "î"},// pos:124, col:20, row:7 --
  176. // {0x9D, "ï"},// pos:125, col:21, row:7 --
  177. // {0x9E, "ñ"},// pos:126, col:1, row:7 --
  178. // {0x9F, "ò"},// pos:127, col:2, row:7 --
  179. // {0xA0, "ó"},// pos:128, col:3, row:7 --
  180. // {0xA1, "ô"},// pos:129, col:4, row:7 --
  181. // {0xA2, "ö"},// pos:130, col:5, row:7 --
  182. // {0xA3, "ù"},// pos:131, col:6, row:7 --
  183. // {0xA4, "ú"},// pos:132, col:7, row:7 --
  184. // {0xA5, "û"},// pos:133, col:8, row:7 --
  185. // {0xA6, "ü"},// pos:134, col:9, row:7 --
  186. // {0xA7, "œ"},// pos:135, col:10, row:7 --
  187. // {0xA8, "Ⅷ"},// pos:136, col:11, row:7 --
  188. // {0xA9, "["},// pos:137, col:12, row:8 --
  189. // {0xAA, "]"},// pos:138, col:13, row:8 --
  190. // {0xAB, "⬛"},// pos:139, col:14, row:8 --
  191. // {0xAC, "⦾"},// pos:140, col:15, row:8 --
  192. // {0xAD, "◆"},// pos:141, col:16, row:8 --
  193. // {0xAE, "【"},// pos:142, col:17, row:8 --
  194. // {0xAF, "】"},// pos:143, col:18, row:8 --
  195. // {0xB0, "⬜"},// pos:144, col:19, row:8 --
  196. // {0xB1, "★"},// pos:145, col:20, row:8 --
  197. // {0xB2, "『"},// pos:146, col:21, row:8 --
  198. // {0xB3, "』"},// pos:147, col:1, row:8 --
  199. // {0xB4, "▽"},// pos:148, col:2, row:8 --
  200. // {0xB5, ";"},// pos:149, col:3, row:8 --
  201. // {0xB6, "▼"},// pos:150, col:4, row:8 --
  202. // {0xB7, "‾"},// pos:151, col:5, row:8 --
  203. // {0xB8, "×"},// pos:152, col:6, row:8 --
  204. // {0xB9, "☆"},// pos:153, col:7, row:8 --
  205. // {0xBA, "’"},// pos:154, col:8, row:8 --
  206. // {0xBB, "↓"},// pos:155, col:9, row:8 --
  207. // {0xBC, "°"},// pos:156, col:10, row:8 --
  208. // {0xBD, "¡"},// pos:157, col:11, row:8 --
  209. // {0xBE, "¿"},// pos:158, col:12, row:9 --
  210. // {0xBF, "—"},// pos:159, col:13, row:9 --
  211. // {0xC0, "«"},// pos:160, col:14, row:9 --
  212. // {0xC1, "»"},// pos:161, col:15, row:9 --
  213. // {0xC2, "±"},// pos:162, col:16, row:9 --
  214. // {0xC3, ""},// pos:163, col:17, row:9 --
  215. // //{0xC4, ""},//{0xC4, "♫"},// pos:164, col:18, row:9 -- seems to be used as an alignment or a place holder many strings have 3 of these in a row.
  216. // {0xC5, "↑"},// pos:165, col:19, row:9 --
  217. // {0xC6, "VI"},// pos:166, col:20, row:9 --
  218. // {0xC7, "II"},// pos:167, col:21, row:9 --
  219. // {0xC8, "¡"},// pos:168, col:1, row:9 --
  220. // {0xC9, "™"},// pos:169, col:2, row:9 --
  221. // {0xCA, "<"},// pos:170, col:3, row:9 --
  222. // {0xCB, ">"},// pos:171, col:4, row:9 --
  223. // {0xCC, "GA"},// pos:172, col:5, row:9 --
  224. // {0xCD, "ME"},// pos:173, col:6, row:9 --
  225. // {0xCE, "FO"},// pos:174, col:7, row:9 --
  226. // {0xCF, "LD"},// pos:175, col:8, row:9 --
  227. // {0xD0, "ER"},// pos:176, col:9, row:9 --
  228. // {0xD1, "Sl"},// pos:177, col:10, row:9 --
  229. // {0xD2, "ot"},// pos:178, col:11, row:9 --
  230. // {0xD3, "ing"},// pos:179, col:12, row:10 --
  231. // {0xD4, "St"},// pos:180, col:13, row:10 --
  232. // {0xD5, "ec"},// pos:181, col:14, row:10 --
  233. // {0xD6, "kp"},// pos:182, col:15, row:10 --
  234. // {0xD7, "la"},// pos:183, col:16, row:10 --
  235. // {0xD8, ":z"},// pos:184, col:17, row:10 --
  236. // {0xD9, "Fr"},// pos:185, col:18, row:10 --
  237. // {0xDA, "nt"},// pos:186, col:19, row:10 --
  238. // {0xDB, "elng"},// pos:187, col:20, row:10 --
  239. // {0xDC, "re"},// pos:188, col:21, row:10 --
  240. // {0xDD, "S:"},// pos:189, col:1, row:10 --
  241. // {0xDE, "so"},// pos:190, col:2, row:10 --
  242. // {0xDF, "Ra"},// pos:191, col:3, row:10 --
  243. // {0xE0, "nu"},// pos:192, col:4, row:10 --
  244. // {0xE1, "ra"},// pos:193, col:5, row:10 --
  245. // {0xE2, "®"},// pos:194, col:6, row:10 -- End of font texture
  246. // //{0xE3, ""},// pos:195, col:0, row:0 --
  247. // //{0xE4, ""},// pos:196, col:0, row:0 --
  248. // //{0xE5, ""},// pos:197, col:0, row:0 --
  249. // //{0xE6, ""},// pos:198, col:0, row:0 --
  250. // //{0xE7, ""},// pos:199, col:0, row:0 --
  251. // {0xE8, "in"},// pos:200, col:0, row:0 --
  252. // {0xE9, "e "},// pos:201, col:0, row:0 --
  253. // {0xEA, "ne"},// pos:202, col:0, row:0 --
  254. // {0xEB, "to"},// pos:203, col:0, row:0 --
  255. // {0xEC, "to"},// pos:204, col:0, row:0 --
  256. // {0xED, "HP"},// pos:205, col:0, row:0 --
  257. // {0xEE, "l "},// pos:206, col:0, row:0 --
  258. // {0xEF, "ll"},// pos:207, col:0, row:0 --
  259. // {0xF0, "GF"},// pos:208, col:0, row:0 --
  260. // {0xF1, "nt"},// pos:209, col:0, row:0 --
  261. // {0xF2, "il"},// pos:210, col:0, row:0 --
  262. // {0xF3, "o "},// pos:211, col:0, row:0 --
  263. // {0xF4, "ef"},// pos:212, col:0, row:0 --
  264. // {0xF5, "on"},// pos:213, col:0, row:0 --
  265. // {0xF6, " w"},// pos:214, col:0, row:0 --
  266. // {0xF7, " r"},// pos:215, col:0, row:0 --
  267. // {0xF8, "wi"},// pos:216, col:0, row:0 --
  268. // {0xF9, "fi"},// pos:217, col:0, row:0 --
  269. // //{0xFA, ""},// pos:218, col:0, row:0 --
  270. // {0xFB, "s "},// pos:219, col:0, row:0 --
  271. // {0xFC, "ar"},// pos:220, col:0, row:0 --
  272. // {0xFD, ""},// pos:221, col:0, row:0 --
  273. // {0xFE, " S"},// pos:222, col:0, row:0 --
  274. // {0xFF, "ag"},// pos:223, col:0, row:0 --
  275. // //{0x00, "\0"}, // I think \0 is a new string. if you read in a msg file it a array of strings each ending with \0
  276. // //{0x02, "\n"}, // changed \n to signal draw text to make a new line
  277. // //{0x03, ""},
  278. // //{0x04, "" }, //Probably
  279. // //{0x0E, "" }, //Probably
  280. // //{0x20, " "},
  281. // //{0x21, "0"},
  282. // //{0x22, "1"},
  283. // //{0x23, "2"},
  284. // //{0x24, "3"},
  285. // //{0x25, "4"},
  286. // //{0x26, "5"},
  287. // //{0x27, "6"},
  288. // //{0x28, "7"},
  289. // //{0x29, "8"},
  290. // //{0x2A, "9"},
  291. // //{0x2B, "%"},
  292. // //{0x2C, "/"},
  293. // //{0x2D, ":"},
  294. // //{0x2E, "!"},
  295. // //{0x2F, "?"},
  296. // //{0x30, "…"},
  297. // //{0x31, "+"},
  298. // //{0x32, "-"},
  299. // //{0x33, "SPECIAL CHARACTER TODO"},
  300. // //{0x34, "*"},
  301. // //{0x35, "&"},
  302. // //{0x36, "SPECIAL CHARACTER TODO" },
  303. // //{0x37, "SPECIAL CHARACTER TODO" },
  304. // //{0x38, "("},
  305. // //{0x39, ")"},
  306. // //{0x3A, "SPECIAL CHARACTER TODO"},
  307. // //{0x3B, "."},
  308. // //{0x3C, ","},
  309. // //{0x3D, "~"},
  310. // //{0x3E, "SPECIAL CHARACTER TODO"},
  311. // //{0x3F, "SPECIAL CHARACTER TODO"},
  312. // //{0x40, "'"},
  313. // //{0x41, "#"},
  314. // //{0x42, "$"},
  315. // //{0x43, "`"},
  316. // //{0x44, "_"},
  317. // //{0x45, "A"},
  318. // //{0x46, "B"},
  319. // //{0x47, "C"},
  320. // //{0x48, "D"},
  321. // //{0x49, "E"},
  322. // //{0x4A, "F"},
  323. // //{0x4B, "G"},
  324. // //{0x4C, "H"},
  325. // //{0x4D, "I"},
  326. // //{0x4E, "J"},
  327. // //{0x4F, "K"},
  328. // //{0x50, "L"},
  329. // //{0x51, "M"},
  330. // //{0x52, "N"},
  331. // //{0x53, "O"},
  332. // //{0x54, "P"},
  333. // //{0x55, "Q"},
  334. // //{0x56, "R"},
  335. // //{0x57, "S"},
  336. // //{0x58, "T"},
  337. // //{0x59, "U"},
  338. // //{0x5A, "V"},
  339. // //{0x5B, "W"},
  340. // //{0x5C, "X"},
  341. // //{0x5D, "Y"},
  342. // //{0x5E, "Z"},
  343. // //{0x5F, "a"},
  344. // //{0x60, "b"},
  345. // //{0x61, "c"},
  346. // //{0x62, "d"},
  347. // //{0x63, "e"},
  348. // //{0x64, "f"},
  349. // //{0x65, "g"},
  350. // //{0x66, "h"},
  351. // //{0x67, "i"},
  352. // //{0x68, "j"},
  353. // //{0x69, "k"},
  354. // //{0x6A, "l"},
  355. // //{0x6B, "m"},
  356. // //{0x6C, "n"},
  357. // //{0x6D, "o"},
  358. // //{0x6E, "p"},
  359. // //{0x6F, "q"},
  360. // //{0x70, "r"},
  361. // //{0x71, "s"},
  362. // //{0x72, "t"},
  363. // //{0x73, "u"},
  364. // //{0x74, "v"},
  365. // //{0x75, "w"},
  366. // //{0x76, "x"},
  367. // //{0x77, "y"},
  368. // //{0x78, "z"},
  369. // //{0x79, "Ł"},
  370. // //{0x7C, "Ä"},
  371. // //{0x88, "Ó"},
  372. // //{0x8A, "Ö"},
  373. // //{0x8E, "Ü"},
  374. // //{0x90, "ß"},
  375. // //{0x94, "ä"},
  376. // //{0xA0, "ó"},
  377. // //{0xA2, "ö"},
  378. // //{0xA6, "ü"},
  379. // //{0xA8, "Ⅷ"},
  380. // //{0xA9, "["},
  381. // //{0xAA, "]"},
  382. // //{0xAB, "[SQUARE]"},
  383. // //{0xAC, "@"},
  384. // //{0xAD, "[SSQUARE]"},
  385. // //{0xAE, "{"},
  386. // //{0xAF, "}"},
  387. // //{0xC6, "Ⅵ"},
  388. // //{0xC7, "Ⅱ"},
  389. // //{0xC9, "™"},
  390. // //{0xCA, "<"},
  391. // //{0xCB, ">"},
  392. // //{0xE8, "in"},
  393. // //{0xE9, "e "},
  394. // //{0xEA, "ne"},
  395. // //{0xEB, "to"},
  396. // //{0xEC, "re"},
  397. // //{0xED, "HP"},
  398. // //{0xEE, "l "},
  399. // //{0xEF, "ll"},
  400. // //{0xF0, "GF"},
  401. // //{0xF1, "nt"},
  402. // //{0xF2, "il"},
  403. // //{0xF3, "o "},
  404. // //{0xF4, "ef"},
  405. // //{0xF5, "on"},
  406. // //{0xF6, " w"},
  407. // //{0xF7, " r"},
  408. // //{0xF8, "wi"},
  409. // //{0xF9, "fi"},
  410. // //{0xFB, "s "},
  411. // //{0xFC, "ar"},
  412. // //{0xFE, " S"},
  413. // //{0xFF, "ag"}
  414. //};
  415. #endregion CharTable
  416. public enum ColorID
  417. {
  418. Dark_Gray, Grey, Yellow, Red, Green, Blue, Purple, White
  419. }
  420. /// <summary>
  421. /// Change colors of text following this.
  422. /// </summary>
  423. private static Dictionary<int, ColorID> ColorCode = new Dictionary<int, ColorID>()
  424. {
  425. {0x0625, ColorID.Blue },
  426. {0x0627, ColorID.White },
  427. {0x0624, ColorID.Green }
  428. };
  429. /// <summary>
  430. /// Placeholder for button images.
  431. /// </summary>
  432. private static Dictionary<int, string> Icons = new Dictionary<int, string>()
  433. {
  434. //on pc it puts a green letter for the keyboard key
  435. //two lefts and two rights doesn't make sense.
  436. //buttons
  437. {0x052F, "Left" },
  438. {0x052D, "Right" },
  439. {0x052C, "Left" },
  440. {0x052E, "Right" },
  441. {0x0526, "Okay" },
  442. {0x0524, "Cancel" },
  443. {0x053B, "Start" },
  444. {0x0522, "L1" },
  445. {0x0520, "L2" },
  446. {0x0521, "R2" },
  447. //other
  448. //commented out because these seem to be varible depending on where they are used.
  449. //{0x0541, "Junction Symbol" },
  450. //{0x0542, "Right Arrow" },
  451. //{ 0x55D, "Fire" },
  452. //{ 0x55E, "Ice" },
  453. //{ 0x55F, "Thunder" },
  454. //{ 0x560, "Earth" },
  455. //{ 0x561, "Poison" },
  456. //{ 0x562, "Wind" },
  457. //{ 0x563, "Water" },
  458. //{ 0x564, "Holy" },
  459. //{ 0x565, "Death" },
  460. //{ 0x566, "Poison" },
  461. //{ 0x567, "Petrify" },
  462. //{ 0x568, "Darkness" },
  463. //{ 0x569, "Silence" },
  464. //{ 0x56A, "Berserk" },
  465. //{ 0x56B, "Zombie" },
  466. //{ 0x56C, "Sleep" },
  467. //{ 0x56D, "Slow" },
  468. //{ 0x56E, "Stop" },
  469. //{ 0x56F, "Curse" },
  470. //{ 0x570, "Confuse" },
  471. //{ 0x571, "Drain" },
  472. //{0x545, "Junction Ability" },
  473. //{0x546, "Command Ability" },
  474. //{0x548, "Character Ability" },
  475. //{0x549, "Party Ability" },
  476. //{0x54A, "GF Ability" },
  477. //{0x54B, "Menu Ability" },
  478. };
  479. /// <summary>
  480. /// Place holders for names that can be customized.
  481. /// </summary>
  482. private static Dictionary<int, string> Names = new Dictionary<int, string>()
  483. {
  484. {0x0330, "Squall" },
  485. {0x0334, "Riona" },
  486. {0x0340, "Angelio" },
  487. {0x333, "Character" } // could be GF, could be character, unsure.
  488. };
  489. /// <summary>
  490. /// Place holders for various things. The 0A values change depending on what section/string you are in. 0B values can be 2 or 3 bytes total.
  491. /// </summary>
  492. private static Dictionary<int, string> Special = new Dictionary<int, string>()
  493. {
  494. //{0xA29, "Ability" }, // that can be learned.
  495. //{0xA27, "Character Name"}, //could be wrong
  496. //{0xA24, "GF Name" },
  497. //{0xA25, "Ability" },
  498. //{0xA22, "Amount" }, //current level or change unsure.
  499. //{0xA28, "Stat" },
  500. //{0xA26, "Spell or Rank" }, //Selected spell or SeeD rank
  501. //{0xA20, "Value" }, //Card Level or SeeD test scores
  502. //{0xABB, "Ignore require: GF Medicine: Ribbon" }, //might be more general like all GF medicine only abilites.
  503. //{0xA97, "Ignore require: Tonberry ability unlock" }, // could be you need to unlock or just have the gf
  504. //{0xA96, "Ignore require: Cactuar ability unlock" }, // could be you need to unlock or just have the gf
  505. //{0xABF, "Ignore require: Defeat Omega Weapon" },
  506. //{0xA3F, "End Ignore" },
  507. {0xB20, "Option-0xB20" }, // could be wrong, //following byte is like an id of selection.
  508. {0xB21, "Option-0xB21" }, // could be wrong
  509. {0xB22, "Option-0xB22" }, // could be wrong
  510. {0xB23, "Option-0xB23" }, // could be wrong
  511. //0xC values are spells.
  512. };
  513. private static Dictionary<int, string> Spell = new Dictionary<int, string>()
  514. {
  515. //Spell
  516. //http://forums.qhimm.com/index.php?topic=11137.msg166280#msg166280
  517. {0xC00,"Empty"},
  518. {0xC01,"Fire"},
  519. {0xC02,"Fira"},
  520. {0xC03,"Firaga"},
  521. {0xC04,"Blizzard"},
  522. {0xC05,"Blizzara"},
  523. {0xC06,"Blizzaga"},
  524. {0xC07,"Thunder"},
  525. {0xC08,"Thundara"},
  526. {0xC09,"Thundaga"},
  527. {0xC0A,"Water"},
  528. {0xC0B,"Aero"},
  529. {0xC0C,"Bio"},
  530. {0xC0D,"Demi"},
  531. {0xC0E,"Holy"},
  532. {0xC0F,"Flare"},
  533. {0xC10,"Meteor"},
  534. {0xC11,"Quake"},
  535. {0xC12,"Tornado"},
  536. {0xC13,"Ultima"},
  537. {0xC14,"Apocalypse"},
  538. {0xC15,"Cure"},
  539. {0xC16,"Cura"},
  540. {0xC17,"Curaga"},
  541. {0xC18,"Life"},
  542. {0xC19,"Full-Life"},
  543. {0xC1A,"Regan"},
  544. {0xC1B,"Esuna"},
  545. {0xC1C,"Dispel"},
  546. {0xC1D,"Protect"},
  547. {0xC1E,"Shell"},
  548. {0xC1F,"Reflect"},
  549. {0xC20,"Aura"},
  550. {0xC21,"Double"},
  551. {0xC22,"Triple"},
  552. {0xC23,"Haste"},
  553. {0xC24,"Slow"},
  554. {0xC25,"Stop"},
  555. {0xC26,"Blind"},
  556. {0xC27,"Confuse"},
  557. {0xC28,"Sleep"},
  558. {0xC29,"Silence"},
  559. {0xC2A,"Break"},
  560. {0xC2B,"Death"},
  561. {0xC2C,"Drain"},
  562. {0xC2D,"Pain"},
  563. {0xC2E,"Berserk"},
  564. {0xC2F,"Float"},
  565. {0xC30,"Zombie"},
  566. {0xC31,"Meltdown"},
  567. {0xC32,"Scan"},
  568. {0xC33,"Full-Cure"},
  569. {0xC34,"Wall"},
  570. {0xC35,"Rapture"},
  571. {0xC36,"Percent"},
  572. {0xC37,"Catastrophe"},
  573. {0xC38,"The End"},
  574. //GF
  575. {0xC60,"Quezacotl" },
  576. {0xC61,"Shiva" },
  577. {0xC62,"Ifrit" },
  578. {0xC63,"Siren" },
  579. {0xC64,"Brothers" },
  580. {0xC65,"Diablos" },
  581. {0xC66,"Carbuncle" },
  582. {0xC67,"Leviathan" },
  583. {0xC68,"Pandemona" },
  584. {0xC69,"Cerberus" },
  585. {0xC6A,"Alexander" },
  586. {0xC6B,"Doomtrain" },
  587. {0xC6C,"Bahamut" },
  588. {0xC6D,"Cactuar" },
  589. {0xC6E,"Tonberry" },
  590. {0xC6F,"Eden" }
  591. };
  592. public Font() => LoadFonts();
  593. internal void LoadFonts()
  594. {
  595. ArchiveWorker aw = new ArchiveWorker(Memory.Archives.A_MENU);
  596. string sysfntTdwFilepath = aw.GetListOfFiles().First(x => x.ToLower().Contains("sysfnt.tdw"));
  597. string sysfntFilepath = aw.GetListOfFiles().First(x => x.ToLower().Contains("sysfnt.tex"));
  598. TEX tex = new TEX(ArchiveWorker.GetBinaryFile(Memory.Archives.A_MENU, sysfntFilepath));
  599. sysfnt = tex.GetTexture((int)ColorID.White);
  600. sysfntbig = new TextureHandler("sysfld{0:00}.tex", tex, 2, 1, (int)ColorID.White);
  601. ReadTdw(ArchiveWorker.GetBinaryFile(Memory.Archives.A_MENU, sysfntTdwFilepath));
  602. }
  603. internal void ReadTdw(byte[] Tdw)
  604. {
  605. uint widthPointer = BitConverter.ToUInt32(Tdw, 0);
  606. uint dataPointer = BitConverter.ToUInt32(Tdw, 4);
  607. getWidths(Tdw, widthPointer, dataPointer - widthPointer);
  608. TIM2 tim = new TIM2(Tdw, dataPointer);
  609. menuFont = new Texture2D(Memory.graphics.GraphicsDevice, tim.GetWidth, tim.GetHeight);
  610. menuFont.SetData(tim.CreateImageBuffer(tim.GetClutColors(ColorID.White)));
  611. }
  612. internal void getWidths(byte[] Tdw,uint offset, uint length)
  613. {
  614. using (MemoryStream os = new MemoryStream((int)length * 2))
  615. using (BinaryWriter bw = new BinaryWriter(os))
  616. using (MemoryStream ms = new MemoryStream(Tdw))
  617. using (BinaryReader br = new BinaryReader(ms))
  618. {
  619. //bw.Write((byte)10);//width of space
  620. ms.Seek(offset, SeekOrigin.Begin);
  621. while (ms.Position < offset + length)
  622. {
  623. byte b = br.ReadByte();
  624. byte low = (byte)(b & 0x0F);
  625. byte high = (byte)(b >> 4);
  626. bw.Write(low);
  627. bw.Write(high);
  628. }
  629. charWidths = os.ToArray();
  630. }
  631. }
  632. private byte[] charWidths;
  633. public Rectangle CalcBasicTextArea(byte[] buffer, Vector2 pos, Vector2 zoom, int whichFont = 0, int isMenu = 0) => CalcBasicTextArea(buffer, (int)pos.X, (int)pos.Y, zoom.X, zoom.Y);
  634. public Rectangle CalcBasicTextArea(byte[] buffer, Point pos, Vector2 zoom, int whichFont = 0, int isMenu = 0) => CalcBasicTextArea(buffer, pos.X, pos.Y, zoom.X, zoom.Y);
  635. public Rectangle CalcBasicTextArea(byte[] buffer, int x, int y, float zoomWidth = 1f, float zoomHeight = 1f, int whichFont = 0, int isMenu = 0) => RenderBasicText(buffer, x, y, zoomWidth, zoomHeight, whichFont, isMenu, 1, true);
  636. public Rectangle RenderBasicText(byte[] buffer, Vector2 pos, Vector2 zoom, int whichFont = 0, int isMenu = 0, float Fade = 1.0f) => RenderBasicText(buffer, (int)pos.X, (int)pos.Y, zoom.X, zoom.Y, whichFont, isMenu, Fade);
  637. public Rectangle RenderBasicText(byte[] buffer, Point pos, Vector2 zoom, int whichFont = 0, int isMenu = 0, float Fade = 1.0f, bool prescaled = false) => RenderBasicText(buffer, pos.X, pos.Y, zoom.X, zoom.Y, whichFont, isMenu, Fade,false, prescaled);
  638. public Rectangle RenderBasicText(byte[] buffer, int x, int y, float zoomWidth = 2.0f, float zoomHeight = 2.7f, int whichFont = 0, int isMenu = 0, float Fade = 1.0f, bool skipdraw =false, bool prescaled = false)
  639. {
  640. if (buffer == null) return new Rectangle();
  641. Rectangle ret = new Rectangle(x, y, 0, 0);
  642. Point real = new Point(x, y);
  643. int charCountWidth = 21;
  644. int charSize = 12; //pixelhandler does the 2x scaling on the fly.
  645. Vector2 zoom = new Vector2(zoomWidth, zoomHeight);
  646. Vector2 scale = !prescaled? Memory.Scale():Vector2.One;
  647. Point size = (new Vector2(0, charSize) * zoom * scale).ToPoint();
  648. int width;
  649. foreach (byte c in buffer)
  650. {
  651. if (c == 0) continue;
  652. byte deltaChar = (byte)(c - 32);
  653. if (deltaChar < charWidths.Length)
  654. {
  655. width = charWidths[deltaChar];
  656. size.X = (int)(charWidths[deltaChar] * zoom.X * scale.X);
  657. }
  658. else
  659. {
  660. width = charSize;
  661. size.X = (int)(charSize * zoom.X * scale.X);
  662. }
  663. Point curSize = size;
  664. int verticalPosition = deltaChar / charCountWidth;
  665. //i.e. 1280 is 100%, 640 is 50% and therefore 2560 is 200% which means multiply by 0.5f or 2.0f
  666. if (c == 0x02)// \n
  667. {
  668. real.X = x;
  669. real.Y += size.Y;
  670. continue;
  671. }
  672. Rectangle destRect = new Rectangle(real, size);
  673. // if you use Memory.SpriteBatchStartAlpha(SamplerState.PointClamp); you won't need
  674. // to trim last pixel. but it doesn't look good on low res fonts.
  675. if (!skipdraw)
  676. {
  677. Rectangle sourceRect = new Rectangle((deltaChar - (verticalPosition * charCountWidth)) * charSize,
  678. verticalPosition * charSize,
  679. width,
  680. charSize);
  681. if (whichFont == 0 || isMenu == 1)
  682. {
  683. //trim pixels to remove texture filtering artifacts.
  684. sourceRect.Width -= 1;
  685. sourceRect.Height -= 1;
  686. Memory.spriteBatch.Draw(isMenu == 1 ? menuFont : sysfnt,
  687. destRect,
  688. sourceRect,
  689. Color.White * Fade);
  690. }
  691. else
  692. {
  693. if (!sysfntbig.Modded)
  694. {
  695. Rectangle ShadowdestRect = new Rectangle(destRect.Location, destRect.Size);
  696. ShadowdestRect.Offset(1 * zoomWidth, 1 * zoomHeight);
  697. sysfntbig.Draw(ShadowdestRect, sourceRect, Color.Black * Fade * .5f);
  698. }
  699. sysfntbig.Draw(destRect, sourceRect, Color.White * Fade);
  700. }
  701. }
  702. real.X += size.X;
  703. int curWidth = real.X - x;
  704. if (curWidth > ret.Width)
  705. ret.Width = curWidth;
  706. }
  707. ret.Height = size.Y + (real.Y - y);
  708. return ret;
  709. }
  710. /// <summary>
  711. /// Converts clean string into dirty string for drawing.
  712. /// </summary>
  713. /// <param name="s">Clean String</param>
  714. /// <returns>Dirty String</returns>
  715. /// <remarks>
  716. /// dirty, do not use for anything else than translating for your own purpouses. I'm just lazy
  717. /// Anything from 0-127 should be able to convert back and forth.
  718. /// But anything 128-256 may get messed up as c# stores it's strings as 16-bit unicode
  719. /// </remarks>
  720. [Obsolete("use 'Memory.DirtyEncoding.GetBytes(s)' or 'new FF8String(s)'")]
  721. public static byte[] CipherDirty(string s) => Memory.DirtyEncoding.GetBytes(s);
  722. //{
  723. // using (MemoryStream ms = new MemoryStream(s.Length))
  724. // {
  725. // foreach (char n in s)
  726. // {
  727. // // might need to change this to let the 0x02 pass and make the render function detect
  728. // // the 0x02 instead of \n
  729. // //if (n == '\n') { str += n; continue; }
  730. // foreach (KeyValuePair<byte, string> kvp in chartable)
  731. // if (kvp.Value.Length == 1)
  732. // if (kvp.Value[0] == n)
  733. // ms.WriteByte(kvp.Key);
  734. // }
  735. // return ms.ToArray();
  736. // }
  737. //}
  738. /// <summary>
  739. /// For string dump file. Not ment to be used to decode FF8Strings.
  740. /// </summary>
  741. /// <param name="s">Dirty String</param>
  742. /// <returns>Clean UTF8 String in byte[] form with some XML</returns>
  743. public static byte[] DumpDirtyString(byte[] s)
  744. {
  745. if (s != null)
  746. using (MemoryStream os = new MemoryStream(s.Length))
  747. using (BinaryWriter bw = new BinaryWriter(os))
  748. using (MemoryStream ms = new MemoryStream(s))
  749. using (BinaryReader br = new BinaryReader(ms))
  750. {
  751. while (ms.Position < ms.Length)
  752. {
  753. byte b = br.ReadByte();
  754. if (DirtyEncoding.BytetoStr.ContainsKey(b))
  755. {
  756. byte[] c = Encoding.UTF8.GetBytes(DirtyEncoding.BytetoStr[b]);
  757. os.Write(c, 0, c.Length);
  758. }
  759. else if (DirtyEncoding.BytetoChar.ContainsKey(b))
  760. {
  761. byte[] c = Encoding.UTF8.GetBytes(DirtyEncoding.BytetoChar[b].ToString());
  762. os.Write(c, 0, c.Length);
  763. }
  764. else if(ms.Position < ms.Length)
  765. {
  766. byte c = br.ReadByte();
  767. ushort i = BitConverter.ToUInt16(new byte[] { c,b }, 0);
  768. switch (b)
  769. {
  770. case 0x06:
  771. if (ColorCode.ContainsKey(i))
  772. bw.Write(Encoding.UTF8.GetBytes($"<Color: \"{ColorCode[i]}\">"));
  773. else
  774. bw.Write(Encoding.UTF8.GetBytes($"<Color: {string.Format("0x{0:X2}", i)}>"));
  775. break;
  776. case 0x05:
  777. if (Icons.ContainsKey(i))
  778. bw.Write(Encoding.UTF8.GetBytes($"<Icon_Button: \"{Icons[i]}\">"));
  779. else
  780. bw.Write(Encoding.UTF8.GetBytes($"<Icon_Button: {string.Format("0x{0:X2}", i)}>"));
  781. break;
  782. case 0x03:
  783. if (Names.ContainsKey(i))
  784. bw.Write(Encoding.UTF8.GetBytes($"<Name: \"{Names[i]}\">"));
  785. else
  786. bw.Write(Encoding.UTF8.GetBytes($"<Name: {string.Format("0x{0:X2}", i)}>"));
  787. break;
  788. case 0x0C:
  789. if (Spell.ContainsKey(i))
  790. bw.Write(Encoding.UTF8.GetBytes($"<Spell_GF: \"{Spell[i]}\">"));
  791. else
  792. bw.Write(Encoding.UTF8.GetBytes($"<Spell_GF: {string.Format("0x{0:X2}", i)}>"));
  793. break;
  794. case 0x0A:
  795. case 0x0B://0x0B can be 2 or 3 bytes only grabbing 2 so might have extra rando character near
  796. if (Special.ContainsKey(i))
  797. bw.Write(Encoding.UTF8.GetBytes($"<Special: \"{Special[i]}\">"));
  798. else
  799. bw.Write(Encoding.UTF8.GetBytes($"<Special: {string.Format("0x{0:X2}", i)}>"));
  800. break;
  801. case 0xC4:
  802. ms.Seek(-1, SeekOrigin.Current);
  803. bw.Write(Encoding.UTF8.GetBytes(string.Format("0x{0:X2}", (int)b)));
  804. break;
  805. default:
  806. bw.Write(Encoding.UTF8.GetBytes(string.Format("0x{0:X2}", i)));
  807. break;
  808. }
  809. }
  810. else
  811. {
  812. bw.Write(b);
  813. }
  814. }
  815. if (os.Length > 0)
  816. return os.ToArray();
  817. }
  818. return null;
  819. }
  820. /*
  821. * myst6re code
  822. *
  823. *
  824. *
  825. for(int i=0 ; i<size ; ++i) {
  826. caract = (quint8)ff8Text.at(i);
  827. if(caract==0) break;
  828. switch(caract) {
  829. case 0x1: // New Page
  830. if(height>maxH) maxH = height;
  831. if(width>maxW) maxW = width;
  832. width = 15;
  833. height = 28;
  834. pagesPos.append(i+1);
  835. break;
  836. case 0x2: // \n
  837. if(width>maxW) maxW = width;
  838. ++line;
  839. width = (ask_first<=line && ask_last>=line ? 79 : 15);//32+15+32 (padding for arrow) or 15
  840. height += 16;
  841. break;
  842. case 0x3: // Character names
  843. caract = (quint8)ff8Text.at(++i);
  844. if(caract>=0x30 && caract<=0x3a)
  845. width += namesWidth[caract-0x30];
  846. else if(caract==0x40)
  847. width += namesWidth[11];
  848. else if(caract==0x50)
  849. width += namesWidth[12];
  850. else if(caract==0x60)
  851. width += namesWidth[13];
  852. break;
  853. case 0x4: // Vars
  854. caract = (quint8)ff8Text.at(++i);
  855. if((caract>=0x20 && caract<=0x27) || (caract>=0x30 && caract<=0x37))
  856. width += font->charWidth(0, 1);// 0
  857. else if(caract>=0x40 && caract<=0x47)
  858. width += font->charWidth(0, 1)*8;// 00000000
  859. break;
  860. case 0x5: // Icons
  861. caract = (quint8)ff8Text.at(++i)-0x20;
  862. if(caract<96)
  863. width += iconWidth[caract]+iconPadding[caract];
  864. break;
  865. case 0xe: // Locations
  866. caract = (quint8)ff8Text.at(++i);
  867. if(caract>=0x20 && caract<=0x27)
  868. width += locationsWidth[caract-0x20];
  869. break;
  870. case 0x19: // Jap 1
  871. if(jp) {
  872. caract = (quint8)ff8Text.at(++i);
  873. if(caract>=0x20)
  874. width += font->charWidth(1, caract-0x20);
  875. }
  876. break;
  877. case 0x1a: // Jap 2
  878. if(jp) {
  879. caract = (quint8)ff8Text.at(++i);
  880. if(caract>=0x20)
  881. width += font->charWidth(2, caract-0x20);
  882. }
  883. break;
  884. case 0x1b: // Jap 3
  885. if(jp) {
  886. caract = (quint8)ff8Text.at(++i);
  887. if(caract>=0x20)
  888. width += font->charWidth(3, caract-0x20);
  889. }
  890. break;
  891. case 0x1c: // Jap 4
  892. if(tdwFile) {
  893. caract = (quint8)ff8Text.at(++i);
  894. if(caract>=0x20)
  895. width += tdwFile->charWidth(0, caract-0x20);
  896. }
  897. break;
  898. default:
  899. if(caract<0x20)
  900. ++i;
  901. else if(jp) {
  902. width += font->charWidth(0, caract-0x20);
  903. } else {
  904. if(caract<232)
  905. width += font->charWidth(0, caract-0x20);
  906. else if(caract>=232)
  907. width += font->charWidth(0, (quint8)optimisedDuo[caract-232][0]) + font->charWidth(0, (quint8)optimisedDuo[caract-232][1]);
  908. }
  909. break;
  910. }
  911. }
  912. if(height>maxH) maxH = height;
  913. if(width>maxW) maxW = width;
  914. if(maxW>322) maxW = 322;
  915. if(maxH>226) maxH = 226;
  916. update();
  917. */
  918. }
  919. }