Introduce >2GB compatible PR 1424 from fdkekin0
This commit is contained in:
@@ -353,7 +353,6 @@ enum class StrId : uint16_t {
|
|||||||
STR_OPDS_BROWSER,
|
STR_OPDS_BROWSER,
|
||||||
STR_COVER_CUSTOM,
|
STR_COVER_CUSTOM,
|
||||||
STR_PAGE_OVERLAY,
|
STR_PAGE_OVERLAY,
|
||||||
STR_RECENTS,
|
|
||||||
STR_MENU_RECENT_BOOKS,
|
STR_MENU_RECENT_BOOKS,
|
||||||
STR_NO_RECENT_BOOKS,
|
STR_NO_RECENT_BOOKS,
|
||||||
STR_CALIBRE_DESC,
|
STR_CALIBRE_DESC,
|
||||||
@@ -418,8 +417,6 @@ enum class StrId : uint16_t {
|
|||||||
STR_AUTO_TURN_ENABLED,
|
STR_AUTO_TURN_ENABLED,
|
||||||
STR_AUTO_TURN_PAGES_PER_MIN,
|
STR_AUTO_TURN_PAGES_PER_MIN,
|
||||||
STR_INFO,
|
STR_INFO,
|
||||||
STR_AUTHOR,
|
|
||||||
STR_SERIES,
|
|
||||||
STR_FILE_SIZE,
|
STR_FILE_SIZE,
|
||||||
STR_SLEEP_COVER_OVERLAY,
|
STR_SLEEP_COVER_OVERLAY,
|
||||||
STR_OVERLAY_WHITE,
|
STR_OVERLAY_WHITE,
|
||||||
|
|||||||
+186
-265
@@ -1,4 +1,5 @@
|
|||||||
#include "I18nStrings.h"
|
#include "I18nStrings.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
// THIS FILE IS AUTO-GENERATED BY gen_i18n.py. DO NOT EDIT.
|
// THIS FILE IS AUTO-GENERATED BY gen_i18n.py. DO NOT EDIT.
|
||||||
@@ -1224,7 +1225,6 @@ const char STRINGS_EN_DATA[] =
|
|||||||
"OPDS Browser\0"
|
"OPDS Browser\0"
|
||||||
"Cover + Custom\0"
|
"Cover + Custom\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Recent Books\0"
|
"Recent Books\0"
|
||||||
"No recent books\0"
|
"No recent books\0"
|
||||||
"Use Calibre wireless device transfers\0"
|
"Use Calibre wireless device transfers\0"
|
||||||
@@ -1289,8 +1289,6 @@ const char STRINGS_EN_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -1340,15 +1338,14 @@ const uint16_t OFFSETS_EN[] = {
|
|||||||
3526, 3534, 3541, 3549, 3554, 3563, 3569, 3573, 3576, 3581, 3586, 3589,
|
3526, 3534, 3541, 3549, 3554, 3563, 3569, 3573, 3576, 3581, 3586, 3589,
|
||||||
3593, 3601, 3606, 3612, 3615, 3620, 3623, 3649, 3658, 3679, 3698, 3723,
|
3593, 3601, 3606, 3612, 3615, 3620, 3623, 3649, 3658, 3679, 3698, 3723,
|
||||||
3736, 3759, 3764, 3771, 3777, 3782, 3790, 3801, 3812, 3820, 3826, 3834,
|
3736, 3759, 3764, 3771, 3777, 3782, 3790, 3801, 3812, 3820, 3826, 3834,
|
||||||
3843, 3851, 3856, 3870, 3890, 3910, 3923, 3938, 3951, 3959, 3972, 3988,
|
3843, 3851, 3856, 3870, 3890, 3910, 3923, 3938, 3951, 3964, 3980, 4018,
|
||||||
4026, 4068, 4075, 4095, 4101, 4108, 4114, 4122, 4157, 4168, 4185, 4225,
|
4060, 4067, 4087, 4093, 4100, 4106, 4114, 4149, 4160, 4177, 4217, 4252,
|
||||||
4260, 4278, 4299, 4317, 4336, 4344, 4352, 4366, 4384, 4391, 4398, 4414,
|
4270, 4291, 4309, 4328, 4336, 4344, 4358, 4376, 4383, 4390, 4406, 4416,
|
||||||
4424, 4436, 4443, 4478, 4507, 4523, 4552, 4586, 4614, 4641, 4671, 4693,
|
4428, 4435, 4470, 4499, 4515, 4544, 4578, 4606, 4633, 4663, 4685, 4711,
|
||||||
4719, 4755, 4771, 4779, 4786, 4810, 4837, 4848, 4870, 4892, 4917, 4942,
|
4747, 4763, 4771, 4778, 4802, 4829, 4840, 4862, 4884, 4909, 4934, 4953,
|
||||||
4961, 4973, 4982, 4989, 5002, 5017, 5033, 5043, 5069, 5076, 5092, 5112,
|
4965, 4974, 4981, 4994, 5009, 5025, 5035, 5061, 5068, 5084, 5104, 5133,
|
||||||
5141, 5146, 5153, 5160, 5165, 5191, 5197, 5202, 5208, 5212, 5251, 5278,
|
5138, 5143, 5169, 5175, 5180, 5186, 5190, 5229, 5256, 5284, 5303, 5327,
|
||||||
5306, 5325, 5349, 5374, 5385, 5390, 5394, 5398, 5407, 5416, 5426, 5437,
|
5352, 5363, 5368, 5372, 5376, 5385, 5394, 5404, 5415, 5422, 5431, 5449,
|
||||||
5444, 5453, 5471,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_ES_DATA[] =
|
const char STRINGS_ES_DATA[] =
|
||||||
@@ -1796,7 +1793,6 @@ const char STRINGS_ES_DATA[] =
|
|||||||
"Navegador OPDS\0"
|
"Navegador OPDS\0"
|
||||||
"Portada + Pers.\0"
|
"Portada + Pers.\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Libros recientes\0"
|
"Libros recientes\0"
|
||||||
"No hay libros recientes\0"
|
"No hay libros recientes\0"
|
||||||
"Transferir contenido a este dispositivo\0"
|
"Transferir contenido a este dispositivo\0"
|
||||||
@@ -1925,8 +1921,6 @@ const char STRINGS_ES_DATA[] =
|
|||||||
"\xA1"
|
"\xA1"
|
||||||
"ginas por minuto\0"
|
"ginas por minuto\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -1976,15 +1970,14 @@ const uint16_t OFFSETS_ES[] = {
|
|||||||
4131, 4141, 4150, 4159, 4165, 4175, 4186, 4190, 4193, 4201, 4209, 4218,
|
4131, 4141, 4150, 4159, 4165, 4175, 4186, 4190, 4193, 4201, 4209, 4218,
|
||||||
4230, 4245, 4250, 4256, 4262, 4268, 4271, 4305, 4315, 4344, 4371, 4397,
|
4230, 4245, 4250, 4256, 4262, 4268, 4271, 4305, 4315, 4344, 4371, 4397,
|
||||||
4415, 4443, 4448, 4454, 4460, 4466, 4476, 4489, 4507, 4525, 4533, 4542,
|
4415, 4443, 4448, 4454, 4460, 4466, 4476, 4489, 4507, 4525, 4533, 4542,
|
||||||
4551, 4560, 4565, 4580, 4611, 4642, 4657, 4673, 4686, 4694, 4711, 4735,
|
4551, 4560, 4565, 4580, 4611, 4642, 4657, 4673, 4686, 4703, 4727, 4767,
|
||||||
4775, 4825, 4833, 4854, 4869, 4876, 4883, 4898, 4941, 4953, 4965, 5015,
|
4817, 4825, 4846, 4861, 4868, 4875, 4890, 4933, 4945, 4957, 5007, 5053,
|
||||||
5061, 5084, 5111, 5132, 5154, 5161, 5184, 5216, 5240, 5247, 5254, 5278,
|
5076, 5103, 5124, 5146, 5153, 5176, 5208, 5232, 5239, 5246, 5270, 5277,
|
||||||
5285, 5297, 5305, 5342, 5378, 5407, 5440, 5482, 5513, 5540, 5570, 5591,
|
5289, 5297, 5334, 5370, 5399, 5432, 5474, 5505, 5532, 5562, 5583, 5618,
|
||||||
5626, 5680, 5703, 5711, 5718, 5748, 5783, 5792, 5816, 5837, 5869, 5895,
|
5672, 5695, 5703, 5710, 5740, 5775, 5784, 5808, 5829, 5861, 5887, 5906,
|
||||||
5914, 5939, 5946, 5952, 5969, 5986, 6008, 6023, 6059, 6068, 6094, 6116,
|
5931, 5938, 5944, 5961, 5978, 6000, 6015, 6051, 6060, 6086, 6108, 6133,
|
||||||
6141, 6146, 6153, 6160, 6165, 6191, 6197, 6202, 6208, 6212, 6251, 6278,
|
6138, 6143, 6169, 6175, 6180, 6186, 6190, 6229, 6256, 6284, 6303, 6327,
|
||||||
6306, 6325, 6349, 6374, 6385, 6390, 6394, 6398, 6407, 6416, 6426, 6437,
|
6352, 6363, 6368, 6372, 6376, 6385, 6394, 6404, 6415, 6422, 6431, 6449,
|
||||||
6444, 6453, 6471,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_FR_DATA[] =
|
const char STRINGS_FR_DATA[] =
|
||||||
@@ -2547,7 +2540,6 @@ const char STRINGS_FR_DATA[] =
|
|||||||
"Navigateur OPDS\0"
|
"Navigateur OPDS\0"
|
||||||
"Couverture + Perso\0"
|
"Couverture + Perso\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Livres r\xC3"
|
"Livres r\xC3"
|
||||||
"\xA9"
|
"\xA9"
|
||||||
"cents\0"
|
"cents\0"
|
||||||
@@ -2683,8 +2675,6 @@ const char STRINGS_FR_DATA[] =
|
|||||||
"Tourne-page auto : \0"
|
"Tourne-page auto : \0"
|
||||||
"Tourne-page auto (pages par minute)\0"
|
"Tourne-page auto (pages par minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -2734,15 +2724,14 @@ const uint16_t OFFSETS_FR[] = {
|
|||||||
3905, 3915, 3923, 3933, 3940, 3954, 3965, 3969, 3973, 3982, 3990, 3993,
|
3905, 3915, 3923, 3933, 3940, 3954, 3965, 3969, 3973, 3982, 3990, 3993,
|
||||||
3997, 4009, 4016, 4023, 4028, 4032, 4035, 4059, 4069, 4100, 4128, 4155,
|
3997, 4009, 4016, 4023, 4028, 4032, 4035, 4059, 4069, 4100, 4128, 4155,
|
||||||
4176, 4199, 4204, 4212, 4221, 4227, 4236, 4248, 4263, 4271, 4277, 4286,
|
4176, 4199, 4204, 4212, 4221, 4227, 4236, 4248, 4263, 4271, 4277, 4286,
|
||||||
4303, 4313, 4318, 4332, 4365, 4392, 4408, 4427, 4440, 4448, 4464, 4484,
|
4303, 4313, 4318, 4332, 4365, 4392, 4408, 4427, 4440, 4456, 4476, 4512,
|
||||||
4520, 4560, 4568, 4590, 4604, 4611, 4619, 4627, 4657, 4670, 4686, 4717,
|
4552, 4560, 4582, 4596, 4603, 4611, 4619, 4649, 4662, 4678, 4709, 4732,
|
||||||
4740, 4758, 4772, 4790, 4808, 4819, 4834, 4854, 4876, 4886, 4893, 4916,
|
4750, 4764, 4782, 4800, 4811, 4826, 4846, 4868, 4878, 4885, 4908, 4920,
|
||||||
4928, 4940, 4949, 4988, 5023, 5047, 5066, 5085, 5117, 5144, 5174, 5195,
|
4932, 4941, 4980, 5015, 5039, 5058, 5077, 5109, 5136, 5166, 5187, 5205,
|
||||||
5213, 5255, 5278, 5289, 5297, 5319, 5344, 5354, 5385, 5412, 5440, 5468,
|
5247, 5270, 5281, 5289, 5311, 5336, 5346, 5377, 5404, 5432, 5460, 5483,
|
||||||
5491, 5512, 5521, 5529, 5544, 5560, 5577, 5598, 5625, 5632, 5649, 5669,
|
5504, 5513, 5521, 5536, 5552, 5569, 5590, 5617, 5624, 5641, 5661, 5697,
|
||||||
5705, 5710, 5717, 5724, 5729, 5755, 5761, 5766, 5772, 5776, 5815, 5842,
|
5702, 5707, 5733, 5739, 5744, 5750, 5754, 5793, 5820, 5848, 5867, 5891,
|
||||||
5870, 5889, 5913, 5938, 5949, 5954, 5958, 5962, 5971, 5980, 5990, 6001,
|
5916, 5927, 5932, 5936, 5940, 5949, 5958, 5968, 5979, 5986, 5995, 6013,
|
||||||
6008, 6017, 6035,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_DE_DATA[] =
|
const char STRINGS_DE_DATA[] =
|
||||||
@@ -3130,7 +3119,6 @@ const char STRINGS_DE_DATA[] =
|
|||||||
"OPDS-Browser\0"
|
"OPDS-Browser\0"
|
||||||
"Umschlag + Eigenes\0"
|
"Umschlag + Eigenes\0"
|
||||||
"Seiten-Overlay\0"
|
"Seiten-Overlay\0"
|
||||||
"Zuletzt\0"
|
|
||||||
"Zuletzt gelesen\0"
|
"Zuletzt gelesen\0"
|
||||||
"Keine B\xC3"
|
"Keine B\xC3"
|
||||||
"\xBC"
|
"\xBC"
|
||||||
@@ -3233,8 +3221,6 @@ const char STRINGS_DE_DATA[] =
|
|||||||
"\xA4"
|
"\xA4"
|
||||||
"ttern (Seiten/Min.)\0"
|
"ttern (Seiten/Min.)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Autor\0"
|
|
||||||
"Reihe\0"
|
|
||||||
"Gr\xC3"
|
"Gr\xC3"
|
||||||
"\xB6"
|
"\xB6"
|
||||||
"\xC3"
|
"\xC3"
|
||||||
@@ -3290,15 +3276,14 @@ const uint16_t OFFSETS_DE[] = {
|
|||||||
3641, 3653, 3663, 3673, 3681, 3695, 3704, 3707, 3712, 3719, 3730, 3733,
|
3641, 3653, 3663, 3673, 3681, 3695, 3704, 3707, 3712, 3719, 3730, 3733,
|
||||||
3737, 3742, 3748, 3755, 3760, 3767, 3770, 3790, 3799, 3821, 3842, 3863,
|
3737, 3742, 3748, 3755, 3760, 3767, 3770, 3790, 3799, 3821, 3842, 3863,
|
||||||
3882, 3896, 3902, 3909, 3914, 3919, 3927, 3938, 3948, 3957, 3963, 3972,
|
3882, 3896, 3902, 3909, 3914, 3919, 3927, 3938, 3948, 3957, 3963, 3972,
|
||||||
3986, 3996, 4001, 4015, 4031, 4054, 4067, 4086, 4101, 4109, 4125, 4139,
|
3986, 3996, 4001, 4015, 4031, 4054, 4067, 4086, 4101, 4117, 4131, 4159,
|
||||||
4167, 4203, 4213, 4232, 4245, 4252, 4259, 4268, 4303, 4308, 4327, 4354,
|
4195, 4205, 4224, 4237, 4244, 4251, 4260, 4295, 4300, 4319, 4346, 4376,
|
||||||
4384, 4403, 4426, 4443, 4461, 4471, 4482, 4510, 4528, 4537, 4547, 4569,
|
4395, 4418, 4435, 4453, 4463, 4474, 4502, 4520, 4529, 4539, 4561, 4570,
|
||||||
4578, 4591, 4598, 4630, 4664, 4688, 4715, 4744, 4776, 4805, 4834, 4859,
|
4583, 4590, 4622, 4656, 4680, 4707, 4736, 4768, 4797, 4826, 4851, 4871,
|
||||||
4879, 4915, 4925, 4933, 4940, 4969, 5001, 5011, 5044, 5074, 5100, 5129,
|
4907, 4917, 4925, 4932, 4961, 4993, 5003, 5036, 5066, 5092, 5121, 5134,
|
||||||
5142, 5157, 5167, 5177, 5187, 5206, 5222, 5232, 5265, 5272, 5293, 5318,
|
5149, 5159, 5169, 5179, 5198, 5214, 5224, 5257, 5264, 5285, 5310, 5341,
|
||||||
5349, 5354, 5360, 5366, 5374, 5395, 5401, 5406, 5412, 5416, 5455, 5482,
|
5346, 5354, 5375, 5381, 5386, 5392, 5396, 5435, 5462, 5490, 5510, 5548,
|
||||||
5510, 5530, 5568, 5607, 5618, 5623, 5627, 5631, 5642, 5652, 5663, 5676,
|
5587, 5598, 5603, 5607, 5611, 5622, 5632, 5643, 5656, 5665, 5671, 5697,
|
||||||
5685, 5691, 5717,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_CS_DATA[] =
|
const char STRINGS_CS_DATA[] =
|
||||||
@@ -4373,7 +4358,6 @@ const char STRINGS_CS_DATA[] =
|
|||||||
"\xAD"
|
"\xAD"
|
||||||
"\0"
|
"\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Ned\xC3"
|
"Ned\xC3"
|
||||||
"\xA1"
|
"\xA1"
|
||||||
"vn\xC3"
|
"vn\xC3"
|
||||||
@@ -4704,8 +4688,6 @@ const char STRINGS_CS_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -4755,15 +4737,14 @@ const uint16_t OFFSETS_CS[] = {
|
|||||||
4344, 4353, 4361, 4371, 4381, 4391, 4404, 4408, 4411, 4416, 4421, 4425,
|
4344, 4353, 4361, 4371, 4381, 4391, 4404, 4408, 4411, 4416, 4421, 4425,
|
||||||
4429, 4441, 4447, 4454, 4461, 4467, 4470, 4494, 4503, 4524, 4543, 4568,
|
4429, 4441, 4447, 4454, 4461, 4467, 4470, 4494, 4503, 4524, 4543, 4568,
|
||||||
4581, 4604, 4609, 4616, 4622, 4627, 4635, 4646, 4657, 4665, 4671, 4679,
|
4581, 4604, 4609, 4616, 4622, 4627, 4635, 4646, 4657, 4665, 4671, 4679,
|
||||||
4698, 4708, 4713, 4727, 4754, 4786, 4804, 4823, 4836, 4844, 4860, 4885,
|
4698, 4708, 4713, 4727, 4754, 4786, 4804, 4823, 4836, 4852, 4877, 4932,
|
||||||
4940, 4986, 4997, 5020, 5031, 5036, 5044, 5054, 5102, 5116, 5133, 5190,
|
4978, 4989, 5012, 5023, 5028, 5036, 5046, 5094, 5108, 5125, 5182, 5231,
|
||||||
5239, 5261, 5286, 5308, 5331, 5345, 5360, 5383, 5408, 5415, 5422, 5438,
|
5253, 5278, 5300, 5323, 5337, 5352, 5375, 5400, 5407, 5414, 5430, 5440,
|
||||||
5448, 5459, 5466, 5508, 5545, 5567, 5596, 5638, 5677, 5704, 5734, 5759,
|
5451, 5458, 5500, 5537, 5559, 5588, 5630, 5669, 5696, 5726, 5751, 5798,
|
||||||
5806, 5844, 5862, 5874, 5885, 5914, 5946, 5955, 5982, 6007, 6044, 6071,
|
5836, 5854, 5866, 5877, 5906, 5938, 5947, 5974, 5999, 6036, 6063, 6079,
|
||||||
6087, 6115, 6121, 6129, 6140, 6155, 6172, 6182, 6208, 6215, 6241, 6261,
|
6107, 6113, 6121, 6132, 6147, 6164, 6174, 6200, 6207, 6233, 6253, 6282,
|
||||||
6290, 6295, 6302, 6309, 6314, 6340, 6346, 6351, 6357, 6361, 6400, 6427,
|
6287, 6292, 6318, 6324, 6329, 6335, 6339, 6378, 6405, 6433, 6452, 6476,
|
||||||
6455, 6474, 6498, 6523, 6534, 6539, 6543, 6547, 6556, 6565, 6575, 6586,
|
6501, 6512, 6517, 6521, 6525, 6534, 6543, 6553, 6564, 6571, 6580, 6598,
|
||||||
6593, 6602, 6620,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_PO_DATA[] =
|
const char STRINGS_PO_DATA[] =
|
||||||
@@ -5239,7 +5220,6 @@ const char STRINGS_PO_DATA[] =
|
|||||||
"Navegador OPDS\0"
|
"Navegador OPDS\0"
|
||||||
"Capa + personalizado\0"
|
"Capa + personalizado\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Livros recentes\0"
|
"Livros recentes\0"
|
||||||
"Sem livros recentes\0"
|
"Sem livros recentes\0"
|
||||||
"Usar transfer\xC3"
|
"Usar transfer\xC3"
|
||||||
@@ -5380,8 +5360,6 @@ const char STRINGS_PO_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -5431,15 +5409,14 @@ const uint16_t OFFSETS_PO[] = {
|
|||||||
4090, 4100, 4109, 4118, 4124, 4131, 4148, 4152, 4157, 4162, 4167, 4172,
|
4090, 4100, 4109, 4118, 4124, 4131, 4148, 4152, 4157, 4162, 4167, 4172,
|
||||||
4178, 4192, 4201, 4209, 4214, 4220, 4223, 4257, 4267, 4288, 4307, 4332,
|
4178, 4192, 4201, 4209, 4214, 4220, 4223, 4257, 4267, 4288, 4307, 4332,
|
||||||
4345, 4368, 4373, 4380, 4386, 4391, 4399, 4410, 4421, 4429, 4435, 4443,
|
4345, 4368, 4373, 4380, 4386, 4391, 4399, 4410, 4421, 4429, 4435, 4443,
|
||||||
4461, 4471, 4476, 4490, 4517, 4543, 4558, 4579, 4592, 4600, 4616, 4636,
|
4461, 4471, 4476, 4490, 4517, 4543, 4558, 4579, 4592, 4608, 4628, 4668,
|
||||||
4676, 4717, 4726, 4749, 4764, 4771, 4778, 4786, 4833, 4849, 4864, 4921,
|
4709, 4718, 4741, 4756, 4763, 4770, 4778, 4825, 4841, 4856, 4913, 4962,
|
||||||
4970, 4990, 5013, 5035, 5056, 5066, 5084, 5106, 5129, 5137, 5144, 5160,
|
4982, 5005, 5027, 5048, 5058, 5076, 5098, 5121, 5129, 5136, 5152, 5163,
|
||||||
5171, 5183, 5190, 5232, 5261, 5289, 5321, 5359, 5388, 5415, 5445, 5467,
|
5175, 5182, 5224, 5253, 5281, 5313, 5351, 5380, 5407, 5437, 5459, 5490,
|
||||||
5498, 5548, 5570, 5578, 5585, 5610, 5638, 5645, 5670, 5693, 5728, 5752,
|
5540, 5562, 5570, 5577, 5602, 5630, 5637, 5662, 5685, 5720, 5744, 5763,
|
||||||
5771, 5796, 5804, 5811, 5827, 5843, 5864, 5874, 5900, 5907, 5921, 5941,
|
5788, 5796, 5803, 5819, 5835, 5856, 5866, 5892, 5899, 5913, 5933, 5962,
|
||||||
5970, 5975, 5982, 5989, 5994, 6020, 6026, 6031, 6037, 6041, 6080, 6107,
|
5967, 5972, 5998, 6004, 6009, 6015, 6019, 6058, 6085, 6113, 6132, 6156,
|
||||||
6135, 6154, 6178, 6203, 6214, 6219, 6223, 6227, 6236, 6245, 6255, 6266,
|
6181, 6192, 6197, 6201, 6205, 6214, 6223, 6233, 6244, 6251, 6260, 6278,
|
||||||
6273, 6282, 6300,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_RU_DATA[] =
|
const char STRINGS_RU_DATA[] =
|
||||||
@@ -10999,7 +10976,6 @@ const char STRINGS_RU_DATA[] =
|
|||||||
"\xB9"
|
"\xB9"
|
||||||
"\0"
|
"\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"\xD0"
|
"\xD0"
|
||||||
"\x9D"
|
"\x9D"
|
||||||
"\xD0"
|
"\xD0"
|
||||||
@@ -12998,8 +12974,6 @@ const char STRINGS_RU_DATA[] =
|
|||||||
"\x83"
|
"\x83"
|
||||||
")\0"
|
")\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -13049,15 +13023,14 @@ const uint16_t OFFSETS_RU[] = {
|
|||||||
5973, 5985, 5998, 6010, 6025, 6040, 6059, 6064, 6071, 6088, 6101, 6108,
|
5973, 5985, 5998, 6010, 6025, 6040, 6059, 6064, 6071, 6088, 6101, 6108,
|
||||||
6117, 6145, 6156, 6169, 6180, 6189, 6192, 6225, 6242, 6293, 6340, 6372,
|
6117, 6145, 6156, 6169, 6180, 6189, 6192, 6225, 6242, 6293, 6340, 6372,
|
||||||
6404, 6459, 6472, 6487, 6502, 6513, 6524, 6538, 6566, 6591, 6608, 6623,
|
6404, 6459, 6472, 6487, 6502, 6513, 6524, 6538, 6566, 6591, 6608, 6623,
|
||||||
6653, 6678, 6683, 6697, 6741, 6798, 6818, 6844, 6857, 6865, 6893, 6926,
|
6653, 6678, 6683, 6697, 6741, 6798, 6818, 6844, 6857, 6885, 6918, 6993,
|
||||||
7001, 7078, 7091, 7115, 7134, 7147, 7164, 7188, 7249, 7273, 7299, 7380,
|
7070, 7083, 7107, 7126, 7139, 7156, 7180, 7241, 7265, 7291, 7372, 7456,
|
||||||
7464, 7495, 7538, 7569, 7602, 7622, 7642, 7692, 7725, 7740, 7747, 7805,
|
7487, 7530, 7561, 7594, 7614, 7634, 7684, 7717, 7732, 7739, 7797, 7809,
|
||||||
7817, 7828, 7840, 7885, 7939, 7984, 8028, 8093, 8155, 8182, 8212, 8251,
|
7820, 7832, 7877, 7931, 7976, 8020, 8085, 8147, 8174, 8204, 8243, 8298,
|
||||||
8306, 8373, 8404, 8424, 8444, 8483, 8506, 8515, 8570, 8625, 8679, 8729,
|
8365, 8396, 8416, 8436, 8475, 8498, 8507, 8562, 8617, 8671, 8721, 8758,
|
||||||
8766, 8806, 8819, 8838, 8860, 8892, 8916, 8937, 9000, 9015, 9056, 9097,
|
8798, 8811, 8830, 8852, 8884, 8908, 8929, 8992, 9007, 9048, 9089, 9146,
|
||||||
9154, 9159, 9166, 9173, 9178, 9204, 9210, 9215, 9221, 9225, 9264, 9291,
|
9151, 9156, 9182, 9188, 9193, 9199, 9203, 9242, 9269, 9297, 9316, 9340,
|
||||||
9319, 9338, 9362, 9387, 9398, 9403, 9407, 9411, 9420, 9429, 9439, 9450,
|
9365, 9376, 9381, 9385, 9389, 9398, 9407, 9417, 9428, 9435, 9444, 9462,
|
||||||
9457, 9466, 9484,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_SV_DATA[] =
|
const char STRINGS_SV_DATA[] =
|
||||||
@@ -13662,7 +13635,6 @@ const char STRINGS_SV_DATA[] =
|
|||||||
"sare\0"
|
"sare\0"
|
||||||
"Omslag + Valfri\0"
|
"Omslag + Valfri\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Senaste b\xC3"
|
"Senaste b\xC3"
|
||||||
"\xB6"
|
"\xB6"
|
||||||
"ckerna\0"
|
"ckerna\0"
|
||||||
@@ -13825,8 +13797,6 @@ const char STRINGS_SV_DATA[] =
|
|||||||
"\xA4"
|
"\xA4"
|
||||||
"ndning (sidor per minut)\0"
|
"ndning (sidor per minut)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -13876,15 +13846,14 @@ const uint16_t OFFSETS_SV[] = {
|
|||||||
3961, 3971, 3978, 3985, 3992, 4002, 4016, 4019, 4023, 4028, 4034, 4038,
|
3961, 3971, 3978, 3985, 3992, 4002, 4016, 4019, 4023, 4028, 4034, 4038,
|
||||||
4041, 4056, 4065, 4072, 4076, 4080, 4085, 4113, 4122, 4142, 4164, 4189,
|
4041, 4056, 4065, 4072, 4076, 4080, 4085, 4113, 4122, 4142, 4164, 4189,
|
||||||
4208, 4240, 4245, 4252, 4258, 4262, 4270, 4281, 4290, 4310, 4316, 4324,
|
4208, 4240, 4245, 4252, 4258, 4262, 4270, 4281, 4290, 4310, 4316, 4324,
|
||||||
4350, 4359, 4364, 4377, 4403, 4423, 4440, 4456, 4469, 4477, 4495, 4516,
|
4350, 4359, 4364, 4377, 4403, 4423, 4440, 4456, 4469, 4487, 4508, 4555,
|
||||||
4563, 4608, 4614, 4632, 4645, 4652, 4658, 4667, 4705, 4716, 4732, 4781,
|
4600, 4606, 4624, 4637, 4644, 4650, 4659, 4697, 4708, 4724, 4773, 4811,
|
||||||
4819, 4841, 4867, 4893, 4918, 4929, 4937, 4961, 4977, 4984, 4991, 5012,
|
4833, 4859, 4885, 4910, 4921, 4929, 4953, 4969, 4976, 4983, 5004, 5013,
|
||||||
5021, 5033, 5038, 5082, 5114, 5135, 5158, 5197, 5220, 5247, 5277, 5297,
|
5025, 5030, 5074, 5106, 5127, 5150, 5189, 5212, 5239, 5269, 5289, 5315,
|
||||||
5323, 5364, 5380, 5388, 5396, 5419, 5445, 5457, 5480, 5506, 5532, 5562,
|
5356, 5372, 5380, 5388, 5411, 5437, 5449, 5472, 5498, 5524, 5554, 5575,
|
||||||
5583, 5611, 5619, 5631, 5639, 5654, 5672, 5681, 5714, 5722, 5739, 5772,
|
5603, 5611, 5623, 5631, 5646, 5664, 5673, 5706, 5714, 5731, 5764, 5803,
|
||||||
5811, 5816, 5823, 5830, 5835, 5861, 5867, 5872, 5878, 5882, 5921, 5948,
|
5808, 5813, 5839, 5845, 5850, 5856, 5860, 5899, 5926, 5954, 5973, 5997,
|
||||||
5976, 5995, 6019, 6044, 6055, 6060, 6064, 6068, 6077, 6086, 6096, 6107,
|
6022, 6033, 6038, 6042, 6046, 6055, 6064, 6074, 6085, 6092, 6101, 6119,
|
||||||
6114, 6123, 6141,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_RO_DATA[] =
|
const char STRINGS_RO_DATA[] =
|
||||||
@@ -14598,7 +14567,6 @@ const char STRINGS_RO_DATA[] =
|
|||||||
"\x83"
|
"\x83"
|
||||||
" + Personalizat\0"
|
" + Personalizat\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"C\xC4"
|
"C\xC4"
|
||||||
"\x83"
|
"\x83"
|
||||||
"r\xC5"
|
"r\xC5"
|
||||||
@@ -14791,8 +14759,6 @@ const char STRINGS_RO_DATA[] =
|
|||||||
": \0"
|
": \0"
|
||||||
"Pagini pe minut\0"
|
"Pagini pe minut\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -14842,15 +14808,14 @@ const uint16_t OFFSETS_RO[] = {
|
|||||||
4235, 4245, 4253, 4263, 4274, 4284, 4297, 4300, 4303, 4314, 4322, 4329,
|
4235, 4245, 4253, 4263, 4274, 4284, 4297, 4300, 4303, 4314, 4322, 4329,
|
||||||
4335, 4348, 4356, 4364, 4368, 4372, 4375, 4398, 4407, 4434, 4463, 4488,
|
4335, 4348, 4356, 4364, 4368, 4372, 4375, 4398, 4407, 4434, 4463, 4488,
|
||||||
4505, 4530, 4539, 4545, 4553, 4559, 4567, 4580, 4596, 4611, 4617, 4625,
|
4505, 4530, 4539, 4545, 4553, 4559, 4567, 4580, 4596, 4611, 4617, 4625,
|
||||||
4633, 4640, 4645, 4659, 4687, 4713, 4726, 4750, 4763, 4771, 4787, 4808,
|
4633, 4640, 4645, 4659, 4687, 4713, 4726, 4750, 4763, 4779, 4800, 4861,
|
||||||
4869, 4918, 4926, 4946, 4958, 4964, 4974, 4983, 5029, 5040, 5054, 5104,
|
4910, 4918, 4938, 4950, 4956, 4966, 4975, 5021, 5032, 5046, 5096, 5134,
|
||||||
5142, 5162, 5185, 5205, 5225, 5239, 5246, 5267, 5291, 5302, 5309, 5336,
|
5154, 5177, 5197, 5217, 5231, 5238, 5259, 5283, 5294, 5301, 5328, 5338,
|
||||||
5346, 5359, 5367, 5407, 5441, 5465, 5502, 5545, 5587, 5614, 5644, 5672,
|
5351, 5359, 5399, 5433, 5457, 5494, 5537, 5579, 5606, 5636, 5664, 5694,
|
||||||
5702, 5743, 5759, 5767, 5774, 5802, 5833, 5845, 5870, 5899, 5928, 5960,
|
5735, 5751, 5759, 5766, 5794, 5825, 5837, 5862, 5891, 5920, 5952, 5972,
|
||||||
5980, 6002, 6013, 6025, 6041, 6058, 6074, 6089, 6111, 6118, 6133, 6155,
|
5994, 6005, 6017, 6033, 6050, 6066, 6081, 6103, 6110, 6125, 6147, 6163,
|
||||||
6171, 6176, 6183, 6190, 6195, 6221, 6227, 6232, 6238, 6242, 6281, 6308,
|
6168, 6173, 6199, 6205, 6210, 6216, 6220, 6259, 6286, 6314, 6333, 6357,
|
||||||
6336, 6355, 6379, 6404, 6415, 6420, 6424, 6428, 6437, 6446, 6456, 6467,
|
6382, 6393, 6398, 6402, 6406, 6415, 6424, 6434, 6445, 6452, 6461, 6479,
|
||||||
6474, 6483, 6501,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_CA_DATA[] =
|
const char STRINGS_CA_DATA[] =
|
||||||
@@ -15336,7 +15301,6 @@ const char STRINGS_CA_DATA[] =
|
|||||||
"Navegador OPDS\0"
|
"Navegador OPDS\0"
|
||||||
"Portada + Personalitzat\0"
|
"Portada + Personalitzat\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Llibres recents\0"
|
"Llibres recents\0"
|
||||||
"No hi ha llibres recents\0"
|
"No hi ha llibres recents\0"
|
||||||
"Usa les transfer\xC3"
|
"Usa les transfer\xC3"
|
||||||
@@ -15479,8 +15443,6 @@ const char STRINGS_CA_DATA[] =
|
|||||||
"\xA0"
|
"\xA0"
|
||||||
"gines per minut)\0"
|
"gines per minut)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -15530,15 +15492,14 @@ const uint16_t OFFSETS_CA[] = {
|
|||||||
4469, 4478, 4489, 4498, 4503, 4514, 4525, 4529, 4532, 4540, 4547, 4550,
|
4469, 4478, 4489, 4498, 4503, 4514, 4525, 4529, 4532, 4540, 4547, 4550,
|
||||||
4554, 4567, 4576, 4582, 4588, 4594, 4597, 4626, 4635, 4665, 4700, 4735,
|
4554, 4567, 4576, 4582, 4588, 4594, 4597, 4626, 4635, 4665, 4700, 4735,
|
||||||
4753, 4783, 4788, 4796, 4805, 4812, 4821, 4833, 4851, 4865, 4872, 4880,
|
4753, 4783, 4788, 4796, 4805, 4812, 4821, 4833, 4851, 4865, 4872, 4880,
|
||||||
4903, 4912, 4917, 4930, 4965, 4995, 5010, 5034, 5047, 5055, 5071, 5096,
|
4903, 4912, 4917, 4930, 4965, 4995, 5010, 5034, 5047, 5063, 5088, 5134,
|
||||||
5142, 5180, 5187, 5218, 5228, 5234, 5242, 5254, 5293, 5305, 5317, 5376,
|
5172, 5179, 5210, 5220, 5226, 5234, 5246, 5285, 5297, 5309, 5368, 5417,
|
||||||
5425, 5443, 5463, 5483, 5500, 5509, 5523, 5547, 5582, 5590, 5597, 5624,
|
5435, 5455, 5475, 5492, 5501, 5515, 5539, 5574, 5582, 5589, 5616, 5627,
|
||||||
5635, 5650, 5659, 5697, 5733, 5767, 5809, 5853, 5891, 5918, 5948, 5978,
|
5642, 5651, 5689, 5725, 5759, 5801, 5845, 5883, 5910, 5940, 5970, 6002,
|
||||||
6010, 6062, 6084, 6091, 6098, 6123, 6151, 6160, 6185, 6208, 6238, 6270,
|
6054, 6076, 6083, 6090, 6115, 6143, 6152, 6177, 6200, 6230, 6262, 6278,
|
||||||
6286, 6310, 6319, 6324, 6341, 6357, 6379, 6392, 6433, 6443, 6471, 6499,
|
6302, 6311, 6316, 6333, 6349, 6371, 6384, 6425, 6435, 6463, 6491, 6530,
|
||||||
6538, 6543, 6550, 6557, 6562, 6588, 6594, 6599, 6605, 6609, 6648, 6675,
|
6535, 6540, 6566, 6572, 6577, 6583, 6587, 6626, 6653, 6681, 6700, 6724,
|
||||||
6703, 6722, 6746, 6771, 6782, 6787, 6791, 6795, 6804, 6813, 6823, 6834,
|
6749, 6760, 6765, 6769, 6773, 6782, 6791, 6801, 6812, 6819, 6828, 6846,
|
||||||
6841, 6850, 6868,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_UK_DATA[] =
|
const char STRINGS_UK_DATA[] =
|
||||||
@@ -21816,7 +21777,6 @@ const char STRINGS_UK_DATA[] =
|
|||||||
"\xB0"
|
"\xB0"
|
||||||
"\0"
|
"\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"\xD0"
|
"\xD0"
|
||||||
"\x9E"
|
"\x9E"
|
||||||
"\xD1"
|
"\xD1"
|
||||||
@@ -23933,8 +23893,6 @@ const char STRINGS_UK_DATA[] =
|
|||||||
"\xB2"
|
"\xB2"
|
||||||
")\0"
|
")\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -23984,15 +23942,14 @@ const uint16_t OFFSETS_UK[] = {
|
|||||||
6651, 6674, 6693, 6707, 6724, 6738, 6752, 6759, 6764, 6781, 6796, 6807,
|
6651, 6674, 6693, 6707, 6724, 6738, 6752, 6759, 6764, 6781, 6796, 6807,
|
||||||
6816, 6844, 6853, 6864, 6875, 6884, 6887, 6941, 6958, 7003, 7054, 7094,
|
6816, 6844, 6853, 6864, 6875, 6884, 6887, 6941, 6958, 7003, 7054, 7094,
|
||||||
7122, 7165, 7178, 7195, 7208, 7219, 7232, 7248, 7270, 7287, 7298, 7319,
|
7122, 7165, 7178, 7195, 7208, 7219, 7232, 7248, 7270, 7287, 7298, 7319,
|
||||||
7349, 7366, 7371, 7385, 7445, 7496, 7516, 7566, 7579, 7587, 7613, 7650,
|
7349, 7366, 7371, 7385, 7445, 7496, 7516, 7566, 7579, 7605, 7642, 7738,
|
||||||
7746, 7829, 7842, 7866, 7891, 7904, 7921, 7953, 8029, 8055, 8083, 8162,
|
7821, 7834, 7858, 7883, 7896, 7913, 7945, 8021, 8047, 8075, 8154, 8232,
|
||||||
8240, 8273, 8318, 8349, 8382, 8404, 8424, 8466, 8501, 8518, 8525, 8574,
|
8265, 8310, 8341, 8374, 8396, 8416, 8458, 8493, 8510, 8517, 8566, 8581,
|
||||||
8589, 8612, 8625, 8681, 8731, 8770, 8822, 8887, 8949, 8976, 9006, 9051,
|
8604, 8617, 8673, 8723, 8762, 8814, 8879, 8941, 8968, 8998, 9043, 9097,
|
||||||
9105, 9195, 9228, 9250, 9270, 9313, 9359, 9372, 9431, 9488, 9550, 9604,
|
9187, 9220, 9242, 9262, 9305, 9351, 9364, 9423, 9480, 9542, 9596, 9635,
|
||||||
9643, 9690, 9704, 9727, 9749, 9781, 9805, 9818, 9871, 9892, 9918, 9964,
|
9682, 9696, 9719, 9741, 9773, 9797, 9810, 9863, 9884, 9910, 9956, 10001,
|
||||||
10009, 10014, 10021, 10028, 10033, 10059, 10065, 10070, 10076, 10080, 10119, 10146,
|
10006, 10011, 10037, 10043, 10048, 10054, 10058, 10097, 10124, 10152, 10171, 10195,
|
||||||
10174, 10193, 10217, 10242, 10253, 10258, 10262, 10266, 10275, 10284, 10294, 10305,
|
10220, 10231, 10236, 10240, 10244, 10253, 10262, 10272, 10283, 10290, 10299, 10317,
|
||||||
10312, 10321, 10339,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_BE_DATA[] =
|
const char STRINGS_BE_DATA[] =
|
||||||
@@ -29182,7 +29139,6 @@ const char STRINGS_BE_DATA[] =
|
|||||||
"\xB9"
|
"\xB9"
|
||||||
"\0"
|
"\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"\xD0"
|
"\xD0"
|
||||||
"\x9D"
|
"\x9D"
|
||||||
"\xD1"
|
"\xD1"
|
||||||
@@ -30947,8 +30903,6 @@ const char STRINGS_BE_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -30998,15 +30952,14 @@ const uint16_t OFFSETS_BE[] = {
|
|||||||
6034, 6044, 6057, 6069, 6084, 6105, 6124, 6131, 6136, 6141, 6146, 6153,
|
6034, 6044, 6057, 6069, 6084, 6105, 6124, 6131, 6136, 6141, 6146, 6153,
|
||||||
6162, 6190, 6201, 6214, 6225, 6234, 6237, 6270, 6287, 6308, 6327, 6352,
|
6162, 6190, 6201, 6214, 6225, 6234, 6237, 6270, 6287, 6308, 6327, 6352,
|
||||||
6365, 6388, 6393, 6400, 6406, 6411, 6419, 6430, 6441, 6449, 6455, 6463,
|
6365, 6388, 6393, 6400, 6406, 6411, 6419, 6430, 6441, 6449, 6455, 6463,
|
||||||
6493, 6512, 6517, 6531, 6575, 6632, 6652, 6680, 6693, 6701, 6729, 6764,
|
6493, 6512, 6517, 6531, 6575, 6632, 6652, 6680, 6693, 6721, 6756, 6835,
|
||||||
6843, 6918, 6931, 6955, 6970, 6983, 7000, 7024, 7085, 7111, 7139, 7218,
|
6910, 6923, 6947, 6962, 6975, 6992, 7016, 7077, 7103, 7131, 7210, 7294,
|
||||||
7302, 7333, 7376, 7407, 7440, 7464, 7486, 7530, 7565, 7572, 7579, 7595,
|
7325, 7368, 7399, 7432, 7456, 7478, 7522, 7557, 7564, 7571, 7587, 7603,
|
||||||
7611, 7624, 7636, 7681, 7735, 7774, 7824, 7887, 7947, 7974, 8004, 8041,
|
7616, 7628, 7673, 7727, 7766, 7816, 7879, 7939, 7966, 7996, 8033, 8090,
|
||||||
8098, 8170, 8205, 8223, 8241, 8280, 8303, 8312, 8363, 8414, 8470, 8520,
|
8162, 8197, 8215, 8233, 8272, 8295, 8304, 8355, 8406, 8462, 8512, 8549,
|
||||||
8557, 8599, 8614, 8633, 8655, 8685, 8709, 8719, 8745, 8752, 8793, 8813,
|
8591, 8606, 8625, 8647, 8677, 8701, 8711, 8737, 8744, 8785, 8805, 8834,
|
||||||
8842, 8847, 8854, 8861, 8866, 8892, 8898, 8903, 8909, 8913, 8952, 8979,
|
8839, 8844, 8870, 8876, 8881, 8887, 8891, 8930, 8957, 8985, 9004, 9028,
|
||||||
9007, 9026, 9050, 9075, 9086, 9091, 9095, 9099, 9108, 9117, 9127, 9138,
|
9053, 9064, 9069, 9073, 9077, 9086, 9095, 9105, 9116, 9123, 9132, 9150,
|
||||||
9145, 9154, 9172,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_IT_DATA[] =
|
const char STRINGS_IT_DATA[] =
|
||||||
@@ -31310,7 +31263,6 @@ const char STRINGS_IT_DATA[] =
|
|||||||
"Browser OPDS\0"
|
"Browser OPDS\0"
|
||||||
"Copertina + Personalizzato\0"
|
"Copertina + Personalizzato\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Libri Recenti\0"
|
"Libri Recenti\0"
|
||||||
"Nessun libro recente\0"
|
"Nessun libro recente\0"
|
||||||
"Usa i trasferimenti wireless del dispositivo di Calibre\0"
|
"Usa i trasferimenti wireless del dispositivo di Calibre\0"
|
||||||
@@ -31389,8 +31341,6 @@ const char STRINGS_IT_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -31440,15 +31390,14 @@ const uint16_t OFFSETS_IT[] = {
|
|||||||
4219, 4228, 4236, 4245, 4250, 4258, 4266, 4270, 4273, 4278, 4283, 4286,
|
4219, 4228, 4236, 4245, 4250, 4258, 4266, 4270, 4273, 4278, 4283, 4286,
|
||||||
4290, 4304, 4312, 4318, 4321, 4326, 4329, 4362, 4372, 4393, 4412, 4437,
|
4290, 4304, 4312, 4318, 4321, 4326, 4329, 4362, 4372, 4393, 4412, 4437,
|
||||||
4450, 4473, 4478, 4485, 4491, 4496, 4504, 4515, 4526, 4534, 4540, 4548,
|
4450, 4473, 4478, 4485, 4491, 4496, 4504, 4515, 4526, 4534, 4540, 4548,
|
||||||
4556, 4565, 4570, 4582, 4613, 4639, 4652, 4679, 4692, 4700, 4714, 4735,
|
4556, 4565, 4570, 4582, 4613, 4639, 4652, 4679, 4692, 4706, 4727, 4783,
|
||||||
4791, 4844, 4854, 4880, 4895, 4901, 4909, 4921, 4966, 4980, 4995, 5047,
|
4836, 4846, 4872, 4887, 4893, 4901, 4913, 4958, 4972, 4987, 5039, 5081,
|
||||||
5089, 5113, 5137, 5161, 5183, 5192, 5206, 5228, 5248, 5255, 5262, 5278,
|
5105, 5129, 5153, 5175, 5184, 5198, 5220, 5240, 5247, 5254, 5270, 5281,
|
||||||
5289, 5302, 5310, 5346, 5380, 5407, 5442, 5483, 5512, 5539, 5569, 5594,
|
5294, 5302, 5338, 5372, 5399, 5434, 5475, 5504, 5531, 5561, 5586, 5618,
|
||||||
5626, 5672, 5691, 5699, 5707, 5735, 5766, 5775, 5800, 5824, 5856, 5887,
|
5664, 5683, 5691, 5699, 5727, 5758, 5767, 5792, 5816, 5848, 5879, 5899,
|
||||||
5907, 5932, 5941, 5948, 5964, 5980, 6000, 6010, 6036, 6043, 6061, 6081,
|
5924, 5933, 5940, 5956, 5972, 5992, 6002, 6028, 6035, 6053, 6073, 6102,
|
||||||
6110, 6115, 6122, 6129, 6134, 6160, 6166, 6171, 6177, 6181, 6220, 6247,
|
6107, 6112, 6138, 6144, 6149, 6155, 6159, 6198, 6225, 6253, 6272, 6296,
|
||||||
6275, 6294, 6318, 6343, 6354, 6359, 6363, 6367, 6376, 6385, 6395, 6406,
|
6321, 6332, 6337, 6341, 6345, 6354, 6363, 6373, 6384, 6391, 6400, 6418,
|
||||||
6413, 6422, 6440,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_PL_DATA[] =
|
const char STRINGS_PL_DATA[] =
|
||||||
@@ -32172,7 +32121,6 @@ const char STRINGS_PL_DATA[] =
|
|||||||
"\x82"
|
"\x82"
|
||||||
"asne\0"
|
"asne\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Ostatnio czytane\0"
|
"Ostatnio czytane\0"
|
||||||
"Brak ostatnio czytanych\0"
|
"Brak ostatnio czytanych\0"
|
||||||
"Przesy\xC5"
|
"Przesy\xC5"
|
||||||
@@ -32371,8 +32319,6 @@ const char STRINGS_PL_DATA[] =
|
|||||||
"Auto-kartkowanie: \0"
|
"Auto-kartkowanie: \0"
|
||||||
"Auto-kartkowanie (str./min)\0"
|
"Auto-kartkowanie (str./min)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -32422,15 +32368,14 @@ const uint16_t OFFSETS_PL[] = {
|
|||||||
4101, 4112, 4119, 4128, 4136, 4144, 4151, 4155, 4159, 4166, 4172, 4177,
|
4101, 4112, 4119, 4128, 4136, 4144, 4151, 4155, 4159, 4166, 4172, 4177,
|
||||||
4183, 4197, 4202, 4208, 4214, 4220, 4223, 4249, 4258, 4285, 4303, 4321,
|
4183, 4197, 4202, 4208, 4214, 4220, 4223, 4249, 4258, 4285, 4303, 4321,
|
||||||
4336, 4361, 4368, 4376, 4382, 4392, 4402, 4415, 4432, 4441, 4448, 4456,
|
4336, 4361, 4368, 4376, 4382, 4392, 4402, 4415, 4432, 4441, 4448, 4456,
|
||||||
4467, 4475, 4480, 4494, 4536, 4567, 4580, 4599, 4612, 4620, 4637, 4661,
|
4467, 4475, 4480, 4494, 4536, 4567, 4580, 4599, 4612, 4629, 4653, 4689,
|
||||||
4697, 4736, 4745, 4768, 4774, 4781, 4791, 4802, 4851, 4865, 4881, 4925,
|
4728, 4737, 4760, 4766, 4773, 4783, 4794, 4843, 4857, 4873, 4917, 4961,
|
||||||
4969, 4989, 5013, 5031, 5050, 5060, 5088, 5111, 5148, 5154, 5161, 5188,
|
4981, 5005, 5023, 5042, 5052, 5080, 5103, 5140, 5146, 5153, 5180, 5192,
|
||||||
5200, 5212, 5224, 5263, 5296, 5320, 5350, 5384, 5415, 5442, 5472, 5494,
|
5204, 5216, 5255, 5288, 5312, 5342, 5376, 5407, 5434, 5464, 5486, 5519,
|
||||||
5527, 5563, 5583, 5591, 5600, 5628, 5659, 5668, 5692, 5718, 5751, 5778,
|
5555, 5575, 5583, 5592, 5620, 5651, 5660, 5684, 5710, 5743, 5770, 5788,
|
||||||
5796, 5820, 5828, 5836, 5851, 5874, 5891, 5900, 5931, 5938, 5957, 5976,
|
5812, 5820, 5828, 5843, 5866, 5883, 5892, 5923, 5930, 5949, 5968, 5996,
|
||||||
6004, 6009, 6016, 6023, 6028, 6054, 6060, 6065, 6071, 6075, 6114, 6141,
|
6001, 6006, 6032, 6038, 6043, 6049, 6053, 6092, 6119, 6147, 6166, 6190,
|
||||||
6169, 6188, 6212, 6237, 6248, 6253, 6257, 6261, 6270, 6279, 6289, 6300,
|
6215, 6226, 6231, 6235, 6239, 6248, 6257, 6267, 6278, 6285, 6294, 6312,
|
||||||
6307, 6316, 6334,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_FI_DATA[] =
|
const char STRINGS_FI_DATA[] =
|
||||||
@@ -33004,7 +32949,6 @@ const char STRINGS_FI_DATA[] =
|
|||||||
"OPDS-selain\0"
|
"OPDS-selain\0"
|
||||||
"Kansi + mukautettu\0"
|
"Kansi + mukautettu\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Viimeisimm\xC3"
|
"Viimeisimm\xC3"
|
||||||
"\xA4"
|
"\xA4"
|
||||||
"t kirjat\0"
|
"t kirjat\0"
|
||||||
@@ -33169,8 +33113,6 @@ const char STRINGS_FI_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -33220,15 +33162,14 @@ const uint16_t OFFSETS_FI[] = {
|
|||||||
4076, 4085, 4093, 4102, 4107, 4113, 4130, 4137, 4140, 4145, 4150, 4160,
|
4076, 4085, 4093, 4102, 4107, 4113, 4130, 4137, 4140, 4145, 4150, 4160,
|
||||||
4165, 4177, 4183, 4189, 4195, 4200, 4203, 4234, 4244, 4265, 4284, 4309,
|
4165, 4177, 4183, 4189, 4195, 4200, 4203, 4234, 4244, 4265, 4284, 4309,
|
||||||
4322, 4345, 4350, 4357, 4363, 4368, 4376, 4387, 4398, 4406, 4412, 4420,
|
4322, 4345, 4350, 4357, 4363, 4368, 4376, 4387, 4398, 4406, 4412, 4420,
|
||||||
4443, 4453, 4458, 4472, 4505, 4539, 4551, 4570, 4583, 4591, 4612, 4637,
|
4443, 4453, 4458, 4472, 4505, 4539, 4551, 4570, 4583, 4604, 4629, 4672,
|
||||||
4680, 4726, 4733, 4762, 4772, 4777, 4787, 4794, 4835, 4851, 4867, 4909,
|
4718, 4725, 4754, 4764, 4769, 4779, 4786, 4827, 4843, 4859, 4901, 4947,
|
||||||
4955, 4977, 4999, 5018, 5037, 5054, 5068, 5090, 5116, 5123, 5130, 5146,
|
4969, 4991, 5010, 5029, 5046, 5060, 5082, 5108, 5115, 5122, 5138, 5145,
|
||||||
5153, 5165, 5173, 5211, 5244, 5267, 5307, 5351, 5379, 5406, 5436, 5470,
|
5157, 5165, 5203, 5236, 5259, 5299, 5343, 5371, 5398, 5428, 5462, 5492,
|
||||||
5500, 5537, 5558, 5564, 5577, 5609, 5644, 5657, 5682, 5715, 5745, 5773,
|
5529, 5550, 5556, 5569, 5601, 5636, 5649, 5674, 5707, 5737, 5765, 5789,
|
||||||
5797, 5823, 5829, 5838, 5851, 5866, 5889, 5899, 5925, 5932, 5949, 5969,
|
5815, 5821, 5830, 5843, 5858, 5881, 5891, 5917, 5924, 5941, 5961, 5990,
|
||||||
5998, 6003, 6010, 6017, 6022, 6048, 6054, 6059, 6065, 6069, 6108, 6135,
|
5995, 6000, 6026, 6032, 6037, 6043, 6047, 6086, 6113, 6141, 6160, 6184,
|
||||||
6163, 6182, 6206, 6231, 6242, 6247, 6251, 6255, 6264, 6273, 6283, 6294,
|
6209, 6220, 6225, 6229, 6233, 6242, 6251, 6261, 6272, 6279, 6288, 6306,
|
||||||
6301, 6310, 6328,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_DA_DATA[] =
|
const char STRINGS_DA_DATA[] =
|
||||||
@@ -33666,7 +33607,6 @@ const char STRINGS_DA_DATA[] =
|
|||||||
"OPDS Browser\0"
|
"OPDS Browser\0"
|
||||||
"Omslag + Brugerdefineret\0"
|
"Omslag + Brugerdefineret\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Seneste b\xC3"
|
"Seneste b\xC3"
|
||||||
"\xB8"
|
"\xB8"
|
||||||
"ger\0"
|
"ger\0"
|
||||||
@@ -33765,8 +33705,6 @@ const char STRINGS_DA_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -33816,15 +33754,14 @@ const uint16_t OFFSETS_DA[] = {
|
|||||||
3824, 3833, 3842, 3850, 3855, 3864, 3875, 3878, 3882, 3887, 3892, 3899,
|
3824, 3833, 3842, 3850, 3855, 3864, 3875, 3878, 3882, 3887, 3892, 3899,
|
||||||
3907, 3923, 3931, 3938, 3941, 3945, 3948, 3975, 3984, 4005, 4024, 4049,
|
3907, 3923, 3931, 3938, 3941, 3945, 3948, 3975, 3984, 4005, 4024, 4049,
|
||||||
4062, 4085, 4090, 4097, 4103, 4108, 4116, 4127, 4138, 4146, 4152, 4160,
|
4062, 4085, 4090, 4097, 4103, 4108, 4116, 4127, 4138, 4146, 4152, 4160,
|
||||||
4184, 4193, 4198, 4212, 4234, 4256, 4269, 4294, 4307, 4315, 4330, 4351,
|
4184, 4193, 4198, 4212, 4234, 4256, 4269, 4294, 4307, 4322, 4343, 4385,
|
||||||
4393, 4434, 4439, 4458, 4469, 4476, 4480, 4489, 4526, 4539, 4556, 4596,
|
4426, 4431, 4450, 4461, 4468, 4472, 4481, 4518, 4531, 4548, 4588, 4623,
|
||||||
4631, 4649, 4668, 4686, 4703, 4713, 4727, 4750, 4764, 4771, 4778, 4794,
|
4641, 4660, 4678, 4695, 4705, 4719, 4742, 4756, 4763, 4770, 4786, 4796,
|
||||||
4804, 4816, 4822, 4860, 4892, 4913, 4939, 4972, 4998, 5025, 5055, 5078,
|
4808, 4814, 4852, 4884, 4905, 4931, 4964, 4990, 5017, 5047, 5070, 5114,
|
||||||
5122, 5160, 5179, 5188, 5195, 5218, 5244, 5254, 5277, 5302, 5331, 5359,
|
5152, 5171, 5180, 5187, 5210, 5236, 5246, 5269, 5294, 5323, 5351, 5372,
|
||||||
5380, 5407, 5415, 5422, 5434, 5449, 5465, 5475, 5501, 5508, 5526, 5546,
|
5399, 5407, 5414, 5426, 5441, 5457, 5467, 5493, 5500, 5518, 5538, 5567,
|
||||||
5575, 5580, 5587, 5594, 5599, 5625, 5631, 5636, 5642, 5646, 5685, 5712,
|
5572, 5577, 5603, 5609, 5614, 5620, 5624, 5663, 5690, 5718, 5737, 5761,
|
||||||
5740, 5759, 5783, 5808, 5819, 5824, 5828, 5832, 5841, 5850, 5860, 5871,
|
5786, 5797, 5802, 5806, 5810, 5819, 5828, 5838, 5849, 5856, 5865, 5883,
|
||||||
5878, 5887, 5905,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_NL_DATA[] =
|
const char STRINGS_NL_DATA[] =
|
||||||
@@ -33892,10 +33829,10 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"Batterij % verbergen\0"
|
"Batterij % verbergen\0"
|
||||||
"Extra regelafstand alinea\0"
|
"Extra regelafstand alinea\0"
|
||||||
"Tekst Anti-Aliasing\0"
|
"Tekst Anti-Aliasing\0"
|
||||||
"Images\0"
|
"Afbeeldingen\0"
|
||||||
"Display\0"
|
"Weergave\0"
|
||||||
"Placeholder\0"
|
"Placeholder\0"
|
||||||
"Suppress\0"
|
"Verbergen\0"
|
||||||
"Create fallback for invalid TOC\0"
|
"Create fallback for invalid TOC\0"
|
||||||
"Korte klik aan/uit-knop\0"
|
"Korte klik aan/uit-knop\0"
|
||||||
"Leesstand\0"
|
"Leesstand\0"
|
||||||
@@ -33908,7 +33845,7 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"Uitlijning alinea lezer\0"
|
"Uitlijning alinea lezer\0"
|
||||||
"Woordafbreking\0"
|
"Woordafbreking\0"
|
||||||
"Tijd tot slaapstand\0"
|
"Tijd tot slaapstand\0"
|
||||||
"Show Hidden Files\0"
|
"Toon verborgen bestanden\0"
|
||||||
"Use Clock\0"
|
"Use Clock\0"
|
||||||
"Clock Settings\0"
|
"Clock Settings\0"
|
||||||
"Uses more battery; clock may drift\0"
|
"Uses more battery; clock may drift\0"
|
||||||
@@ -34064,7 +34001,7 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"\xAB"
|
"\xAB"
|
||||||
" Home\0"
|
" Home\0"
|
||||||
"Kies\0"
|
"Kies\0"
|
||||||
"Selected\0"
|
"Geselecteerd\0"
|
||||||
"Wissel\0"
|
"Wissel\0"
|
||||||
"Bevestig\0"
|
"Bevestig\0"
|
||||||
"Annuleer\0"
|
"Annuleer\0"
|
||||||
@@ -34110,7 +34047,6 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"OPDS-browser\0"
|
"OPDS-browser\0"
|
||||||
"Omslag + Aangepast\0"
|
"Omslag + Aangepast\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Recente boeken\0"
|
"Recente boeken\0"
|
||||||
"Geen recente boeken\0"
|
"Geen recente boeken\0"
|
||||||
"Gebruik Calibre draadloze overdracht\0"
|
"Gebruik Calibre draadloze overdracht\0"
|
||||||
@@ -34134,7 +34070,7 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"Naar Home\0"
|
"Naar Home\0"
|
||||||
"Voortgang synchroniseren\0"
|
"Voortgang synchroniseren\0"
|
||||||
"Boekcache verwijderen\0"
|
"Boekcache verwijderen\0"
|
||||||
"Delete\0"
|
"Verwijder\0"
|
||||||
"Remove\0"
|
"Remove\0"
|
||||||
"Pagina als QR tonen\0"
|
"Pagina als QR tonen\0"
|
||||||
"Hoofdstuk: \0"
|
"Hoofdstuk: \0"
|
||||||
@@ -34174,11 +34110,9 @@ const char STRINGS_NL_DATA[] =
|
|||||||
"Geen voetnoten op deze pagina\0"
|
"Geen voetnoten op deze pagina\0"
|
||||||
"[link]\0"
|
"[link]\0"
|
||||||
"Screenshot maken\0"
|
"Screenshot maken\0"
|
||||||
"Auto Turn Enabled: \0"
|
"Automatisch omslaan ingeschakeld: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Autom. omslaan (pagina's per minuut)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -34211,32 +34145,31 @@ const uint16_t OFFSETS_NL[] = {
|
|||||||
377, 400, 411, 424, 435, 454, 472, 511, 544, 564, 578, 616,
|
377, 400, 411, 424, 435, 454, 472, 511, 544, 564, 578, 616,
|
||||||
672, 691, 705, 746, 774, 785, 821, 838, 854, 885, 896, 916,
|
672, 691, 705, 746, 774, 785, 821, 838, 854, 885, 896, 916,
|
||||||
940, 945, 967, 979, 1018, 1052, 1084, 1125, 1132, 1138, 1148, 1156,
|
940, 945, 967, 979, 1018, 1052, 1084, 1125, 1132, 1138, 1148, 1156,
|
||||||
1168, 1193, 1214, 1240, 1260, 1267, 1275, 1287, 1296, 1328, 1352, 1362,
|
1168, 1193, 1214, 1240, 1260, 1273, 1282, 1294, 1304, 1336, 1360, 1370,
|
||||||
1390, 1427, 1444, 1464, 1483, 1501, 1525, 1540, 1560, 1578, 1588, 1603,
|
1398, 1435, 1452, 1472, 1491, 1509, 1533, 1548, 1568, 1593, 1603, 1618,
|
||||||
1638, 1644, 1657, 1666, 1670, 1674, 1688, 1714, 1740, 1761, 1782, 1804,
|
1653, 1659, 1672, 1681, 1685, 1689, 1703, 1729, 1755, 1776, 1797, 1819,
|
||||||
1825, 1855, 1879, 1892, 1914, 1927, 1944, 1960, 1982, 2002, 2012, 2028,
|
1840, 1870, 1894, 1907, 1929, 1942, 1959, 1975, 1997, 2017, 2027, 2043,
|
||||||
2045, 2067, 2079, 2096, 2106, 2120, 2138, 2161, 2173, 2187, 2200, 2222,
|
2060, 2082, 2094, 2111, 2121, 2135, 2153, 2176, 2188, 2202, 2215, 2237,
|
||||||
2236, 2259, 2264, 2281, 2296, 2307, 2323, 2341, 2355, 2379, 2399, 2412,
|
2251, 2274, 2279, 2296, 2311, 2322, 2338, 2356, 2370, 2394, 2414, 2427,
|
||||||
2419, 2447, 2471, 2488, 2512, 2535, 2571, 2593, 2602, 2617, 2647, 2667,
|
2434, 2462, 2486, 2503, 2527, 2550, 2586, 2608, 2617, 2632, 2662, 2682,
|
||||||
2690, 2696, 2733, 2767, 2809, 2841, 2857, 2870, 2887, 2895, 2916, 2951,
|
2705, 2711, 2748, 2782, 2824, 2856, 2872, 2885, 2902, 2910, 2931, 2966,
|
||||||
2958, 2964, 2974, 2981, 2986, 2994, 3005, 3011, 3020, 3027, 3035, 3041,
|
2973, 2979, 2989, 2996, 3001, 3009, 3020, 3026, 3035, 3042, 3050, 3056,
|
||||||
3056, 3063, 3082, 3092, 3110, 3126, 3142, 3151, 3161, 3175, 3181, 3191,
|
3071, 3078, 3097, 3107, 3125, 3141, 3157, 3166, 3176, 3190, 3196, 3206,
|
||||||
3197, 3209, 3214, 3222, 3228, 3238, 3244, 3254, 3261, 3267, 3273, 3280,
|
3212, 3224, 3229, 3237, 3243, 3253, 3259, 3269, 3276, 3282, 3288, 3295,
|
||||||
3287, 3294, 3303, 3314, 3326, 3338, 3350, 3357, 3382, 3409, 3426, 3442,
|
3302, 3309, 3318, 3329, 3341, 3353, 3365, 3372, 3397, 3424, 3441, 3457,
|
||||||
3453, 3477, 3492, 3508, 3558, 3578, 3592, 3609, 3615, 3624, 3650, 3671,
|
3468, 3492, 3507, 3523, 3573, 3593, 3607, 3624, 3630, 3639, 3665, 3686,
|
||||||
3694, 3704, 3715, 3735, 3763, 3789, 3798, 3807, 3816, 3824, 3829, 3838,
|
3709, 3719, 3730, 3750, 3778, 3804, 3813, 3822, 3831, 3839, 3844, 3857,
|
||||||
3845, 3854, 3863, 3871, 3876, 3885, 3893, 3896, 3900, 3905, 3913, 3917,
|
3864, 3873, 3882, 3890, 3895, 3904, 3912, 3915, 3919, 3924, 3932, 3936,
|
||||||
3921, 3936, 3942, 3949, 3956, 3963, 3966, 3992, 4001, 4022, 4048, 4074,
|
3940, 3955, 3961, 3968, 3975, 3982, 3985, 4011, 4020, 4041, 4067, 4093,
|
||||||
4089, 4110, 4114, 4124, 4128, 4133, 4143, 4156, 4166, 4176, 4182, 4191,
|
4108, 4129, 4133, 4143, 4147, 4152, 4162, 4175, 4185, 4195, 4201, 4210,
|
||||||
4200, 4209, 4214, 4230, 4253, 4280, 4293, 4312, 4325, 4333, 4348, 4368,
|
4219, 4228, 4233, 4249, 4272, 4299, 4312, 4331, 4344, 4359, 4379, 4416,
|
||||||
4405, 4449, 4457, 4476, 4488, 4495, 4499, 4509, 4551, 4567, 4581, 4626,
|
4460, 4468, 4487, 4499, 4506, 4510, 4520, 4562, 4578, 4592, 4637, 4673,
|
||||||
4662, 4678, 4697, 4713, 4730, 4740, 4750, 4775, 4797, 4804, 4811, 4831,
|
4689, 4708, 4724, 4741, 4751, 4761, 4786, 4808, 4818, 4825, 4845, 4857,
|
||||||
4843, 4858, 4865, 4904, 4941, 4964, 4991, 5023, 5044, 5071, 5101, 5123,
|
4872, 4879, 4918, 4955, 4978, 5005, 5037, 5058, 5085, 5115, 5137, 5166,
|
||||||
5152, 5194, 5214, 5222, 5230, 5255, 5283, 5293, 5321, 5347, 5379, 5405,
|
5208, 5228, 5236, 5244, 5269, 5297, 5307, 5335, 5361, 5393, 5419, 5440,
|
||||||
5426, 5439, 5447, 5456, 5471, 5487, 5503, 5513, 5543, 5550, 5567, 5587,
|
5453, 5461, 5470, 5485, 5501, 5517, 5527, 5557, 5564, 5581, 5616, 5653,
|
||||||
5616, 5621, 5628, 5635, 5640, 5666, 5672, 5677, 5683, 5687, 5726, 5753,
|
5658, 5663, 5689, 5695, 5700, 5706, 5710, 5749, 5776, 5804, 5823, 5847,
|
||||||
5781, 5800, 5824, 5849, 5860, 5865, 5869, 5873, 5882, 5891, 5901, 5912,
|
5872, 5883, 5888, 5892, 5896, 5905, 5914, 5924, 5935, 5942, 5951, 5969,
|
||||||
5919, 5928, 5946,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_TR_DATA[] =
|
const char STRINGS_TR_DATA[] =
|
||||||
@@ -35242,7 +35175,6 @@ const char STRINGS_TR_DATA[] =
|
|||||||
"\x96"
|
"\x96"
|
||||||
"zel\0"
|
"zel\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Son Kitaplar\0"
|
"Son Kitaplar\0"
|
||||||
"Son okunan kitap yok\0"
|
"Son okunan kitap yok\0"
|
||||||
"Calibre kablosuz cihaz transferini kullan\0"
|
"Calibre kablosuz cihaz transferini kullan\0"
|
||||||
@@ -35469,8 +35401,6 @@ const char STRINGS_TR_DATA[] =
|
|||||||
"\x87"
|
"\x87"
|
||||||
"evirme (Dakikada Sayfa)\0"
|
"evirme (Dakikada Sayfa)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -35520,15 +35450,14 @@ const uint16_t OFFSETS_TR[] = {
|
|||||||
4044, 4051, 4058, 4066, 4070, 4077, 4089, 4094, 4101, 4109, 4115, 4121,
|
4044, 4051, 4058, 4066, 4070, 4077, 4089, 4094, 4101, 4109, 4115, 4121,
|
||||||
4128, 4141, 4145, 4150, 4158, 4167, 4173, 4201, 4210, 4240, 4263, 4288,
|
4128, 4141, 4145, 4150, 4158, 4167, 4173, 4201, 4210, 4240, 4263, 4288,
|
||||||
4307, 4340, 4346, 4351, 4358, 4364, 4372, 4383, 4401, 4411, 4420, 4424,
|
4307, 4340, 4346, 4351, 4358, 4364, 4372, 4383, 4401, 4411, 4420, 4424,
|
||||||
4440, 4447, 4452, 4473, 4509, 4535, 4551, 4565, 4578, 4586, 4599, 4620,
|
4440, 4447, 4452, 4473, 4509, 4535, 4551, 4565, 4578, 4591, 4612, 4654,
|
||||||
4662, 4700, 4705, 4732, 4740, 4746, 4754, 4766, 4801, 4813, 4829, 4873,
|
4692, 4697, 4724, 4732, 4738, 4746, 4758, 4793, 4805, 4821, 4865, 4902,
|
||||||
4910, 4925, 4942, 4956, 4971, 4980, 4996, 5030, 5054, 5058, 5065, 5092,
|
4917, 4934, 4948, 4963, 4972, 4988, 5022, 5046, 5050, 5057, 5084, 5094,
|
||||||
5102, 5114, 5122, 5159, 5195, 5224, 5254, 5282, 5310, 5337, 5367, 5392,
|
5106, 5114, 5151, 5187, 5216, 5246, 5274, 5302, 5329, 5359, 5384, 5414,
|
||||||
5422, 5459, 5478, 5484, 5491, 5514, 5540, 5555, 5578, 5602, 5628, 5650,
|
5451, 5470, 5476, 5483, 5506, 5532, 5547, 5570, 5594, 5620, 5642, 5663,
|
||||||
5671, 5699, 5708, 5715, 5730, 5745, 5764, 5774, 5796, 5809, 5832, 5858,
|
5691, 5700, 5707, 5722, 5737, 5756, 5766, 5788, 5801, 5824, 5850, 5885,
|
||||||
5893, 5898, 5905, 5912, 5917, 5943, 5949, 5954, 5960, 5964, 6003, 6030,
|
5890, 5895, 5921, 5927, 5932, 5938, 5942, 5981, 6008, 6036, 6055, 6079,
|
||||||
6058, 6077, 6101, 6126, 6137, 6142, 6146, 6150, 6159, 6168, 6178, 6189,
|
6104, 6115, 6120, 6124, 6128, 6137, 6146, 6156, 6167, 6174, 6183, 6201,
|
||||||
6196, 6205, 6223,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_KK_DATA[] =
|
const char STRINGS_KK_DATA[] =
|
||||||
@@ -41178,7 +41107,6 @@ const char STRINGS_KK_DATA[] =
|
|||||||
"\xBD"
|
"\xBD"
|
||||||
"\0"
|
"\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"\xD0"
|
"\xD0"
|
||||||
"\x96"
|
"\x96"
|
||||||
"\xD1"
|
"\xD1"
|
||||||
@@ -43289,8 +43217,6 @@ const char STRINGS_KK_DATA[] =
|
|||||||
"\x8B"
|
"\x8B"
|
||||||
")\0"
|
")\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -43340,15 +43266,14 @@ const uint16_t OFFSETS_KK[] = {
|
|||||||
6037, 6050, 6069, 6082, 6089, 6109, 6126, 6131, 6138, 6153, 6166, 6179,
|
6037, 6050, 6069, 6082, 6089, 6109, 6126, 6131, 6138, 6153, 6166, 6179,
|
||||||
6194, 6219, 6226, 6231, 6244, 6255, 6260, 6310, 6327, 6362, 6395, 6436,
|
6194, 6219, 6226, 6231, 6244, 6255, 6260, 6310, 6327, 6362, 6395, 6436,
|
||||||
6464, 6517, 6532, 6545, 6556, 6567, 6578, 6592, 6614, 6643, 6652, 6667,
|
6464, 6517, 6532, 6545, 6556, 6567, 6578, 6592, 6614, 6643, 6652, 6667,
|
||||||
6703, 6726, 6731, 6759, 6809, 6869, 6889, 6927, 6940, 6948, 6993, 7045,
|
6703, 6726, 6731, 6759, 6809, 6869, 6889, 6927, 6940, 6985, 7037, 7102,
|
||||||
7110, 7208, 7219, 7256, 7269, 7276, 7291, 7304, 7370, 7401, 7458, 7564,
|
7200, 7211, 7248, 7261, 7268, 7283, 7296, 7362, 7393, 7450, 7556, 7643,
|
||||||
7651, 7682, 7715, 7742, 7767, 7781, 7810, 7850, 7879, 7886, 7893, 7937,
|
7674, 7707, 7734, 7759, 7773, 7802, 7842, 7871, 7878, 7885, 7929, 7942,
|
||||||
7950, 7963, 7976, 8023, 8069, 8110, 8154, 8204, 8256, 8283, 8313, 8361,
|
7955, 7968, 8015, 8061, 8102, 8146, 8196, 8248, 8275, 8305, 8353, 8430,
|
||||||
8438, 8514, 8545, 8565, 8587, 8616, 8648, 8667, 8720, 8782, 8835, 8904,
|
8506, 8537, 8557, 8579, 8608, 8640, 8659, 8712, 8774, 8827, 8896, 8940,
|
||||||
8948, 8982, 8994, 9016, 9038, 9076, 9100, 9138, 9201, 9218, 9248, 9302,
|
8974, 8986, 9008, 9030, 9068, 9092, 9130, 9193, 9210, 9240, 9294, 9368,
|
||||||
9376, 9381, 9388, 9395, 9400, 9426, 9432, 9437, 9443, 9447, 9486, 9513,
|
9373, 9378, 9404, 9410, 9415, 9421, 9425, 9464, 9491, 9519, 9538, 9562,
|
||||||
9541, 9560, 9584, 9609, 9620, 9625, 9629, 9633, 9642, 9651, 9661, 9672,
|
9587, 9598, 9603, 9607, 9611, 9620, 9629, 9639, 9650, 9657, 9666, 9684,
|
||||||
9679, 9688, 9706,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char STRINGS_PT_DATA[] =
|
const char STRINGS_PT_DATA[] =
|
||||||
@@ -43864,7 +43789,6 @@ const char STRINGS_PT_DATA[] =
|
|||||||
"Navegador OPDS\0"
|
"Navegador OPDS\0"
|
||||||
"Capa + personalizado\0"
|
"Capa + personalizado\0"
|
||||||
"Page overlay\0"
|
"Page overlay\0"
|
||||||
"Recents\0"
|
|
||||||
"Livros recentes\0"
|
"Livros recentes\0"
|
||||||
"Sem livros recentes\0"
|
"Sem livros recentes\0"
|
||||||
"Usar transfer\xC3"
|
"Usar transfer\xC3"
|
||||||
@@ -44013,8 +43937,6 @@ const char STRINGS_PT_DATA[] =
|
|||||||
"Auto Turn Enabled: \0"
|
"Auto Turn Enabled: \0"
|
||||||
"Auto Turn (Pages Per Minute)\0"
|
"Auto Turn (Pages Per Minute)\0"
|
||||||
"Info\0"
|
"Info\0"
|
||||||
"Author\0"
|
|
||||||
"Series\0"
|
|
||||||
"Size\0"
|
"Size\0"
|
||||||
"Sleep Screen Info Overlay\0"
|
"Sleep Screen Info Overlay\0"
|
||||||
"White\0"
|
"White\0"
|
||||||
@@ -44064,15 +43986,14 @@ const uint16_t OFFSETS_PT[] = {
|
|||||||
4185, 4195, 4204, 4210, 4216, 4227, 4242, 4246, 4251, 4256, 4261, 4266,
|
4185, 4195, 4204, 4210, 4216, 4227, 4242, 4246, 4251, 4256, 4261, 4266,
|
||||||
4272, 4286, 4295, 4303, 4308, 4314, 4317, 4352, 4362, 4383, 4402, 4427,
|
4272, 4286, 4295, 4303, 4308, 4314, 4317, 4352, 4362, 4383, 4402, 4427,
|
||||||
4440, 4463, 4468, 4475, 4481, 4486, 4494, 4505, 4516, 4524, 4530, 4538,
|
4440, 4463, 4468, 4475, 4481, 4486, 4494, 4505, 4516, 4524, 4530, 4538,
|
||||||
4556, 4566, 4571, 4585, 4612, 4640, 4655, 4676, 4689, 4697, 4713, 4733,
|
4556, 4566, 4571, 4585, 4612, 4640, 4655, 4676, 4689, 4705, 4725, 4766,
|
||||||
4774, 4826, 4835, 4858, 4873, 4880, 4887, 4902, 4945, 4961, 4976, 5034,
|
4818, 4827, 4850, 4865, 4872, 4879, 4894, 4937, 4953, 4968, 5026, 5075,
|
||||||
5083, 5103, 5126, 5148, 5169, 5179, 5197, 5219, 5243, 5252, 5259, 5275,
|
5095, 5118, 5140, 5161, 5171, 5189, 5211, 5235, 5244, 5251, 5267, 5278,
|
||||||
5286, 5298, 5305, 5343, 5372, 5394, 5426, 5464, 5492, 5519, 5549, 5571,
|
5290, 5297, 5335, 5364, 5386, 5418, 5456, 5484, 5511, 5541, 5563, 5597,
|
||||||
5605, 5652, 5674, 5682, 5689, 5717, 5748, 5755, 5780, 5803, 5838, 5862,
|
5644, 5666, 5674, 5681, 5709, 5740, 5747, 5772, 5795, 5830, 5854, 5873,
|
||||||
5881, 5906, 5915, 5922, 5938, 5957, 5978, 5988, 6014, 6021, 6036, 6056,
|
5898, 5907, 5914, 5930, 5949, 5970, 5980, 6006, 6013, 6028, 6048, 6077,
|
||||||
6085, 6090, 6097, 6104, 6109, 6135, 6141, 6146, 6152, 6156, 6195, 6222,
|
6082, 6087, 6113, 6119, 6124, 6130, 6134, 6173, 6200, 6228, 6247, 6271,
|
||||||
6250, 6269, 6293, 6318, 6329, 6334, 6338, 6342, 6351, 6360, 6370, 6381,
|
6296, 6307, 6312, 6316, 6320, 6329, 6338, 6348, 6359, 6366, 6375, 6393,
|
||||||
6388, 6397, 6415,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace i18n_strings
|
} // namespace i18n_strings
|
||||||
|
|||||||
+12
-2
@@ -13,11 +13,14 @@
|
|||||||
bool Xtc::load() {
|
bool Xtc::load() {
|
||||||
LOG_DBG("XTC", "Loading XTC: %s", filepath.c_str());
|
LOG_DBG("XTC", "Loading XTC: %s", filepath.c_str());
|
||||||
|
|
||||||
|
// Ensure the per-book cache exists before the parser tries to create page_table.bin.
|
||||||
|
setupCacheDir();
|
||||||
|
|
||||||
// Initialize parser
|
// Initialize parser
|
||||||
parser.reset(new xtc::XtcParser());
|
parser.reset(new xtc::XtcParser());
|
||||||
|
|
||||||
// Open XTC file
|
// Open XTC file and initialize its cache-backed page table
|
||||||
xtc::XtcError err = parser->open(filepath.c_str());
|
xtc::XtcError err = parser->open(filepath.c_str(), cachePath.c_str());
|
||||||
if (err != xtc::XtcError::OK) {
|
if (err != xtc::XtcError::OK) {
|
||||||
LOG_ERR("XTC", "Failed to load: %s", xtc::errorToString(err));
|
LOG_ERR("XTC", "Failed to load: %s", xtc::errorToString(err));
|
||||||
parser.reset();
|
parser.reset();
|
||||||
@@ -619,3 +622,10 @@ xtc::XtcError Xtc::getLastError() const {
|
|||||||
}
|
}
|
||||||
return parser->getLastError();
|
return parser->getLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Xtc::prefetchPages(uint32_t pageIndex) const {
|
||||||
|
if (!loaded || !parser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parser->prefetchWindow(pageIndex);
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ class Xtc {
|
|||||||
*/
|
*/
|
||||||
void setupCacheDir() const;
|
void setupCacheDir() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preload window around specified page (for page turn optimization)
|
||||||
|
*/
|
||||||
|
void prefetchPages(uint32_t pageIndex) const;
|
||||||
|
|
||||||
// Path accessors
|
// Path accessors
|
||||||
const std::string& getCachePath() const { return cachePath; }
|
const std::string& getCachePath() const { return cachePath; }
|
||||||
const std::string& getPath() const { return filepath; }
|
const std::string& getPath() const { return filepath; }
|
||||||
|
|||||||
+507
-93
@@ -10,6 +10,7 @@
|
|||||||
#include <FsHelpers.h>
|
#include <FsHelpers.h>
|
||||||
#include <HalStorage.h>
|
#include <HalStorage.h>
|
||||||
#include <Logging.h>
|
#include <Logging.h>
|
||||||
|
#include <esp_heap_caps.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -18,6 +19,8 @@ namespace xtc {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr size_t MAX_CHAPTERS = 4096;
|
||||||
|
|
||||||
bool canSeekToOffset(const uint64_t offset) {
|
bool canSeekToOffset(const uint64_t offset) {
|
||||||
return offset <= static_cast<uint64_t>(std::numeric_limits<size_t>::max());
|
return offset <= static_cast<uint64_t>(std::numeric_limits<size_t>::max());
|
||||||
}
|
}
|
||||||
@@ -31,6 +34,26 @@ bool seekToOffset(FsFile& file, const uint64_t offset) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void XtcParser::safeDeserializeHeader(const uint8_t* buf, PageTableCacheHeader& header) {
|
||||||
|
memcpy(&header.magic, buf + 0, 4);
|
||||||
|
memcpy(&header.version, buf + 4, 4);
|
||||||
|
memcpy(&header.pageCount, buf + 8, 4);
|
||||||
|
memcpy(&header.originalHash, buf + 12, 4);
|
||||||
|
memcpy(&header.originalSize, buf + 16, 8);
|
||||||
|
memcpy(&header.entrySize, buf + 24, 4);
|
||||||
|
memcpy(&header.reserved, buf + 28, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtcParser::safeSerializeHeader(uint8_t* buf, const PageTableCacheHeader& header) {
|
||||||
|
memcpy(buf + 0, &header.magic, 4);
|
||||||
|
memcpy(buf + 4, &header.version, 4);
|
||||||
|
memcpy(buf + 8, &header.pageCount, 4);
|
||||||
|
memcpy(buf + 12, &header.originalHash, 4);
|
||||||
|
memcpy(buf + 16, &header.originalSize, 8);
|
||||||
|
memcpy(buf + 24, &header.entrySize, 4);
|
||||||
|
memcpy(buf + 28, &header.reserved, 4);
|
||||||
|
}
|
||||||
|
|
||||||
XtcParser::XtcParser()
|
XtcParser::XtcParser()
|
||||||
: m_isOpen(false),
|
: m_isOpen(false),
|
||||||
m_defaultWidth(DISPLAY_WIDTH),
|
m_defaultWidth(DISPLAY_WIDTH),
|
||||||
@@ -39,17 +62,28 @@ XtcParser::XtcParser()
|
|||||||
m_hasChapters(false),
|
m_hasChapters(false),
|
||||||
m_lastError(XtcError::OK) {
|
m_lastError(XtcError::OK) {
|
||||||
memset(&m_header, 0, sizeof(m_header));
|
memset(&m_header, 0, sizeof(m_header));
|
||||||
|
|
||||||
|
for (auto& entry : m_l1Cache) {
|
||||||
|
entry.pageIndex = 0xFFFFFFFF;
|
||||||
|
entry.lastAccess = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XtcParser::~XtcParser() { close(); }
|
XtcParser::~XtcParser() { close(); }
|
||||||
|
|
||||||
XtcError XtcParser::open(const char* filepath) {
|
XtcError XtcParser::open(const char* filepath, const char* cacheDir) {
|
||||||
// Close if already open
|
// Close any previous file state before reopening
|
||||||
if (m_isOpen) {
|
if (m_isOpen) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open file
|
m_originalPath = filepath;
|
||||||
|
m_cacheDir = cacheDir;
|
||||||
|
|
||||||
|
uint32_t fileHash = calculateFileHash(filepath);
|
||||||
|
m_cacheFilePath = std::string(cacheDir) + "/xtc_" + std::to_string(fileHash) + "/page_table.bin";
|
||||||
|
|
||||||
|
// Open the original XTC file just long enough to read metadata and validate the header.
|
||||||
if (!Storage.openFileForRead("XTC", filepath, m_file)) {
|
if (!Storage.openFileForRead("XTC", filepath, m_file)) {
|
||||||
m_lastError = XtcError::FILE_NOT_FOUND;
|
m_lastError = XtcError::FILE_NOT_FOUND;
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
@@ -63,57 +97,416 @@ XtcError XtcParser::open(const char* filepath) {
|
|||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read title & author if available
|
if (m_header.pageCount == 0) {
|
||||||
|
LOG_ERR("XTC", "File has no pages");
|
||||||
|
m_file.close();
|
||||||
|
m_lastError = XtcError::CORRUPTED_HEADER;
|
||||||
|
return m_lastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metadata strings are small, so keep them in memory even when the page table is moved to cache.
|
||||||
if (m_header.hasMetadata) {
|
if (m_header.hasMetadata) {
|
||||||
m_lastError = readTitle();
|
readTitle();
|
||||||
|
readAuthor();
|
||||||
|
m_title.shrink_to_fit();
|
||||||
|
m_author.shrink_to_fit();
|
||||||
|
LOG_INF("XTC", "Metadata strings: titleLen=%u cap=%u, authorLen=%u cap=%u",
|
||||||
|
static_cast<unsigned int>(m_title.size()), static_cast<unsigned int>(m_title.capacity()),
|
||||||
|
static_cast<unsigned int>(m_author.size()), static_cast<unsigned int>(m_author.capacity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defer chapter parsing until the reader actually needs the table of contents.
|
||||||
|
m_pageTableOffset = m_header.pageTableOffset;
|
||||||
|
m_hasChapters = (m_header.hasChapters == 1) && (m_header.chapterOffset != 0);
|
||||||
|
LOG_INF("XTC", "Chapter metadata deferred: available=%s", m_hasChapters ? "yes" : "no");
|
||||||
|
|
||||||
|
m_file.close();
|
||||||
|
|
||||||
|
// Build or reuse the on-disk page table cache before marking the parser open.
|
||||||
|
if (!isPageTableCacheValid()) {
|
||||||
|
LOG_INF("XTC", "Building page table cache for %u pages", m_header.pageCount);
|
||||||
|
m_lastError = buildPageTableCache();
|
||||||
if (m_lastError != XtcError::OK) {
|
if (m_lastError != XtcError::OK) {
|
||||||
LOG_DBG("XTC", "Failed to read title: %s", errorToString(m_lastError));
|
LOG_ERR("XTC", "Failed to build page table cache");
|
||||||
m_file.close();
|
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
m_lastError = readAuthor();
|
const size_t heapBefore = ESP.getMaxAllocHeap();
|
||||||
if (m_lastError != XtcError::OK) {
|
LOG_DBG("XTC", "Cache built, heap before defrag: free=%zu, maxAlloc=%zu", ESP.getFreeHeap(), heapBefore);
|
||||||
LOG_DBG("XTC", "Failed to read author: %s", errorToString(m_lastError));
|
|
||||||
m_file.close();
|
// Defragment heap: small delay allows heap coalescing after file handles are closed
|
||||||
return m_lastError;
|
// This typically improves MaxAlloc by 10-20KB, enabling 96KB page buffer for grayscale
|
||||||
|
LOG_DBG("XTC", "Defragmenting heap (waiting 50ms)...");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
|
||||||
|
const size_t heapAfter = ESP.getMaxAllocHeap();
|
||||||
|
const size_t heapGain = heapAfter > heapBefore ? (heapAfter - heapBefore) : 0;
|
||||||
|
if (heapGain > 0) {
|
||||||
|
LOG_INF("XTC", "Heap defragmented: +%zu bytes contiguous (now %zu)", heapGain, heapAfter);
|
||||||
|
} else {
|
||||||
|
LOG_DBG("XTC", "Heap after defrag: free=%zu, maxAlloc=%zu", ESP.getFreeHeap(), heapAfter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read page table
|
if (!openCacheFile()) {
|
||||||
m_lastError = readPageTable();
|
LOG_ERR("XTC", "Failed to open cache file");
|
||||||
if (m_lastError != XtcError::OK) {
|
m_lastError = XtcError::FILE_NOT_FOUND;
|
||||||
LOG_DBG("XTC", "Failed to read page table: %s", errorToString(m_lastError));
|
|
||||||
m_file.close();
|
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read chapters if present
|
// Prime the sliding L2 window with the first chunk of page metadata.
|
||||||
m_lastError = readChapters();
|
loadL2Window(0);
|
||||||
if (m_lastError != XtcError::OK) {
|
|
||||||
LOG_DBG("XTC", "Failed to read chapters: %s", errorToString(m_lastError));
|
LOG_DBG("XTC", "File opened, heap: free=%zu, maxAlloc=%zu", ESP.getFreeHeap(), ESP.getMaxAllocHeap());
|
||||||
m_file.close();
|
|
||||||
return m_lastError;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
LOG_DBG("XTC", "Opened file: %s (%u pages, %dx%d)", filepath, m_header.pageCount, m_defaultWidth, m_defaultHeight);
|
LOG_DBG("XTC", "Opened file: %s (%u pages, cache: %s)", filepath, m_header.pageCount, m_cacheFilePath.c_str());
|
||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XtcParser::close() {
|
void XtcParser::close() {
|
||||||
if (m_isOpen) {
|
closeCacheFile();
|
||||||
|
|
||||||
|
if (m_isOpen && m_file.isOpen()) {
|
||||||
m_file.close();
|
m_file.close();
|
||||||
m_isOpen = false;
|
|
||||||
}
|
}
|
||||||
m_pageTable.clear();
|
m_isOpen = false;
|
||||||
|
m_l2Valid = false;
|
||||||
|
m_l2WindowCount = 0;
|
||||||
|
m_chaptersLoaded = false;
|
||||||
|
|
||||||
|
for (auto& entry : m_l1Cache) {
|
||||||
|
entry.pageIndex = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
m_chapters.clear();
|
m_chapters.clear();
|
||||||
m_title.clear();
|
m_title.clear();
|
||||||
m_hasChapters = false;
|
m_author.clear();
|
||||||
memset(&m_header, 0, sizeof(m_header));
|
memset(&m_header, 0, sizeof(m_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XtcParser::ensureChaptersLoaded() {
|
||||||
|
if (m_chaptersLoaded || !m_hasChapters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter parsing allocates variable-length strings, so keep it lazy.
|
||||||
|
const XtcError err = readChapters();
|
||||||
|
if (err != XtcError::OK) {
|
||||||
|
LOG_ERR("XTC", "Failed to lazy-load chapters: %s", errorToString(err));
|
||||||
|
m_hasChapters = false;
|
||||||
|
m_chapters.clear();
|
||||||
|
m_chapters.shrink_to_fit();
|
||||||
|
}
|
||||||
|
m_chaptersLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtcParser::openCacheFile() {
|
||||||
|
if (m_cacheFile.isOpen()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Storage.openFileForRead("XTC", m_cacheFilePath.c_str(), m_cacheFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtcParser::closeCacheFile() {
|
||||||
|
if (m_cacheFile.isOpen()) {
|
||||||
|
m_cacheFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtcParser::getPageInfo(uint32_t pageIndex, PageInfo& info) {
|
||||||
|
if (pageIndex >= m_header.pageCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// L1 is the hot cache for the most recently used pages.
|
||||||
|
if (lookupL1(pageIndex, info)) {
|
||||||
|
LOG_DBG("XTC", "L1 hit: page %u", pageIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// L2 is the sliding window around the reader's current position.
|
||||||
|
if (lookupL2(pageIndex, info)) {
|
||||||
|
updateL1(pageIndex, info);
|
||||||
|
LOG_DBG("XTC", "L2 hit: page %u", pageIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to the SD-backed cache file, then refresh L2/L1.
|
||||||
|
LOG_DBG("XTC", "L3 load: page %u", pageIndex);
|
||||||
|
loadL2Window(pageIndex);
|
||||||
|
|
||||||
|
if (lookupL2(pageIndex, info)) {
|
||||||
|
updateL1(pageIndex, info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtcParser::prefetchWindow(uint32_t pageIndex) {
|
||||||
|
if (pageIndex >= m_header.pageCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid reloading the same window when the requested page is already covered.
|
||||||
|
if (m_l2Valid && pageIndex >= m_l2WindowStart && pageIndex < m_l2WindowStart + m_l2WindowCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadL2Window(pageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtcParser::lookupL1(uint32_t pageIndex, PageInfo& info) {
|
||||||
|
for (const auto& entry : m_l1Cache) {
|
||||||
|
if (entry.pageIndex == pageIndex) {
|
||||||
|
info = entry.info;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtcParser::updateL1(uint32_t pageIndex, const PageInfo& info) {
|
||||||
|
for (auto& entry : m_l1Cache) {
|
||||||
|
if (entry.pageIndex == pageIndex) {
|
||||||
|
entry.lastAccess = ++m_accessCounter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the least-recently-used entry, or fill the first empty slot.
|
||||||
|
uint32_t oldestAccess = m_accessCounter;
|
||||||
|
size_t oldestIndex = 0;
|
||||||
|
bool foundEmpty = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_l1Cache.size(); i++) {
|
||||||
|
if (m_l1Cache[i].pageIndex == 0xFFFFFFFF) {
|
||||||
|
oldestIndex = i;
|
||||||
|
foundEmpty = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m_l1Cache[i].lastAccess < oldestAccess) {
|
||||||
|
oldestAccess = m_l1Cache[i].lastAccess;
|
||||||
|
oldestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_l1Cache[oldestIndex].pageIndex = pageIndex;
|
||||||
|
m_l1Cache[oldestIndex].info = info;
|
||||||
|
m_l1Cache[oldestIndex].lastAccess = ++m_accessCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtcParser::lookupL2(uint32_t pageIndex, PageInfo& info) {
|
||||||
|
if (!m_l2Valid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageIndex >= m_l2WindowStart && pageIndex < m_l2WindowStart + m_l2WindowCount) {
|
||||||
|
size_t idx = pageIndex - m_l2WindowStart;
|
||||||
|
info = m_l2Window[idx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XtcParser::loadL2Window(uint32_t centerPage) {
|
||||||
|
// Center the sliding window around the requested page when possible.
|
||||||
|
uint32_t halfWindow = L2_WINDOW_SIZE / 2;
|
||||||
|
uint32_t windowStart = (centerPage > halfWindow) ? centerPage - halfWindow : 0;
|
||||||
|
uint32_t windowEnd = windowStart + L2_WINDOW_SIZE;
|
||||||
|
|
||||||
|
if (windowEnd > m_header.pageCount) {
|
||||||
|
windowEnd = m_header.pageCount;
|
||||||
|
windowStart = (windowEnd > L2_WINDOW_SIZE) ? windowEnd - L2_WINDOW_SIZE : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t windowSize = windowEnd - windowStart;
|
||||||
|
if (windowSize == 0) {
|
||||||
|
m_l2Valid = false;
|
||||||
|
m_l2WindowCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_cacheFile.isOpen() && !openCacheFile()) {
|
||||||
|
LOG_ERR("XTC", "Cache file not available");
|
||||||
|
m_l2Valid = false;
|
||||||
|
m_l2WindowCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t entryOffset = sizeof(PageTableCacheHeader) + windowStart * sizeof(PageInfo);
|
||||||
|
if (!m_cacheFile.seek(entryOffset)) {
|
||||||
|
LOG_ERR("XTC", "Failed to seek in page table cache");
|
||||||
|
m_l2Valid = false;
|
||||||
|
m_l2WindowCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t readCount = 0;
|
||||||
|
for (size_t i = 0; i < windowSize; i++) {
|
||||||
|
PageInfo info;
|
||||||
|
if (m_cacheFile.read(reinterpret_cast<uint8_t*>(&info), sizeof(PageInfo)) != sizeof(PageInfo)) {
|
||||||
|
LOG_ERR("XTC", "Failed to read page info %zu", windowStart + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_l2Window[i] = info;
|
||||||
|
readCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_l2WindowStart = windowStart;
|
||||||
|
m_l2WindowCount = readCount;
|
||||||
|
m_l2Valid = (readCount > 0);
|
||||||
|
|
||||||
|
LOG_DBG("XTC", "L2 window loaded: [%u, %u] (%zu pages)", windowStart, windowStart + readCount - 1, readCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XtcParser::isPageTableCacheValid() const {
|
||||||
|
if (!Storage.exists(m_cacheFilePath.c_str())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FsFile cacheFile;
|
||||||
|
if (!Storage.openFileForRead("XTC", m_cacheFilePath.c_str(), cacheFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t headerBuf[sizeof(PageTableCacheHeader)];
|
||||||
|
if (cacheFile.read(headerBuf, sizeof(headerBuf)) != sizeof(headerBuf)) {
|
||||||
|
cacheFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableCacheHeader header;
|
||||||
|
safeDeserializeHeader(headerBuf, header);
|
||||||
|
|
||||||
|
if (header.magic != PAGE_TABLE_CACHE_MAGIC || header.version != PAGE_TABLE_CACHE_VERSION) {
|
||||||
|
cacheFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cache must match both the page count and the original file size.
|
||||||
|
if (header.pageCount != m_header.pageCount) {
|
||||||
|
cacheFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t expectedSize = sizeof(PageTableCacheHeader) + header.pageCount * sizeof(PageInfo);
|
||||||
|
if (cacheFile.size() < expectedSize) {
|
||||||
|
cacheFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.originalSize > 0) {
|
||||||
|
FsFile originalFile;
|
||||||
|
if (Storage.openFileForRead("XTC", m_originalPath.c_str(), originalFile)) {
|
||||||
|
uint64_t currentSize = originalFile.size();
|
||||||
|
originalFile.close();
|
||||||
|
if (currentSize != header.originalSize) {
|
||||||
|
LOG_INF("XTC", "Cache invalidated: file size changed");
|
||||||
|
cacheFile.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheFile.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
XtcError XtcParser::buildPageTableCache() {
|
||||||
|
FsFile originalFile;
|
||||||
|
if (!Storage.openFileForRead("XTC", m_originalPath.c_str(), originalFile)) {
|
||||||
|
return XtcError::FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t lastSlash = m_cacheFilePath.find_last_of('/');
|
||||||
|
if (lastSlash != std::string::npos) {
|
||||||
|
std::string cacheDir = m_cacheFilePath.substr(0, lastSlash);
|
||||||
|
Storage.mkdir(cacheDir.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
FsFile cacheFile;
|
||||||
|
if (!Storage.openFileForWrite("XTC", m_cacheFilePath.c_str(), cacheFile)) {
|
||||||
|
originalFile.close();
|
||||||
|
return XtcError::WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist a compact PageInfo array so we do not need to hold the full table in RAM.
|
||||||
|
PageTableCacheHeader header;
|
||||||
|
header.magic = PAGE_TABLE_CACHE_MAGIC;
|
||||||
|
header.version = PAGE_TABLE_CACHE_VERSION;
|
||||||
|
header.pageCount = m_header.pageCount;
|
||||||
|
header.originalHash = calculateFileHash(m_originalPath.c_str());
|
||||||
|
header.originalSize = originalFile.size();
|
||||||
|
header.entrySize = sizeof(PageInfo);
|
||||||
|
header.reserved = 0;
|
||||||
|
|
||||||
|
uint8_t headerBuf[sizeof(PageTableCacheHeader)];
|
||||||
|
safeSerializeHeader(headerBuf, header);
|
||||||
|
if (cacheFile.write(headerBuf, sizeof(headerBuf)) != sizeof(headerBuf)) {
|
||||||
|
cacheFile.close();
|
||||||
|
originalFile.close();
|
||||||
|
return XtcError::WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seekToOffset(originalFile, m_pageTableOffset)) {
|
||||||
|
cacheFile.close();
|
||||||
|
originalFile.close();
|
||||||
|
return XtcError::READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the source page table entries into the cached PageInfo layout.
|
||||||
|
for (uint16_t i = 0; i < m_header.pageCount; i++) {
|
||||||
|
PageTableEntry entry;
|
||||||
|
if (originalFile.read(reinterpret_cast<uint8_t*>(&entry), sizeof(PageTableEntry)) != sizeof(PageTableEntry)) {
|
||||||
|
LOG_ERR("XTC", "Failed to read page table entry %u", i);
|
||||||
|
cacheFile.close();
|
||||||
|
originalFile.close();
|
||||||
|
return XtcError::READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageInfo info;
|
||||||
|
info.offset = entry.dataOffset;
|
||||||
|
info.size = entry.dataSize;
|
||||||
|
info.width = entry.width;
|
||||||
|
info.height = entry.height;
|
||||||
|
info.bitDepth = m_bitDepth;
|
||||||
|
info.padding = 0;
|
||||||
|
|
||||||
|
if (cacheFile.write(reinterpret_cast<const uint8_t*>(&info), sizeof(info)) != sizeof(info)) {
|
||||||
|
cacheFile.close();
|
||||||
|
originalFile.close();
|
||||||
|
return XtcError::WRITE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheFile.close();
|
||||||
|
originalFile.close();
|
||||||
|
|
||||||
|
LOG_INF("XTC", "Page table cache built: %u entries", m_header.pageCount);
|
||||||
|
return XtcError::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t XtcParser::calculateFileHash(const char* filepath) const {
|
||||||
|
uint32_t hash = 0;
|
||||||
|
size_t len = strlen(filepath);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
hash = hash * 31 + static_cast<uint8_t>(filepath[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FsFile file;
|
||||||
|
if (Storage.openFileForRead("XTC", filepath, file)) {
|
||||||
|
uint64_t size = file.size();
|
||||||
|
hash ^= static_cast<uint32_t>(size);
|
||||||
|
hash ^= static_cast<uint32_t>(size >> 32);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
XtcError XtcParser::readHeader() {
|
XtcError XtcParser::readHeader() {
|
||||||
// Read first 56 bytes of header
|
// Read the fixed-size XTC header first.
|
||||||
size_t bytesRead = m_file.read(reinterpret_cast<uint8_t*>(&m_header), sizeof(XtcHeader));
|
size_t bytesRead = m_file.read(reinterpret_cast<uint8_t*>(&m_header), sizeof(XtcHeader));
|
||||||
if (bytesRead != sizeof(XtcHeader)) {
|
if (bytesRead != sizeof(XtcHeader)) {
|
||||||
return XtcError::READ_ERROR;
|
return XtcError::READ_ERROR;
|
||||||
@@ -179,49 +572,17 @@ XtcError XtcParser::readAuthor() {
|
|||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
XtcError XtcParser::readPageTable() {
|
|
||||||
if (m_header.pageTableOffset == 0) {
|
|
||||||
LOG_DBG("XTC", "Page table offset is 0, cannot read");
|
|
||||||
return XtcError::CORRUPTED_HEADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek to page table
|
|
||||||
if (!seekToOffset(m_file, m_header.pageTableOffset)) {
|
|
||||||
LOG_DBG("XTC", "Failed to seek to page table at %llu", m_header.pageTableOffset);
|
|
||||||
return XtcError::READ_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pageTable.resize(m_header.pageCount);
|
|
||||||
|
|
||||||
// Read page table entries
|
|
||||||
for (uint16_t i = 0; i < m_header.pageCount; i++) {
|
|
||||||
PageTableEntry entry;
|
|
||||||
size_t bytesRead = m_file.read(reinterpret_cast<uint8_t*>(&entry), sizeof(PageTableEntry));
|
|
||||||
if (bytesRead != sizeof(PageTableEntry)) {
|
|
||||||
LOG_DBG("XTC", "Failed to read page table entry %u", i);
|
|
||||||
return XtcError::READ_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pageTable[i].offset = entry.dataOffset;
|
|
||||||
m_pageTable[i].size = entry.dataSize;
|
|
||||||
m_pageTable[i].width = entry.width;
|
|
||||||
m_pageTable[i].height = entry.height;
|
|
||||||
m_pageTable[i].bitDepth = m_bitDepth;
|
|
||||||
|
|
||||||
// Update default dimensions from first page
|
|
||||||
if (i == 0) {
|
|
||||||
m_defaultWidth = entry.width;
|
|
||||||
m_defaultHeight = entry.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DBG("XTC", "Read %u page table entries", m_header.pageCount);
|
|
||||||
return XtcError::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
XtcError XtcParser::readChapters() {
|
XtcError XtcParser::readChapters() {
|
||||||
m_hasChapters = false;
|
m_hasChapters = false;
|
||||||
m_chapters.clear();
|
m_chapters.clear();
|
||||||
|
m_chapters.shrink_to_fit();
|
||||||
|
|
||||||
|
// Reopen the original file on demand because open() closes it after cache initialization.
|
||||||
|
if (!m_file.isOpen()) {
|
||||||
|
if (!Storage.openFileForRead("XTC", m_originalPath.c_str(), m_file)) {
|
||||||
|
return XtcError::FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t hasChaptersFlag = 0;
|
uint8_t hasChaptersFlag = 0;
|
||||||
if (!m_file.seek(0x0B)) {
|
if (!m_file.seek(0x0B)) {
|
||||||
@@ -248,7 +609,13 @@ XtcError XtcParser::readChapters() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t fileSize = m_file.size();
|
const uint64_t fileSize = m_file.size();
|
||||||
if (chapterOffset < sizeof(XtcHeader) || chapterOffset >= fileSize || chapterOffset + 96 > fileSize) {
|
constexpr size_t chapterSize = 96;
|
||||||
|
|
||||||
|
if (chapterOffset < sizeof(XtcHeader) || chapterOffset >= fileSize) {
|
||||||
|
return XtcError::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileSize - chapterOffset < chapterSize) {
|
||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,18 +632,32 @@ XtcError XtcParser::readChapters() {
|
|||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t chapterSize = 96;
|
|
||||||
const uint64_t available = maxOffset - chapterOffset;
|
const uint64_t available = maxOffset - chapterOffset;
|
||||||
const size_t chapterCount = static_cast<size_t>(available / chapterSize);
|
const uint64_t chapterCount64 = available / chapterSize;
|
||||||
|
if (chapterCount64 == 0) {
|
||||||
|
return XtcError::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chapterCount64 > MAX_CHAPTERS || chapterCount64 > std::numeric_limits<size_t>::max()) {
|
||||||
|
LOG_ERR("XTC", "Chapter table too large: available=%llu chapterCount=%llu",
|
||||||
|
static_cast<unsigned long long>(available), static_cast<unsigned long long>(chapterCount64));
|
||||||
|
return XtcError::CORRUPTED_HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t chapterCount = static_cast<size_t>(chapterCount64);
|
||||||
if (chapterCount == 0) {
|
if (chapterCount == 0) {
|
||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t freeHeapBefore = ESP.getFreeHeap();
|
||||||
|
const size_t maxAllocBefore = ESP.getMaxAllocHeap();
|
||||||
|
|
||||||
if (!seekToOffset(m_file, chapterOffset)) {
|
if (!seekToOffset(m_file, chapterOffset)) {
|
||||||
return XtcError::READ_ERROR;
|
return XtcError::READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> chapterBuf(chapterSize);
|
std::vector<uint8_t> chapterBuf(chapterSize);
|
||||||
|
m_chapters.reserve(chapterCount);
|
||||||
for (size_t i = 0; i < chapterCount; i++) {
|
for (size_t i = 0; i < chapterCount; i++) {
|
||||||
if (m_file.read(chapterBuf.data(), chapterSize) != chapterSize) {
|
if (m_file.read(chapterBuf.data(), chapterSize) != chapterSize) {
|
||||||
return XtcError::READ_ERROR;
|
return XtcError::READ_ERROR;
|
||||||
@@ -320,17 +701,27 @@ XtcError XtcParser::readChapters() {
|
|||||||
m_chapters.push_back(std::move(chapter));
|
m_chapters.push_back(std::move(chapter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_chapters.shrink_to_fit();
|
||||||
m_hasChapters = !m_chapters.empty();
|
m_hasChapters = !m_chapters.empty();
|
||||||
LOG_DBG("XTC", "Chapters: %u", static_cast<unsigned int>(m_chapters.size()));
|
size_t chapterNameBytes = 0;
|
||||||
|
for (const auto& chapter : m_chapters) {
|
||||||
|
chapterNameBytes += chapter.name.capacity() + 1;
|
||||||
|
}
|
||||||
|
const size_t chapterVectorBytes = m_chapters.capacity() * sizeof(ChapterInfo);
|
||||||
|
const size_t totalChapterBytes = chapterVectorBytes + chapterNameBytes;
|
||||||
|
const size_t freeHeapAfter = ESP.getFreeHeap();
|
||||||
|
const size_t maxAllocAfter = ESP.getMaxAllocHeap();
|
||||||
|
const int heapDelta = static_cast<int>(freeHeapBefore) - static_cast<int>(freeHeapAfter);
|
||||||
|
const int maxAllocDelta = static_cast<int>(maxAllocBefore) - static_cast<int>(maxAllocAfter);
|
||||||
|
LOG_INF("XTC", "Chapter metadata: count=%u, vector~=%zu, names~=%zu, total~=%zu, heapDelta=%d, maxAllocDelta=%d",
|
||||||
|
static_cast<unsigned int>(m_chapters.size()), chapterVectorBytes, chapterNameBytes, totalChapterBytes,
|
||||||
|
heapDelta, maxAllocDelta);
|
||||||
return XtcError::OK;
|
return XtcError::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XtcParser::getPageInfo(uint32_t pageIndex, PageInfo& info) const {
|
const std::vector<ChapterInfo>& XtcParser::getChapters() {
|
||||||
if (pageIndex >= m_pageTable.size()) {
|
ensureChaptersLoaded();
|
||||||
return false;
|
return m_chapters;
|
||||||
}
|
|
||||||
info = m_pageTable[pageIndex];
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t XtcParser::loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSize) {
|
size_t XtcParser::loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSize) {
|
||||||
@@ -344,11 +735,23 @@ size_t XtcParser::loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSiz
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PageInfo& page = m_pageTable[pageIndex];
|
// Resolve the page location through the cache hierarchy before touching the data file.
|
||||||
|
PageInfo info;
|
||||||
|
if (!getPageInfo(pageIndex, info)) {
|
||||||
|
m_lastError = XtcError::READ_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Seek to page data
|
// Reopen the source file lazily because normal parser open() does not keep it pinned.
|
||||||
if (!seekToOffset(m_file, page.offset)) {
|
if (!m_file.isOpen()) {
|
||||||
LOG_DBG("XTC", "Failed to seek to page %u at offset %llu", pageIndex, static_cast<unsigned long long>(page.offset));
|
if (!Storage.openFileForRead("XTC", m_originalPath.c_str(), m_file)) {
|
||||||
|
m_lastError = XtcError::FILE_NOT_FOUND;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seekToOffset(m_file, info.offset)) {
|
||||||
|
LOG_DBG("XTC", "Failed to seek to page %u at offset %llu", pageIndex, static_cast<unsigned long long>(info.offset));
|
||||||
m_lastError = XtcError::READ_ERROR;
|
m_lastError = XtcError::READ_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -382,14 +785,14 @@ size_t XtcParser::loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSiz
|
|||||||
bitmapSize = ((pageHeader.width + 7) / 8) * pageHeader.height;
|
bitmapSize = ((pageHeader.width + 7) / 8) * pageHeader.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check buffer size
|
// The caller owns the buffer, so fail early if it is too small.
|
||||||
if (bufferSize < bitmapSize) {
|
if (bufferSize < bitmapSize) {
|
||||||
LOG_DBG("XTC", "Buffer too small: need %u, have %u", bitmapSize, bufferSize);
|
LOG_DBG("XTC", "Buffer too small: need %u, have %u", bitmapSize, bufferSize);
|
||||||
m_lastError = XtcError::MEMORY_ERROR;
|
m_lastError = XtcError::MEMORY_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read bitmap data
|
// Read the bitmap payload into the caller-provided buffer.
|
||||||
size_t bytesRead = m_file.read(buffer, bitmapSize);
|
size_t bytesRead = m_file.read(buffer, bitmapSize);
|
||||||
if (bytesRead != bitmapSize) {
|
if (bytesRead != bitmapSize) {
|
||||||
LOG_DBG("XTC", "Page read error: expected %u, got %u", bitmapSize, bytesRead);
|
LOG_DBG("XTC", "Page read error: expected %u, got %u", bitmapSize, bytesRead);
|
||||||
@@ -412,15 +815,25 @@ XtcError XtcParser::loadPageStreaming(uint32_t pageIndex,
|
|||||||
return XtcError::PAGE_OUT_OF_RANGE;
|
return XtcError::PAGE_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PageInfo& page = m_pageTable[pageIndex];
|
// Streaming uses the same cache lookup path but reads the payload in chunks.
|
||||||
|
PageInfo info;
|
||||||
// Seek to page data
|
if (!getPageInfo(pageIndex, info)) {
|
||||||
if (!seekToOffset(m_file, page.offset)) {
|
|
||||||
LOG_DBG("XTC", "Failed to seek to page %u at offset %llu", pageIndex, static_cast<unsigned long long>(page.offset));
|
|
||||||
return XtcError::READ_ERROR;
|
return XtcError::READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and skip page header (XTG for 1-bit, XTH for 2-bit)
|
// Reopen the source file on demand for streaming reads as well.
|
||||||
|
if (!m_file.isOpen()) {
|
||||||
|
if (!Storage.openFileForRead("XTC", m_originalPath.c_str(), m_file)) {
|
||||||
|
return XtcError::FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seekToOffset(m_file, info.offset)) {
|
||||||
|
LOG_DBG("XTC", "Failed to seek to page %u at offset %llu", pageIndex, static_cast<unsigned long long>(info.offset));
|
||||||
|
return XtcError::READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and validate the page header before yielding any bitmap bytes.
|
||||||
XtgPageHeader pageHeader;
|
XtgPageHeader pageHeader;
|
||||||
size_t headerRead = m_file.read(reinterpret_cast<uint8_t*>(&pageHeader), sizeof(XtgPageHeader));
|
size_t headerRead = m_file.read(reinterpret_cast<uint8_t*>(&pageHeader), sizeof(XtgPageHeader));
|
||||||
const uint32_t expectedMagic = (m_bitDepth == 2) ? XTH_MAGIC : XTG_MAGIC;
|
const uint32_t expectedMagic = (m_bitDepth == 2) ? XTH_MAGIC : XTG_MAGIC;
|
||||||
@@ -431,6 +844,7 @@ XtcError XtcParser::loadPageStreaming(uint32_t pageIndex,
|
|||||||
// Calculate bitmap size based on bit depth
|
// Calculate bitmap size based on bit depth
|
||||||
// XTG (1-bit): Row-major, ((width+7)/8) * height bytes
|
// XTG (1-bit): Row-major, ((width+7)/8) * height bytes
|
||||||
// XTH (2-bit): Two bit planes, ((width * height + 7) / 8) * 2 bytes
|
// XTH (2-bit): Two bit planes, ((width * height + 7) / 8) * 2 bytes
|
||||||
|
// Match the bitmap sizing rules used by the non-streaming path.
|
||||||
size_t bitmapSize;
|
size_t bitmapSize;
|
||||||
if (m_bitDepth == 2) {
|
if (m_bitDepth == 2) {
|
||||||
bitmapSize = ((static_cast<size_t>(pageHeader.width) * pageHeader.height + 7) / 8) * 2;
|
bitmapSize = ((static_cast<size_t>(pageHeader.width) * pageHeader.height + 7) / 8) * 2;
|
||||||
@@ -438,7 +852,7 @@ XtcError XtcParser::loadPageStreaming(uint32_t pageIndex,
|
|||||||
bitmapSize = ((pageHeader.width + 7) / 8) * pageHeader.height;
|
bitmapSize = ((pageHeader.width + 7) / 8) * pageHeader.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read in chunks
|
// Feed the bitmap to the callback in bounded chunks to keep peak memory low.
|
||||||
std::vector<uint8_t> chunk(chunkSize);
|
std::vector<uint8_t> chunk(chunkSize);
|
||||||
size_t totalRead = 0;
|
size_t totalRead = 0;
|
||||||
|
|
||||||
|
|||||||
+52
-26
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <HalStorage.h>
|
#include <HalStorage.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -30,7 +32,7 @@ class XtcParser {
|
|||||||
~XtcParser();
|
~XtcParser();
|
||||||
|
|
||||||
// File open/close
|
// File open/close
|
||||||
XtcError open(const char* filepath);
|
XtcError open(const char* filepath, const char* cacheDir);
|
||||||
void close();
|
void close();
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
|
|
||||||
@@ -41,28 +43,14 @@ class XtcParser {
|
|||||||
uint16_t getHeight() const { return m_defaultHeight; }
|
uint16_t getHeight() const { return m_defaultHeight; }
|
||||||
uint8_t getBitDepth() const { return m_bitDepth; } // 1 = XTC/XTG, 2 = XTCH/XTH
|
uint8_t getBitDepth() const { return m_bitDepth; } // 1 = XTC/XTG, 2 = XTCH/XTH
|
||||||
|
|
||||||
// Page information
|
// Page information - three-tier cache interface
|
||||||
bool getPageInfo(uint32_t pageIndex, PageInfo& info) const;
|
bool getPageInfo(uint32_t pageIndex, PageInfo& info);
|
||||||
|
|
||||||
/**
|
// Preload window around specified page (optimize sequential page turns)
|
||||||
* Load page bitmap (raw 1-bit data, skipping XTG header)
|
void prefetchWindow(uint32_t pageIndex);
|
||||||
*
|
|
||||||
* @param pageIndex Page index (0-based)
|
// Load page bitmap (unchanged)
|
||||||
* @param buffer Output buffer (caller allocated)
|
|
||||||
* @param bufferSize Buffer size
|
|
||||||
* @return Number of bytes read on success, 0 on failure
|
|
||||||
*/
|
|
||||||
size_t loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSize);
|
size_t loadPage(uint32_t pageIndex, uint8_t* buffer, size_t bufferSize);
|
||||||
|
|
||||||
/**
|
|
||||||
* Streaming page load
|
|
||||||
* Memory-efficient method that reads page data in chunks.
|
|
||||||
*
|
|
||||||
* @param pageIndex Page index
|
|
||||||
* @param callback Callback function to receive data chunks
|
|
||||||
* @param chunkSize Chunk size (default: 1024 bytes)
|
|
||||||
* @return Error code
|
|
||||||
*/
|
|
||||||
XtcError loadPageStreaming(uint32_t pageIndex,
|
XtcError loadPageStreaming(uint32_t pageIndex,
|
||||||
std::function<void(const uint8_t* data, size_t size, size_t offset)> callback,
|
std::function<void(const uint8_t* data, size_t size, size_t offset)> callback,
|
||||||
size_t chunkSize = 1024);
|
size_t chunkSize = 1024);
|
||||||
@@ -72,7 +60,7 @@ class XtcParser {
|
|||||||
std::string getAuthor() const { return m_author; }
|
std::string getAuthor() const { return m_author; }
|
||||||
|
|
||||||
bool hasChapters() const { return m_hasChapters; }
|
bool hasChapters() const { return m_hasChapters; }
|
||||||
const std::vector<ChapterInfo>& getChapters() const { return m_chapters; }
|
const std::vector<ChapterInfo>& getChapters();
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
static bool isValidXtcFile(const char* filepath);
|
static bool isValidXtcFile(const char* filepath);
|
||||||
@@ -82,24 +70,62 @@ class XtcParser {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FsFile m_file;
|
FsFile m_file;
|
||||||
|
FsFile m_cacheFile;
|
||||||
bool m_isOpen;
|
bool m_isOpen;
|
||||||
XtcHeader m_header;
|
XtcHeader m_header;
|
||||||
std::vector<PageInfo> m_pageTable;
|
std::string m_cacheDir;
|
||||||
std::vector<ChapterInfo> m_chapters;
|
std::string m_cacheFilePath;
|
||||||
|
std::string m_originalPath;
|
||||||
std::string m_title;
|
std::string m_title;
|
||||||
std::string m_author;
|
std::string m_author;
|
||||||
uint16_t m_defaultWidth;
|
uint16_t m_defaultWidth;
|
||||||
uint16_t m_defaultHeight;
|
uint16_t m_defaultHeight;
|
||||||
uint8_t m_bitDepth; // 1 = XTC/XTG (1-bit), 2 = XTCH/XTH (2-bit)
|
uint8_t m_bitDepth;
|
||||||
bool m_hasChapters;
|
bool m_hasChapters;
|
||||||
|
bool m_chaptersLoaded = false;
|
||||||
XtcError m_lastError;
|
XtcError m_lastError;
|
||||||
|
uint32_t m_accessCounter = 0;
|
||||||
|
|
||||||
|
// L1: Hot cache (fixed 4 entries)
|
||||||
|
std::array<L1CacheEntry, L1_CACHE_SIZE> m_l1Cache;
|
||||||
|
|
||||||
|
// L2: Sliding window (fixed size array)
|
||||||
|
std::array<PageInfo, L2_WINDOW_SIZE> m_l2Window;
|
||||||
|
uint32_t m_l2WindowStart = 0;
|
||||||
|
size_t m_l2WindowCount = 0;
|
||||||
|
bool m_l2Valid = false;
|
||||||
|
|
||||||
|
// Chapters (usually few, keep in memory)
|
||||||
|
std::vector<ChapterInfo> m_chapters;
|
||||||
|
|
||||||
|
// Original Page Table offset (for rebuilding cache)
|
||||||
|
uint64_t m_pageTableOffset = 0;
|
||||||
|
|
||||||
// Internal helper functions
|
// Internal helper functions
|
||||||
XtcError readHeader();
|
XtcError readHeader();
|
||||||
XtcError readPageTable();
|
|
||||||
XtcError readTitle();
|
XtcError readTitle();
|
||||||
XtcError readAuthor();
|
XtcError readAuthor();
|
||||||
XtcError readChapters();
|
XtcError readChapters();
|
||||||
|
void ensureChaptersLoaded();
|
||||||
|
|
||||||
|
// L3 cache management
|
||||||
|
bool isPageTableCacheValid() const;
|
||||||
|
XtcError buildPageTableCache();
|
||||||
|
bool openCacheFile();
|
||||||
|
void closeCacheFile();
|
||||||
|
|
||||||
|
// L1/L2 cache operations
|
||||||
|
bool lookupL1(uint32_t pageIndex, PageInfo& info);
|
||||||
|
void updateL1(uint32_t pageIndex, const PageInfo& info);
|
||||||
|
bool lookupL2(uint32_t pageIndex, PageInfo& info);
|
||||||
|
void loadL2Window(uint32_t centerPage);
|
||||||
|
|
||||||
|
// Safe deserialization (alignment-safe for ESP32-C3)
|
||||||
|
static void safeDeserializeHeader(const uint8_t* buf, PageTableCacheHeader& header);
|
||||||
|
static void safeSerializeHeader(uint8_t* buf, const PageTableCacheHeader& header);
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
uint32_t calculateFileHash(const char* filepath) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xtc
|
} // namespace xtc
|
||||||
|
|||||||
@@ -102,6 +102,33 @@ struct ChapterInfo {
|
|||||||
uint16_t endPage;
|
uint16_t endPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cache configuration
|
||||||
|
constexpr size_t L1_CACHE_SIZE = 4; // L1 cache entries
|
||||||
|
constexpr size_t L2_WINDOW_SIZE = 100; // L2 window size (reduced for 2-bit memory)
|
||||||
|
constexpr uint32_t PAGE_TABLE_CACHE_VERSION = 1; // Cache file version
|
||||||
|
|
||||||
|
// Cache magic number
|
||||||
|
constexpr uint32_t PAGE_TABLE_CACHE_MAGIC = 0x50435458; // "XTCP"
|
||||||
|
|
||||||
|
// Cache file header - NOTE: Do NOT read directly from file buffer!
|
||||||
|
// Use safeDeserializeHeader() function for alignment-safe access.
|
||||||
|
struct PageTableCacheHeader {
|
||||||
|
uint32_t magic; // 'XTCP' = 0x50435458
|
||||||
|
uint32_t version; // Cache version
|
||||||
|
uint32_t pageCount; // Total pages
|
||||||
|
uint32_t originalHash; // Original file hash (for validation)
|
||||||
|
uint64_t originalSize; // Original file size (for validation)
|
||||||
|
uint32_t entrySize; // PageInfo size (16)
|
||||||
|
uint32_t reserved; // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// L1 cache entry
|
||||||
|
struct L1CacheEntry {
|
||||||
|
uint32_t pageIndex = 0xFFFFFFFF; // 0xFFFFFFFF = invalid
|
||||||
|
PageInfo info{};
|
||||||
|
uint32_t lastAccess = 0; // Timestamp for LRU
|
||||||
|
};
|
||||||
|
|
||||||
// Error codes
|
// Error codes
|
||||||
enum class XtcError {
|
enum class XtcError {
|
||||||
OK = 0,
|
OK = 0,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <FsHelpers.h>
|
#include <FsHelpers.h>
|
||||||
#include <HalStorage.h>
|
#include <HalStorage.h>
|
||||||
|
#include <I18n.h>
|
||||||
|
|
||||||
#include "CrossPointSettings.h"
|
#include "CrossPointSettings.h"
|
||||||
#include "Epub.h"
|
#include "Epub.h"
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#include "XtcReaderActivity.h"
|
#include "XtcReaderActivity.h"
|
||||||
#include "activities/util/BmpViewerActivity.h"
|
#include "activities/util/BmpViewerActivity.h"
|
||||||
#include "activities/util/FullScreenMessageActivity.h"
|
#include "activities/util/FullScreenMessageActivity.h"
|
||||||
|
#include "components/UITheme.h"
|
||||||
|
#include "fontIds.h"
|
||||||
|
|
||||||
std::string ReaderActivity::extractFolderPath(const std::string& filePath) {
|
std::string ReaderActivity::extractFolderPath(const std::string& filePath) {
|
||||||
const auto lastSlash = filePath.find_last_of('/');
|
const auto lastSlash = filePath.find_last_of('/');
|
||||||
@@ -116,6 +119,10 @@ void ReaderActivity::onEnter() {
|
|||||||
if (isBmpFile(initialBookPath)) {
|
if (isBmpFile(initialBookPath)) {
|
||||||
onGoToBmpViewer(initialBookPath);
|
onGoToBmpViewer(initialBookPath);
|
||||||
} else if (isXtcFile(initialBookPath)) {
|
} else if (isXtcFile(initialBookPath)) {
|
||||||
|
renderer.clearScreen();
|
||||||
|
renderer.drawCenteredText(UI_12_FONT_ID, 300, tr(STR_LOADING), true, EpdFontFamily::BOLD);
|
||||||
|
renderer.displayBuffer();
|
||||||
|
|
||||||
auto xtc = loadXtc(initialBookPath);
|
auto xtc = loadXtc(initialBookPath);
|
||||||
if (!xtc) {
|
if (!xtc) {
|
||||||
onGoBack();
|
onGoBack();
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ void XtcReaderActivity::onEnter() {
|
|||||||
APP_STATE.saveToFile();
|
APP_STATE.saveToFile();
|
||||||
RECENT_BOOKS.addBook(xtc->getPath(), xtc->getTitle(), xtc->getAuthor(), "", xtc->getThumbBmpPath());
|
RECENT_BOOKS.addBook(xtc->getPath(), xtc->getTitle(), xtc->getAuthor(), "", xtc->getThumbBmpPath());
|
||||||
|
|
||||||
|
xtc->prefetchPages(currentPage);
|
||||||
|
|
||||||
// Trigger first update
|
// Trigger first update
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
@@ -63,6 +65,7 @@ void XtcReaderActivity::loop() {
|
|||||||
[this](const ActivityResult& result) {
|
[this](const ActivityResult& result) {
|
||||||
if (!result.isCancelled) {
|
if (!result.isCancelled) {
|
||||||
currentPage = std::get<PageResult>(result.data).page;
|
currentPage = std::get<PageResult>(result.data).page;
|
||||||
|
xtc->prefetchPages(currentPage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -118,12 +121,14 @@ void XtcReaderActivity::loop() {
|
|||||||
} else {
|
} else {
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
}
|
}
|
||||||
|
xtc->prefetchPages(currentPage);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
} else if (nextTriggered) {
|
} else if (nextTriggered) {
|
||||||
currentPage += skipAmount;
|
currentPage += skipAmount;
|
||||||
if (currentPage >= xtc->getPageCount()) {
|
if (currentPage >= xtc->getPageCount()) {
|
||||||
currentPage = xtc->getPageCount(); // Allow showing "End of book"
|
currentPage = xtc->getPageCount(); // Allow showing "End of book"
|
||||||
}
|
}
|
||||||
|
xtc->prefetchPages(currentPage);
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user