language.c 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //language.c
  2. #include "language.h"
  3. #include <inttypes.h>
  4. #include <avr/pgmspace.h>
  5. #include "bootapp.h"
  6. // Currectly active language selection.
  7. unsigned char lang_selected = 0;
  8. #if (LANG_MODE == 0) //primary language only
  9. #else //(LANG_MODE == 0)
  10. //reserved xx kbytes for secondary language table
  11. const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG";
  12. #endif //(LANG_MODE == 0)
  13. //lang_table_t structure - 16byte header
  14. typedef struct
  15. {
  16. struct
  17. {
  18. uint32_t magic;
  19. uint16_t size;
  20. uint16_t count;
  21. uint16_t checksum;
  22. uint16_t reserved0;
  23. uint32_t reserved1;
  24. } header;
  25. uint16_t table[];
  26. } lang_table_t;
  27. //lang_table pointer
  28. lang_table_t* lang_table = 0;
  29. const char* lang_get_translation(const char* s)
  30. {
  31. if (lang_selected == 0) return s + 2; //primary language selected
  32. if (lang_table == 0) return s + 2; //sec. lang table not found
  33. uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id
  34. if (ui == 0xffff) return s + 2; //translation not found
  35. ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset
  36. if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0)
  37. return s + 2;//not translated string
  38. return (const char*)((char*)lang_table + ui); //return calculated pointer
  39. }
  40. const char* lang_get_sec_lang_str(const char* s)
  41. {
  42. uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space
  43. ui += 0x00ff; //add 1 page
  44. ui &= 0xff00; //align to page
  45. lang_table_t* _lang_table = ui; //table pointer
  46. ui = pgm_read_word(((uint16_t*)s)); //read string id
  47. if (ui == 0xffff) return s + 2; //translation not found
  48. ui = pgm_read_word(((uint16_t*)(((char*)_lang_table + 16 + ui*2)))); //read relative offset
  49. return (const char*)((char*)_lang_table + ui); //return calculated pointer
  50. }
  51. const char* lang_select(unsigned char lang)
  52. {
  53. #if (LANG_MODE == 0) //primary language only
  54. return 0;
  55. #else //(LANG_MODE == 0)
  56. if (lang == 0) //primary language
  57. {
  58. lang_table = 0;
  59. lang_selected = 0;
  60. return;
  61. }
  62. uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space
  63. ui += 0x00ff; //add 1 page
  64. ui &= 0xff00; //align to page
  65. lang_table = ui; //set table pointer
  66. ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16)))); //read relative offset of first string (language name)
  67. return (const char*)((char*)lang_table + ui); //return calculated pointer
  68. #endif //(LANG_MODE == 0)
  69. }
  70. unsigned char lang_get_count()
  71. {
  72. uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space
  73. ui += 0x00ff; //add 1 page
  74. ui &= 0xff00; //align to page
  75. lang_table_t* _lang_table = ui; //table pointer
  76. if (pgm_read_dword(((uint32_t*)(_lang_table + 0))) == 0x4bb45aa5) return 2;
  77. return 1;
  78. }
  79. const char* lang_get_name(unsigned char lang)
  80. {
  81. if (lang == 0) return MSG_LANGUAGE_NAME + 2;
  82. return lang_get_sec_lang_str(MSG_LANGUAGE_NAME);
  83. }
  84. const char MSG_LANGUAGE_NAME[] PROGMEM_I1 = ISTR("English"); ////c=0 r=0