config.sound_fdd = 1;
config.sound_relay = 0;
config.sound_buttons = 0;
+
+ config.roma_kana_conversion = false;
#endif
}
config.log_to_syslog = MyGetPrivateProfileBool(_T("Emulator"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
config.log_to_console = MyGetPrivateProfileBool(_T("Emulator"), _T("WriteToConsole"), config.log_to_console, config_path);
+ config.roma_kana_conversion = MyGetPrivateProfileInt(_T("Emulator"), _T("RomaKana"), config.roma_kana_conversion, config_path);
+
for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); ii++) {
uint32_t flags = 0;
flags = MyGetPrivateProfileInt(_T("Emulator"), create_string(_T("SyslogEnabled%d"), ii), 0x0000, config_path);
MyWritePrivateProfileBool(_T("Emulator"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
MyWritePrivateProfileBool(_T("Emulator"), _T("WriteToConsole"), config.log_to_console, config_path);
+ MyWritePrivateProfileInt(_T("Emulator"), _T("RomaKana"), config.roma_kana_conversion, config_path);
for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); ii++) {
uint32_t flags = 0;
int sound_fdd;
int sound_relay;
int sound_buttons;
+
+ bool roma_kana_conversion;
#endif
} config_t;
--- /dev/null
+/*
+ Skelton for retropc emulator
+
+ Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
+ Date : 2016.10.23-
+
+ [ Romaji -> Kana conversion ]
+*/
+
+#include "common.h"
+#include "vm.h"
+#include "romakana.h"
+
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+
+_TCHAR detect_shiin(const _TCHAR src, bool *b_dakuon, bool *b_handakuon, bool *b_chi, bool *b_kigou)
+{
+ _TCHAR base_code;
+ *b_dakuon = false;
+ *b_handakuon = false;
+ *b_chi = false;
+ *b_kigou = false;
+ switch(src) {
+ case 'X':
+ case 'x':
+ base_code = KANA_SMALL_A;
+ break;
+ case 'K':
+ case 'k':
+ base_code = KANA_KA; // KA
+ break;
+ case 'S':
+ case 's':
+ base_code = KANA_SA; // SA
+ break;
+ case 'T':
+ case 't':
+ base_code = KANA_TA; // TA
+ break;
+ case 'N':
+ case 'n':
+ base_code = KANA_NA; // NA
+ break;
+ case 'H':
+ case 'h':
+ base_code = KANA_HA; // HA
+ break;
+ case 'M':
+ case 'm':
+ base_code = KANA_MA; // MA
+ break;
+ case 'Y':
+ case 'y':
+ base_code = KANA_YA; // YA
+ break;
+ case 'R':
+ case 'r':
+ base_code = KANA_RA; // RA
+ break;
+ case 'W':
+ case 'w':
+ base_code = KANA_WA; // WA
+ break;
+ case 'G':
+ case 'g':
+ base_code = KANA_KA;
+ *b_dakuon = true;
+ break;
+ case 'Z':
+ case 'z':
+ base_code = KANA_SA;
+ *b_dakuon = true;
+ break;
+ case 'D':
+ case 'd':
+ base_code = KANA_TA;
+ *b_dakuon = true;
+ break;
+ case 'B':
+ case 'b':
+ base_code = KANA_HA;
+ *b_dakuon = true;
+ break;
+ case 'P':
+ case 'p':
+ base_code = KANA_HA;
+ *b_handakuon = true;
+ break;
+ case 'C':
+ case 'c':
+ base_code = 0;
+ *b_chi = true;
+ break;
+ case '-':
+ base_code = KANA_ONBIKI;
+ *b_kigou = true;
+ break;
+ case '`':
+ base_code = KANA_DAKUON;
+ *b_kigou = true;
+ break;
+ case '{':
+ base_code = KANA_HANDAKUON;
+ *b_kigou = true;
+ break;
+ case '[':
+ base_code = KANA_UPPER_KAKKO;
+ *b_kigou = true;
+ break;
+ case ']':
+ base_code = KANA_DOWNER_KAKKO;
+ *b_kigou = true;
+ break;
+ case ',':
+ base_code = KANA_COMMA;
+ *b_kigou = true;
+ break;
+ case '.':
+ base_code = KANA_MARU;
+ *b_kigou = true;
+ break;
+ case '/':
+ base_code = KANA_NAKAGURO;
+ *b_kigou = true;
+ break;
+ default:
+ base_code = 0;
+ break;
+ }
+ return base_code;
+}
+
+int detect_boin(_TCHAR src, _TCHAR base_code, bool *b_xya, bool *b_tsu, bool *b_nn)
+{
+ int code = -1;
+ *b_xya = false;
+ *b_tsu = false;
+ *b_nn = false;
+ switch(src)
+ {
+ case 'A':
+ case 'a':
+ code = 0;
+ break;
+ case 'I':
+ case 'i':
+ code = 1;
+ break;
+ case 'U':
+ case 'u':
+ code = 2;
+ break;
+ case 'E':
+ case 'e':
+ code = 3;
+ break;
+ case 'O':
+ case 'o':
+ code = 4;
+ break;
+ case 'Y':
+ case 'y':
+ *b_xya = true;
+ code = -1;
+ break;
+ case 'S': // TSU
+ case 's':
+ if((base_code & 0x00ff) == 0x00c0) {
+ code = -2;
+ *b_tsu = true;
+ }
+ break;
+ case 'N': // NN
+ case 'n':
+ code = -3;
+ *b_nn = true;
+ break;
+ }
+ return code;
+}
+
+_TCHAR detect_xya(const _TCHAR c, _TCHAR base_code)
+{
+ bool b_dummy1;
+ bool b_dummy2;
+ bool b_dummy3;
+ int r_code = detect_boin(c, base_code, &b_dummy1, &b_dummy2, &b_dummy3);
+ switch(r_code) {
+ case 0: // Kya
+ return KANA_SMALL_YA;
+ break;
+ case 2: // Kyu
+ return KANA_SMALL_YU;
+ break;
+ case 4: // Kyo
+ return KANA_SMALL_YO;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return 0;
+}
+
+
+_TCHAR detect_w(const _TCHAR c, _TCHAR base_code)
+{
+ bool b_dummy1;
+ bool b_dummy2;
+ bool b_dummy3;
+ int r_code = detect_boin(c, base_code, &b_dummy1, &b_dummy2, &b_dummy3);
+ switch(r_code) {
+ case 0: // Wa
+ return KANA_WA;
+ break;
+ case 4: // Wo
+ return KANA_WO;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return 0;
+}
+
+extern "C" {
+int alphabet_to_kana(const _TCHAR *src, _TCHAR *dst, int *dstlen)
+{
+ int srclen;
+ bool b_boin = false;
+ bool b_shiin = false;
+ bool b_x = false;
+ bool b_dakuon = false;
+ bool b_handakuon = false;
+ bool b_xya = false;
+ bool b_tsu = false;
+ bool b_chi = false;
+ bool b_nn = false;
+ bool b_kigou = false;
+ int dstp = 0;
+ int dlen;
+ int i, j;
+ _TCHAR base_code = 0;
+ if((src == NULL) || (dst == NULL) || (dstlen == NULL)) return -1;
+ srclen = strlen(src);
+ dlen = *dstlen;
+ if((dlen <= 0) || (srclen <= 0)) return -1;
+ i = 0;
+ j = 0;
+ do {
+ base_code = detect_shiin((const _TCHAR)src[i], &b_dakuon, &b_handakuon, &b_chi, &b_kigou);
+ if(b_kigou) {
+ if(base_code != 0) {
+ if(j < dlen) {
+ dst[j++] = base_code;
+ }
+ }
+ i++;
+ } else if(base_code != 0) {
+ if((i + 1) >= srclen) {
+ *dstlen = 0;
+ return 0;
+ }
+ if((base_code & 0x00ff) == KANA_WA) {
+ _TCHAR c_code = detect_w((const _TCHAR)src[i + 1], base_code);
+ if(c_code != 0) {
+ if(j < dlen) {
+ dst[j++] = c_code;
+ }
+ i += 2;
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ i += 2;
+ }
+ } else if((base_code & 0x00ff) == KANA_SMALL_A) {
+ int c_code = 0;
+ c_code = detect_boin((const _TCHAR)src[i + 1], base_code, &b_xya, &b_tsu, &b_nn);
+ if(c_code >= 0) {
+ if(j < dlen) {
+ dst[j++] = KANA_SMALL_A + c_code;
+ }
+ i += 2;
+ } else {
+ if(b_xya) {
+ if((i + 2) < srclen) {
+ _TCHAR rr = detect_xya((const _TCHAR)src[i + 2], base_code);
+ if(rr != 0) {
+ if(j < dlen) {
+ dst[j++] = rr;
+ }
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 2];
+ }
+ }
+ i += 3;
+ } else {
+ *dstlen = 0;
+ return 0;
+ }
+ } else {
+ if((i + 2) < srclen) {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ i += 2;
+ } else {
+ *dstlen = 0;
+ return 0;
+ }
+ }
+ }
+ } else {
+ int code = detect_boin((const _TCHAR)src[i + 1], base_code, &b_xya, &b_tsu, &b_nn);
+ if(b_nn) {
+ if(j < dlen) {
+ dst[j++] = KANA_NN;
+ }
+ i += 2;
+ } else if(code >= 0) {
+ if(j < dlen) {
+ if((base_code & 0x00ff) == KANA_YA) {
+ switch(code) {
+ case 0:
+ dst[j++] = base_code;
+ break;
+ case 2:
+ dst[j++] = base_code + 1;
+ break;
+ case 4:
+ dst[j++] = base_code + 2;
+ break;
+ default:
+ dst[j++] = src[i];
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ break;
+ }
+ } else {
+ dst[j++] = base_code + code;
+ }
+ }
+ if(b_dakuon) {
+ if(j < dlen) {
+ dst[j++] = KANA_DAKUON;
+ }
+ } else if(b_handakuon) {
+ if(j < dlen) {
+ dst[j++] = KANA_HANDAKUON;
+ }
+ }
+ i += 2;
+
+ } else {
+ _TCHAR next_code = 0;
+ if(b_xya) {
+ if((i + 2) >= srclen) {
+ *dstlen = 0;
+ return 0;
+ }
+ uint32_t bc = base_code & 0x00ff;
+ if(((bc >= KANA_KA) && (bc <= KANA_MA)) || (bc == KANA_RA)) {
+ // Ky*, Sy*, Ty*, Ny*, My*, Hy*, Ry*, Zy*, Dy*, By*, Py*
+ next_code = detect_xya((const _TCHAR)src[i + 2], base_code);
+ if(next_code != 0) {
+ if(j < dlen) {
+ dst[j] = base_code + 1;
+ j++;
+ i += 2;
+ }
+ if(b_dakuon) {
+ if(j < dlen) {
+ dst[j] = KANA_DAKUON;
+ j++;
+ }
+ } else if(b_handakuon) {
+ if(j < dlen) {
+ dst[j] = KANA_HANDAKUON;
+ j++;
+ }
+ }
+ if(j < dlen) {
+ dst[j] = next_code;
+ j++;
+ i++;
+ }
+ } else {
+ i += 2;
+ }
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 2];
+ }
+ i += 3;
+ }
+ } else if(b_tsu) {
+ if((i + 2) >= srclen) {
+ *dstlen = 0;
+ return 0;
+ }
+ uint32_t bc = base_code & 0x00ff;
+ if((src[i + 2] == 'u') || (src[i + 2] == 'U')) {
+ if(j < dlen) {
+ dst[j++] = KANA_TA + 2; // TU
+ }
+ i += 3;
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 2];
+ }
+ i += 3;
+ }
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i++];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i++];
+ }
+ }
+ }
+ }
+ } else { // Not shiin
+ if(b_chi) {
+ if((i + 2) < srclen) {
+ if((src[i + 1] == 'H') || (src[i + 1] == 'h')) {
+ int code = detect_boin((const _TCHAR)src[i + 2], base_code, &b_xya, &b_tsu, &b_nn);
+ _TCHAR ccode = 0;
+ if(code >= 0) {
+ switch(code) {
+ case 0: // Cha
+ case 2: // Chu
+ case 3: // Che
+ case 4: // Cho
+ ccode = KANA_TA + 1;
+ break;
+ }
+ if(ccode != 0) {
+ if(j < dlen) {
+ dst[j++] = ccode;
+ }
+ if(j < dlen) {
+ if(code == 3) { // Che
+ dst[j++] = KANA_SMALL_E;
+ } else {
+ dst[j++] = (code >> 1) + KANA_SMALL_YA;
+ }
+ }
+ } else {
+ if(code == 1) {
+ if(j < dlen) {
+ dst[j++] = KANA_TA + 1;
+ }
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 2];
+ }
+ }
+ }
+ i += 3;
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ if(j < dlen) {
+ dst[j++] = src[i + 1];
+ }
+ i += 2;
+ }
+ } else { // Not cha-cho
+ if(j < dlen) {
+ dst[j++] = src[i++];
+ }
+ }
+ } else {
+ *dstlen = 0;
+ return 0;
+ }
+ } else { // Not chi
+ if(base_code != 0) {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ break; // over srclen.
+ }
+ int code = detect_boin((const _TCHAR)src[i], base_code, &b_xya, &b_tsu, &b_nn);
+ if(code >= 0) {
+ if(j < dlen) {
+ dst[j++] = code + KANA_A;
+ }
+ } else {
+ if(j < dlen) {
+ dst[j++] = src[i];
+ }
+ }
+ i++;
+ }
+ }
+ } while((i <= srclen) && (j < dlen));
+ *dstlen = j;
+ if(j <= 0) return 0;
+ return i;
+}
+}
+#endif //defined(SUPPORT_ROMA_KANA_CONVERSION)
--- /dev/null
+/*
+ Skelton for retropc emulator
+
+ Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
+ Date : 2016.10.23-
+
+ [ Romaji -> Kana conversion ]
+*/
+
+#ifndef _ROMAKANA_H
+#define _ROMAKANA_H
+
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+#define KANA_MARU 0x00a1
+#define KANA_UPPER_KAKKO 0x00a2
+#define KANA_DOWNER_KAKKO 0x00a3
+#define KANA_COMMA 0x00a4
+#define KANA_NAKAGURO 0x00a5
+#define KANA_WO 0x00a6
+#define KANA_SMALL_A 0x00a7
+#define KANA_SMALL_I 0x00a8
+#define KANA_SMALL_U 0x00a9
+#define KANA_SMALL_E 0x00aa
+#define KANA_SMALL_O 0x00ab
+#define KANA_SMALL_YA 0x00ac
+#define KANA_SMALL_YU 0x00ad
+#define KANA_SMALL_YO 0x00ae
+#define KANA_SMALL_TU 0x00af
+#define KANA_ONBIKI 0x00b0
+#define KANA_A 0x00b1
+#define KANA_KA 0x00b6
+#define KANA_SA 0x00bb
+#define KANA_TA 0x00c0
+#define KANA_NA 0x00c5
+#define KANA_HA 0x00ca
+#define KANA_MA 0x00cf
+#define KANA_YA 0x00d4
+#define KANA_RA 0x00d7
+#define KANA_WA 0x00dc
+#define KANA_NN 0x00dd
+#define KANA_DAKUON 0x00de
+#define KANA_HANDAKUON 0x00df
+
+extern "C" {
+// Convert romaji -> kana.
+// ARG:
+// src : src string (ASCII)
+// dst : dst string (KANA = iso2022-jp + 0x80) see http://charset.7jp.net/jis.html .
+//
+// -1 : Illegal
+// 0 : Not converted
+// 1 : convert
+// 2 : convert, but, another candicate exiusts.
+ extern int alphabet_to_kana(const _TCHAR *src, _TCHAR *dst, int *dstlen);
+}
+#endif // defined(SUPPORT_ROMA_KANA_CONVERSION)
+
+#endif
#define USE_DEBUGGER
#define DATAREC_SOUND
#define USE_DIG_RESOLUTION
+#define SUPPORT_ROMA_KANA_CONVERSION
+
#if defined(_USE_QT)
#define USE_SOUND_FILES 3
#define USE_SOUND_FILES_FDD
uint32_t keycode_7;
int keymode;
- private:
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+ _TCHAR romakana_buffer[16];
+ int romakana_ptr;
+#endif
+private:
bool ctrl_pressed;
bool lshift_pressed;
bool rshift_pressed;
* History :
* Feb 12, 2015 : Initial
*/
-
+#include "fm7.h"
#include "../../fifo.h"
#include "../device.h"
#include "fm7_keyboard.h"
-
#include "keyboard_tables.h"
+
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+#include "../../romakana.h"
+#endif
+
#if defined(_FM77AV_VARIANTS)
#include "../beep.h"
#include "fm77av_hidden_message_keyboard.h"
keyptr = graph_key;
}
} else if(kana_pressed) {
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+ if(config.roma_kana_conversion) {
+ if(shift_pressed) {
+ keyptr = standard_shift_key;
+ } else {
+ keyptr = standard_key;
+ }
+ } else {
+ if(shift_pressed) {
+ keyptr = kana_shift_key;
+ } else {
+ keyptr = kana_key;
+ }
+ }
+#else
if(shift_pressed) {
keyptr = kana_shift_key;
} else {
keyptr = kana_key;
}
+#endif
} else { // Standard
stdkey = true;
if(shift_pressed) {
}
}
}
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+ else if(kana_pressed) {
+ int i = 0;
+ if(((retval >= '`') && (retval <= 'z')) ||
+ ((retval >= '@') && (retval <= 'Z')) ||
+ ((retval >= ',') && (retval <= '/')) ||
+ ((retval == '[') || (retval == ']')) ||
+ ((retval == '{') || (retval == '}'))) {
+ if(romakana_ptr < sizeof(romakana_buffer)) {
+ romakana_buffer[romakana_ptr++] = retval;
+ _TCHAR kana_buffer[16];
+ int kana_len = sizeof(kana_buffer);
+ memset(kana_buffer, 0x00, sizeof(kana_buffer));
+
+ if(alphabet_to_kana((const _TCHAR *)romakana_buffer, kana_buffer, &kana_len) > 0) {
+ int r;
+ if(kana_len > 0) {
+ for(i = 0; i < kana_len; i++) {
+ r = kana_buffer[i];
+ if(r == KANA_WO) {
+ r = (KANA_WA + 1) & 0x00ff;
+ } else {
+ r = r & 0x00ff;
+ }
+ key_fifo->write(r);
+ }
+ }
+ memset(romakana_buffer, 0x00, sizeof(romakana_buffer));
+ romakana_ptr = 0;
+ }
+ retval = 0;
+ } else { // Discard
+ for(i = 0; i < sizeof(romakana_buffer); i++) {
+ key_fifo->write(romakana_buffer[i]);
+ }
+ retval = 0;
+ memset(romakana_buffer, 0x00, sizeof(romakana_buffer));
+ romakana_ptr = 0;
+ }
+ } else {
+ if(romakana_ptr > 0) {
+ for(i = 0; i < romakana_ptr; i++) {
+ key_fifo->write(romakana_buffer[i]);
+ }
+ memset(romakana_buffer, 0x00, sizeof(romakana_buffer));
+ romakana_ptr = 0;
+ }
+ }
+ }
+#endif
return retval;
}
event_hidden1_av = -1;
hidden1_ptr = 0;
#endif
+#if defined(SUPPORT_ROMA_KANA_CONVERSION)
+ memset(romakana_buffer, 0x00, sizeof(romakana_buffer));
+ romakana_ptr = 0;
+#endif
// Bus
this->write_signals(&break_line, 0x00);
#if defined(_FM77AV_VARIANTS)