From 24ebbd942c0cc2557b43fb54e058d967cc28f3b3 Mon Sep 17 00:00:00 2001
From: Dmitry Mikhirev
Date: Wed, 29 Aug 2012 01:26:25 +0400
Subject: fix UTF-8 strings conversion
---
brainuino.ino | 58 +++++++++++----------
font.h | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
font_en.h | 0
font_ru-en.h | 160 ----------------------------------------------------------
lcdprint.cpp | 16 +++---
lcdprint.h | 2 +-
utf8.cpp | 41 ++++++++-------
utf8.h | 3 +-
8 files changed, 220 insertions(+), 220 deletions(-)
create mode 100644 font.h
delete mode 100644 font_en.h
delete mode 100644 font_ru-en.h
diff --git a/brainuino.ino b/brainuino.ino
index 7fb0233..557b023 100644
--- a/brainuino.ino
+++ b/brainuino.ino
@@ -1,7 +1,7 @@
/*
Brainuino Aleph
- Copyright (C) 2011 Dmitry Mikhirev
+ Copyright (C) 2011-2012 Dmitry Mikhirev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,10 +17,11 @@
along with this program. If not, see .
*/
+#include
#include
// undefine the following if your LCD does not support Russian font
-//#define RUSSIAN
+#define RUSSIAN
#include "pinout.h"
#include "game.h"
@@ -51,12 +52,10 @@ void loop()
timer = timer1;
printGameType();
-/*
// ensure that stop button is released
while (digitalRead(CONTROL2) == LOW) {
delay(20);
}
-*/
ask();
}
@@ -69,7 +68,7 @@ void ask()
digitalWrite(REDLAMP, LOW);
#ifdef RUSSIAN
- printState(convert("Задаётся вопрос "));
+ printState("Задаётся вопрос ");
#else
printState("Asking question ");
#endif
@@ -131,7 +130,7 @@ void discuss()
printGameType();
#ifdef RUSSIAN
- printState(convert("Отсчёт: "));
+ printState("Отсчёт: ");
#else
printState("Count: ");
#endif
@@ -183,7 +182,7 @@ void answer(uint8_t num) {
printPlayer(num);
#ifdef RUSSIAN
- printState(convert("Ответ "));
+ printState("Ответ ");
#else
printState("Answer ");
#endif
@@ -224,7 +223,7 @@ void falseStart(uint8_t num) {
tone(SPEAKER, 1784, 1000);
digitalWrite(REDLAMP, HIGH);
#ifdef RUSSIAN
- printState(convert(" Фальстарт "));
+ printState(" Фальстарт ");
#else
printState(" False start ");
#endif
@@ -244,12 +243,12 @@ void refresh() {
}
-void printState(String state) {
+void printState(char *state) {
// displaying string in the beginning of LCD second row
lcd.setCursor(0, 1);
- lcd.print(state);
+ uprint(state, &lcd);
}
@@ -257,11 +256,11 @@ void printTime() {
// displaying time passed after starting timer
- String timestr;
+ char timestr[33];
- timestr = String(time/1000) + '.' + String((time%1000)/100);
+ sprintf(timestr, "%.1f", float(time)/1000;
lcd.setCursor(8, 1);
- lcd.print(timestr);
+ uprint(timestr, &lcd);
}
@@ -270,24 +269,24 @@ void printPreciseTime() {
// displaying time passed after starting timer
// or that it was not started yet
- String timestr;
+ char timestr[33];
// if timer was started
if (startTime > 0) {
time = millis()-startTime;
- timestr = String(time/1000) + '.' + String(time%1000);
+ sprintf(timestr, "%.3f", float(time)/1000);
}
// if it was not
else
#ifdef RUSSIAN
- timestr = convert("досрочно");
+ sprintf(timestr, "досрочно");
#else
- timestr = "prematur";
+ sprintf(timestr, "prematur");
#endif
lcd.setCursor(8, 1);
- lcd.print(timestr);
+ uprint(timestr, &lcd);
}
@@ -345,27 +344,27 @@ void printGameType() {
case BRAIN:
#ifdef RUSSIAN
- lcd.print(convert(" Брейн-ринг "));
+ uprint(" Брейн-ринг ", &lcd);
#else
- lcd.print(" Brain-ring ");
+ uprint(" Brain-ring ", &lcd);
#endif
break;
case SI:
#ifdef RUSSIAN
- lcd.print(convert(" Своя игра "));
+ uprint(" Своя игра ", &lcd);
#else
- lcd.print(" Jeopardy ");
+ uprint(" Jeopardy ", &lcd);
#endif
break;
case CHGK:
#ifdef RUSSIAN
- lcd.print(convert("Что? Где? Когда?"));
+ uprint("Что? Где? Когда?", &lcd);
#else
- lcd.print("What?Where?When?");
+ uprint("What?Where?When?", &lcd);
#endif
break;
@@ -377,26 +376,29 @@ void printPlayer(uint8_t num) {
// displaying number of player or team
+ char printstring[65];
+
lcd.setCursor(0, 0);
switch (gameType) {
case BRAIN:
#ifdef RUSSIAN
- lcd.print(convert("Команда ") + String(int(num)) + " ");
+ sprintf(printstring, "Команда %u ", num);
#else
- lcd.print("Team " + String(int(num)) + " ");
+ sprintf(printstring, "Team %u ", num);
#endif
break;
case SI:
#ifdef RUSSIAN
- lcd.print(convert("Игрок ") + String(int(num)) + " ");
+ sprintf(printstring, "Игрок %u ", num);
#else
- lcd.print("Player " + String(int(num) + " "));
+ sprintf(printstring, "Player %u ", num);
#endif
break;
}
+ uprint(printstring, &lcd);
buttonPressed = 0;
}
diff --git a/font.h b/font.h
new file mode 100644
index 0000000..b1a512e
--- /dev/null
+++ b/font.h
@@ -0,0 +1,160 @@
+/*
+ Brainuino Aleph
+
+ Copyright (C) 2012 Dmitry Mikhirev
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef font_h
+#define font_h
+
+#include
+
+struct charcode {
+ const int32_t uni;
+ const char font;
+};
+
+charcode charmap[] PROGMEM = {
+// tilde
+ {0x007e, 0xe9},
+// latin-1 supplement
+ {0x0083, 0xce},
+ {0x00a2, 0x5c},
+ {0x00a7, 0xfd},
+ {0x00a8, 0xe8},
+ {0x00ab, 0xc8},
+ {0x00b4, 0xe7},
+ {0x00b6, 0xfe},
+ {0x00b7, 0xdf},
+ {0x00bb, 0xc9},
+ {0x00bc, 0xf0},
+ {0x00bd, 0xf2},
+ {0x00be, 0xf3},
+ {0x00bf, 0xcd},
+ {0x00d7, 0xd5},
+ {0x00e7, 0xeb},
+ {0x00e9, 0xea},
+ {0x00eb, 0xb5},
+// greek
+ {0x0391, 0x41},
+ {0x0392, 0x42},
+ {0x0393, 0xa1},
+ {0x0395, 0x45},
+ {0x0396, 0x5a},
+ {0x0397, 0x48},
+ {0x0399, 0x49},
+ {0x039a, 0x4b},
+ {0x039c, 0x4d},
+ {0x039d, 0x4e},
+ {0x039f, 0x4f},
+ {0x03a0, 0xa8},
+ {0x03a1, 0x50},
+ {0x03a4, 0x54},
+ {0x03a5, 0x59},
+ {0x03a6, 0xaa},
+ {0x03a7, 0x58},
+ {0x03ba, 0xba},
+ {0x03bf, 0x6f},
+ {0x03c0, 0xbe},
+ {0x03c1, 0x70},
+// cyryllic
+ {0x0401, 0xa2},
+ {0x0410, 0x41},
+ {0x0411, 0xa0},
+ {0x0412, 0x42},
+ {0x0413, 0xa1},
+ {0x0414, 0xe0},
+ {0x0415, 0x45},
+ {0x0416, 0xa3},
+ {0x0417, 0xa4},
+ {0x0418, 0xa5},
+ {0x0419, 0xa6},
+ {0x041a, 0x4b},
+ {0x041b, 0xa7},
+ {0x041c, 0x4d},
+ {0x041e, 0x4f},
+ {0x041f, 0xa8},
+ {0x0420, 0x50},
+ {0x0421, 0x43},
+ {0x0422, 0x54},
+ {0x0423, 0xa9},
+ {0x0424, 0xaa},
+ {0x0425, 0x58},
+ {0x0426, 0xe1},
+ {0x0427, 0xab},
+ {0x0428, 0xac},
+ {0x0429, 0xe2},
+ {0x042a, 0xad},
+ {0x042b, 0xae},
+ {0x042c, 0x62},
+ {0x042d, 0xaf},
+ {0x042e, 0xb0},
+ {0x042f, 0xb1},
+ {0x0430, 0x61},
+ {0x0431, 0xb2},
+ {0x0432, 0xb3},
+ {0x0433, 0xb4},
+ {0x0434, 0xe3},
+ {0x0435, 0x65},
+ {0x0436, 0xb6},
+ {0x0437, 0xb7},
+ {0x0438, 0xb8},
+ {0x0439, 0xb9},
+ {0x043a, 0xba},
+ {0x043b, 0xbb},
+ {0x043c, 0xbc},
+ {0x043d, 0xbd},
+ {0x043e, 0x6f},
+ {0x043f, 0xbe},
+ {0x0440, 0x70},
+ {0x0441, 0x63},
+ {0x0442, 0xbf},
+ {0x0443, 0x79},
+ {0x0444, 0xe4},
+ {0x0445, 0x78},
+ {0x0446, 0xe5},
+ {0x0447, 0xc0},
+ {0x0448, 0xc1},
+ {0x0449, 0xe6},
+ {0x044a, 0xc2},
+ {0x044b, 0xc3},
+ {0x044c, 0xc4},
+ {0x044d, 0xc5},
+ {0x044e, 0xc6},
+ {0x044f, 0xc7},
+ {0x0451, 0xb5},
+// general punctuation
+ {0x2010, 0x2e},
+ {0x2011, 0x2e},
+ {0x2012, 0x2e},
+ {0x2013, 0x2e},
+ {0x2014, 0x2e},
+ {0x2015, 0x2e},
+ {0x201c, 0xca},
+ {0x201d, 0xcb},
+// one third
+ {0x2153, 0xf1},
+// arrows
+ {0x2191, 0xd9},
+ {0x2193, 0xda},
+ {0x21b5, 0x7e},
+// mathematical operators
+ {0x2212, 0x2e},
+ {0x2218, 0xef},
+ {0x22c5, 0xdf}
+};
+
+#endif
diff --git a/font_en.h b/font_en.h
deleted file mode 100644
index e69de29..0000000
diff --git a/font_ru-en.h b/font_ru-en.h
deleted file mode 100644
index 2b6c785..0000000
--- a/font_ru-en.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- Brainuino Aleph
-
- Copyright (C) 2012 Dmitry Mikhirev
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-#ifndef en_ru_h
-#define en_ru_h
-
-#include
-
-struct charcode {
- const int32_t uni;
- const char font;
-};
-
-const charcode charmap[] PROGMEM = {
-// tilde
- {0x007e, 0xe9},
-// latin-1 supplement
- {0x0083, 0xce},
- {0x00a2, 0x5c},
- {0x00a7, 0xfd},
- {0x00a8, 0xe8},
- {0x00ab, 0xc8},
- {0x00b4, 0xe7},
- {0x00b6, 0xfe},
- {0x00b7, 0xdf},
- {0x00bb, 0xc9},
- {0x00bc, 0xf0},
- {0x00bd, 0xf2},
- {0x00be, 0xf3},
- {0x00bf, 0xcd},
- {0x00d7, 0xd5},
- {0x00e7, 0xeb},
- {0x00e9, 0xea},
- {0x00eb, 0xb5},
-// greek
- {0x0391, 0x41},
- {0x0392, 0x42},
- {0x0393, 0xa1},
- {0x0395, 0x45},
- {0x0396, 0x5a},
- {0x0397, 0x48},
- {0x0399, 0x49},
- {0x039a, 0x4b},
- {0x039c, 0x4d},
- {0x039d, 0x4e},
- {0x039f, 0x4f},
- {0x03a0, 0xa8},
- {0x03a1, 0x50},
- {0x03a4, 0x54},
- {0x03a5, 0x59},
- {0x03a6, 0xaa},
- {0x03a7, 0x58},
- {0x03ba, 0xba},
- {0x03bf, 0x6f},
- {0x03c0, 0xbe},
- {0x03c1, 0x70},
-// cyryllic
- {0x0401, 0xa2},
- {0x0410, 0x41},
- {0x0411, 0xa0},
- {0x0412, 0x42},
- {0x0413, 0xa1},
- {0x0414, 0xe0},
- {0x0415, 0x45},
- {0x0416, 0xa3},
- {0x0417, 0xa4},
- {0x0418, 0xa5},
- {0x0419, 0xa6},
- {0x041a, 0x4b},
- {0x041b, 0xa7},
- {0x041c, 0x4d},
- {0x041e, 0x4f},
- {0x041f, 0xa8},
- {0x0420, 0x50},
- {0x0421, 0x43},
- {0x0422, 0x54},
- {0x0423, 0xa9},
- {0x0424, 0xaa},
- {0x0425, 0x58},
- {0x0426, 0xe1},
- {0x0427, 0xab},
- {0x0428, 0xac},
- {0x0429, 0xe2},
- {0x042a, 0xad},
- {0x042b, 0xae},
- {0x042c, 0x62},
- {0x042d, 0xaf},
- {0x042e, 0xb0},
- {0x042f, 0xb1},
- {0x0430, 0x61},
- {0x0431, 0xb2},
- {0x0432, 0xb3},
- {0x0433, 0xb4},
- {0x0434, 0xe3},
- {0x0435, 0x65},
- {0x0436, 0xb6},
- {0x0437, 0xb7},
- {0x0438, 0xb8},
- {0x0439, 0xb9},
- {0x043a, 0xba},
- {0x043b, 0xbb},
- {0x043c, 0xbc},
- {0x043d, 0xbd},
- {0x043e, 0x6f},
- {0x043f, 0xbf},
- {0x0440, 0x70},
- {0x0441, 0x63},
- {0x0442, 0xbf},
- {0x0443, 0x79},
- {0x0444, 0xe4},
- {0x0445, 0x78},
- {0x0446, 0xe5},
- {0x0447, 0xc0},
- {0x0448, 0xc1},
- {0x0449, 0xe6},
- {0x044a, 0xc2},
- {0x044b, 0xc3},
- {0x044c, 0xc4},
- {0x044d, 0xc5},
- {0x044e, 0xc6},
- {0x044f, 0xc7},
- {0x0451, 0xb5},
-// general punctuation
- {0x2010, 0x2e},
- {0x2011, 0x2e},
- {0x2012, 0x2e},
- {0x2013, 0x2e},
- {0x2014, 0x2e},
- {0x2015, 0x2e},
- {0x201c, 0xca},
- {0x201d, 0xcb},
-// one third
- {0x2153, 0xf1},
-// arrows
- {0x2191, 0xd9},
- {0x2193, 0xda},
- {0x21b5, 0x7e},
-// mathematical operators
- {0x2212, 0x2e},
- {0x2218, 0xef},
- {0x22c5, 0xdf}
-};
-
-#endif
diff --git a/lcdprint.cpp b/lcdprint.cpp
index 585b2de..c79bb1c 100644
--- a/lcdprint.cpp
+++ b/lcdprint.cpp
@@ -17,12 +17,11 @@
along with this program. If not, see .
*/
-
+#include
#include "lcdprint.h"
-#include "font_ru-en.h"
-//#include "font_en.h"
+#include "font.h"
-char* convert(utf8 str)
+size_t uprint(utf8 str, LiquidCrystal *lcd)
{
int32_t ucode;
int i, j;
@@ -36,9 +35,9 @@ char* convert(utf8 str)
result[i] = char(ucode);
} else {
result[i] = 0xff;
- for (j = 0; j < numcodes && charmap[j].uni < ucode; j++) {
- if (charmap[j].uni == ucode) {
- result[i] = charmap[j].font;
+ for (j = 0; (j < numcodes) && (pgm_read_dword(&charmap[j].uni) <= ucode); j++) {
+ if (pgm_read_dword(&charmap[j].uni) == ucode) {
+ result[i] = pgm_read_byte(&charmap[j].font);
}
}
}
@@ -47,6 +46,5 @@ char* convert(utf8 str)
break;
}
}
-
- return result;
+ return lcd->print(result);
}
diff --git a/lcdprint.h b/lcdprint.h
index b76c425..86dbfcc 100644
--- a/lcdprint.h
+++ b/lcdprint.h
@@ -22,6 +22,6 @@
#include "utf8.h"
-char* convert (utf8);
+size_t uprint (utf8, LiquidCrystal*);
#endif
diff --git a/utf8.cpp b/utf8.cpp
index 026d16e..ea28922 100644
--- a/utf8.cpp
+++ b/utf8.cpp
@@ -20,23 +20,22 @@
#include "utf8.h"
#include
-utf8::utf8 (char* string)
+utf8::utf8 (char* input)
{
- bytes = strlen(string);
- _string = (char *)malloc(bytes + 1);
- strcpy(_string, string);
+ bytes = strlen(input);
+ string = strdup(input);
chars = 0;
for (_index = 0; _index < bytes; _index++) {
- if (_string[_index] & 0x80 == 0) {
+ if ((string[_index] & 0x80) == 0x00) {
+ chars++;
+ } else if ((string[_index] & 0x20) == 0x00) {
+ chars++;
+ _index ++;
+ } else if ((string[_index] & 0x10) == 0x00) {
chars++;
- } else if (_string[_index] & 0x20 == 0) {
- chars += 2;
- _index++;
- } else if (_string[_index] & 0x10 == 0) {
- chars += 3;
_index += 2;
- } else if (_string[_index] & 0x8 == 0) {
- chars += 4;
+ } else if ((string[_index] & 0x08) == 0x00) {
+ chars++;
_index += 3;
}
}
@@ -46,18 +45,18 @@ utf8::utf8 (char* string)
int32_t utf8::get()
{
int32_t code;
- if (_string[_index] & 0x80 == 0) {
- code = int32_t(_string[_index]);
+ if ((string[_index] & 0x80) == 0) {
+ code = int32_t(string[_index]);
_index++;
- } else if (_string[_index] & 0x20 == 0) {
- code = int32_t(_string[_index] & 0x1f) << 6 | int32_t(_string[_index+1] & 0x3f);
+ } else if ((string[_index] & 0x20) == 0) {
+ code = int32_t(string[_index] & 0x1f) << 6 | int32_t(string[_index+1] & 0x3f);
_index += 2;
- } else if (_string[_index] & 0x10 == 0) {
- code = int32_t(_string[_index] & 0xf) << 12 | int32_t(_string[_index+1] & 0x3f) << 6 | int32_t(_string[_index+2] & 0x3f);
+ } else if ((string[_index] & 0x10) == 0) {
+ code = int32_t(string[_index] & 0xf) << 12 | int32_t(string[_index+1] & 0x3f) << 6 | int32_t(string[_index+2] & 0x3f);
_index += 3;
- } else if (_string[_index] & 0x8 == 0) {
- code = int32_t(_string[_index] & 0x7) << 18 | int32_t(_string[_index+1] & 0x3f) << 12 | int32_t(_string[_index+2] & 0x3f) << 6 | int32_t(_string[_index+3] & 0x3f);
+ } else if ((string[_index] & 0x8) == 0) {
+ code = int32_t(string[_index] & 0x7) << 18 | int32_t(string[_index+1] & 0x3f) << 12 | int32_t(string[_index+2] & 0x3f) << 6 | int32_t(string[_index+3] & 0x3f);
}
- if (_index > bytes) _index = 0;
+ if (_index >= bytes) _index = 0;
return code;
}
diff --git a/utf8.h b/utf8.h
index 5dbc221..dd4cd9b 100644
--- a/utf8.h
+++ b/utf8.h
@@ -28,8 +28,9 @@ class utf8 {
uint16_t chars;
uint16_t bytes;
int32_t get();
+ char* string;
+
private:
- char* _string;
uint16_t _index;
};
--
cgit v1.2.3