OSDN Git Service

2b7eb9519ab5fce026ed75abaaaf2276412db150
[csp-qt/common_source_project-fm7.git] / source / src / qt / common / emu_thread_slots.cpp
1 /*
2         Skelton for retropc emulator
3         Author : Takeda.Toshiya
4     Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.10
6         History: 2016.8.26 Split from emu_thread.cpp
7         Note: This class must be compiled per VM, must not integrate shared units.
8         [ win32 main ] -> [ Qt main ] -> [Emu Thread] -> [QObject SLOTs depended by VM]
9 */
10
11 #include <QString>
12 #include <QTextCodec>
13 #include <QWaitCondition>
14
15 #include <SDL.h>
16
17 #include "../gui/emu_thread_tmpl.h"
18
19 #include "qt_gldraw.h"
20 #include "csp_logger.h"
21 #include "../gui/menu_flags.h"
22 #include "dock_disks.h"
23 // buttons
24 #ifdef MAX_BUTTONS
25 #define MAX_FONT_SIZE 32
26 #endif
27 #define MAX_SKIP_FRAMES 10
28
29
30 const int auto_key_table_base[][2] = {
31         // 0x100: shift
32         // 0x200: kana
33         // 0x400: alphabet
34         // 0x800: ALPHABET
35         // 0x1000 : LOCK
36         // 0x2000 : UNLOCK
37         {0x0a,  0x000 | 0x0d},  // Enter(Unix)
38         {0x0d,  0x000 | 0x0d},  // Enter
39         {0x20,  0x000 | 0x20},  // ' '
40
41         {0x21,  0x100 | 0x31},  // '!'
42         {0x22,  0x100 | 0x32},  // '"'
43         {0x23,  0x100 | 0x33},  // '#'
44         {0x24,  0x100 | 0x34},  // '$'
45         {0x25,  0x100 | 0x35},  // '%'
46         {0x26,  0x100 | 0x36},  // '&'
47         {0x27,  0x100 | 0x37},  // '''
48         {0x28,  0x100 | 0x38},  // '('
49         {0x29,  0x100 | 0x39},  // ')'
50         {0x2a,  0x100 | 0xba},  // '*'
51         {0x2b,  0x100 | 0xbb},  // '+'
52         {0x2c,  0x000 | 0xbc},  // ','
53         {0x2d,  0x000 | 0xbd},  // '-'
54         {0x2e,  0x000 | 0xbe},  // '.'
55         {0x2f,  0x000 | 0xbf},  // '/'
56
57         {0x30,  0x000 | 0x30},  // '0'
58         {0x31,  0x000 | 0x31},  // '1'
59         {0x32,  0x000 | 0x32},  // '2'
60         {0x33,  0x000 | 0x33},  // '3'
61         {0x34,  0x000 | 0x34},  // '4'
62         {0x35,  0x000 | 0x35},  // '5'
63         {0x36,  0x000 | 0x36},  // '6'
64         {0x37,  0x000 | 0x37},  // '7'
65         {0x38,  0x000 | 0x38},  // '8'
66         {0x39,  0x000 | 0x39},  // '9'
67
68         {0x3a,  0x000 | 0xba},  // ':'
69         {0x3b,  0x000 | 0xbb},  // ';'
70         {0x3c,  0x100 | 0xbc},  // '<'
71         {0x3d,  0x100 | 0xbd},  // '='
72         {0x3e,  0x100 | 0xbe},  // '>'
73         {0x3f,  0x100 | 0xbf},  // '?'
74         {0x40,  0x000 | 0xc0},  // '@'
75
76         {0x41,  0x400 | 0x41},  // 'A'
77         {0x42,  0x400 | 0x42},  // 'B'
78         {0x43,  0x400 | 0x43},  // 'C'
79         {0x44,  0x400 | 0x44},  // 'D'
80         {0x45,  0x400 | 0x45},  // 'E'
81         {0x46,  0x400 | 0x46},  // 'F'
82         {0x47,  0x400 | 0x47},  // 'G'
83         {0x48,  0x400 | 0x48},  // 'H'
84         {0x49,  0x400 | 0x49},  // 'I'
85         {0x4a,  0x400 | 0x4a},  // 'J'
86         {0x4b,  0x400 | 0x4b},  // 'K'
87         {0x4c,  0x400 | 0x4c},  // 'L'
88         {0x4d,  0x400 | 0x4d},  // 'M'
89         {0x4e,  0x400 | 0x4e},  // 'N'
90         {0x4f,  0x400 | 0x4f},  // 'O'
91         {0x50,  0x400 | 0x50},  // 'P'
92         {0x51,  0x400 | 0x51},  // 'Q'
93         {0x52,  0x400 | 0x52},  // 'R'
94         {0x53,  0x400 | 0x53},  // 'S'
95         {0x54,  0x400 | 0x54},  // 'T'
96         {0x55,  0x400 | 0x55},  // 'U'
97         {0x56,  0x400 | 0x56},  // 'V'
98         {0x57,  0x400 | 0x57},  // 'W'
99         {0x58,  0x400 | 0x58},  // 'X'
100         {0x59,  0x400 | 0x59},  // 'Y'
101         {0x5a,  0x400 | 0x5a},  // 'Z'
102
103         {0x5b,  0x000 | 0xdb},  // '['
104         {0x5c,  0x000 | 0xdc},  // '\'
105         {0x5d,  0x000 | 0xdd},  // ']'
106         {0x5e,  0x000 | 0xde},  // '^'
107         {0x5f,  0x100 | 0xe2},  // '_'
108         {0x60,  0x100 | 0xc0},  // '`'
109
110         {0x61,  0x800 | 0x41},  // 'a'
111         {0x62,  0x800 | 0x42},  // 'b'
112         {0x63,  0x800 | 0x43},  // 'c'
113         {0x64,  0x800 | 0x44},  // 'd'
114         {0x65,  0x800 | 0x45},  // 'e'
115         {0x66,  0x800 | 0x46},  // 'f'
116         {0x67,  0x800 | 0x47},  // 'g'
117         {0x68,  0x800 | 0x48},  // 'h'
118         {0x69,  0x800 | 0x49},  // 'i'
119         {0x6a,  0x800 | 0x4a},  // 'j'
120         {0x6b,  0x800 | 0x4b},  // 'k'
121         {0x6c,  0x800 | 0x4c},  // 'l'
122         {0x6d,  0x800 | 0x4d},  // 'm'
123         {0x6e,  0x800 | 0x4e},  // 'n'
124         {0x6f,  0x800 | 0x4f},  // 'o'
125         {0x70,  0x800 | 0x50},  // 'p'
126         {0x71,  0x800 | 0x51},  // 'q'
127         {0x72,  0x800 | 0x52},  // 'r'
128         {0x73,  0x800 | 0x53},  // 's'
129         {0x74,  0x800 | 0x54},  // 't'
130         {0x75,  0x800 | 0x55},  // 'u'
131         {0x76,  0x800 | 0x56},  // 'v'
132         {0x77,  0x800 | 0x57},  // 'w'
133         {0x78,  0x800 | 0x58},  // 'x'
134         {0x79,  0x800 | 0x59},  // 'y'
135         {0x7a,  0x800 | 0x5a},  // 'z'
136
137         {0x7b,  0x100 | 0xdb},  // '{'
138         {0x7c,  0x100 | 0xdc},  // '|'
139         {0x7d,  0x100 | 0xdd},  // '}'
140         {0x7e,  0x100 | 0xde},  // '~'
141
142         {0xa1,  0x300 | 0xbe},  // '
143         {0xa2,  0x300 | 0xdb},  // '
144         {0xa3,  0x300 | 0xdd},  // '
145         {0xa4,  0x300 | 0xbc},  // '
146         {0xa5,  0x300 | 0xbf},  // '・'
147         {0xa6,  0x300 | 0x30},  // 'ヲ'
148         {0xa7,  0x300 | 0x33},  // 'ァ'
149         {0xa8,  0x300 | 0x45},  // 'ィ'
150         {0xa9,  0x300 | 0x34},  // 'ゥ'
151         {0xaa,  0x300 | 0x35},  // 'ェ'
152         {0xab,  0x300 | 0x36},  // 'ォ'
153         {0xac,  0x300 | 0x37},  // 'ャ'
154         {0xad,  0x300 | 0x38},  // 'ュ'
155         {0xae,  0x300 | 0x39},  // 'ョ'
156         {0xaf,  0x300 | 0x5a},  // 'ッ'
157         {0xb0,  0x200 | 0xdc},  // 'ー'
158         {0xb1,  0x200 | 0x33},  // 'ア'
159         {0xb2,  0x200 | 0x45},  // 'イ'
160         {0xb3,  0x200 | 0x34},  // 'ウ'
161         {0xb4,  0x200 | 0x35},  // 'エ'
162         {0xb5,  0x200 | 0x36},  // 'オ'
163         {0xb6,  0x200 | 0x54},  // 'カ'
164         {0xb7,  0x200 | 0x47},  // 'キ'
165         {0xb8,  0x200 | 0x48},  // 'ク'
166         {0xb9,  0x200 | 0xba},  // 'ケ'
167         {0xba,  0x200 | 0x42},  // 'コ'
168         {0xbb,  0x200 | 0x58},  // 'サ'
169         {0xbc,  0x200 | 0x44},  // 'シ'
170         {0xbd,  0x200 | 0x52},  // 'ス'
171         {0xbe,  0x200 | 0x50},  // 'セ'
172         {0xbf,  0x200 | 0x43},  // 'ソ'
173         {0xc0,  0x200 | 0x51},  // 'タ'
174         {0xc1,  0x200 | 0x41},  // 'チ'
175         {0xc2,  0x200 | 0x5a},  // 'ツ'
176         {0xc3,  0x200 | 0x57},  // 'テ'
177         {0xc4,  0x200 | 0x53},  // 'ト'
178         {0xc5,  0x200 | 0x55},  // 'ナ'
179         {0xc6,  0x200 | 0x49},  // 'ニ'
180         {0xc7,  0x200 | 0x31},  // 'ヌ'
181         {0xc8,  0x200 | 0xbc},  // 'ネ'
182         {0xc9,  0x200 | 0x4b},  // 'ノ'
183         {0xca,  0x200 | 0x46},  // 'ハ'
184         {0xcb,  0x200 | 0x56},  // 'ヒ'
185         {0xcc,  0x200 | 0x32},  // 'フ'
186         {0xcd,  0x200 | 0xde},  // 'ヘ'
187         {0xce,  0x200 | 0xbd},  // 'ホ'
188         {0xcf,  0x200 | 0x4a},  // 'マ'
189         {0xd0,  0x200 | 0x4e},  // 'ミ'
190         {0xd1,  0x200 | 0xdd},  // 'ム'
191         {0xd2,  0x200 | 0xbf},  // 'メ'
192         {0xd3,  0x200 | 0x4d},  // 'モ'
193         {0xd4,  0x200 | 0x37},  // 'ヤ'
194         {0xd5,  0x200 | 0x38},  // 'ユ'
195         {0xd6,  0x200 | 0x39},  // 'ヨ'
196         {0xd7,  0x200 | 0x4f},  // 'ラ'
197         {0xd8,  0x200 | 0x4c},  // 'リ'
198         {0xd9,  0x200 | 0xbe},  // 'ル'
199         {0xda,  0x200 | 0xbb},  // 'レ'
200         {0xdb,  0x200 | 0xe2},  // 'ロ'
201         {0xdc,  0x200 | 0x30},  // 'ワ'
202         {0xdd,  0x200 | 0x59},  // 'ン'
203         {0xde,  0x200 | 0xc0},  // '゙'
204         {0xdf,  0x200 | 0xdb},  // '゚'
205         {-1, -1},
206 };
207
208 const int auto_key_table_base_us[][2] = {
209         // 0x100: shift
210         // 0x200: kana
211         // 0x400: alphabet
212         // 0x800: ALPHABET
213         {0x0a,  0x000 | 0x0d},  // Enter(Unix)
214         {0x0d,  0x000 | 0x0d},  // Enter
215         {0x20,  0x000 | 0x20},  // ' '
216         {0x21,  0x100 | 0x31},  // '!'
217         {0x22,  0x100 | 0xba},  // '"'
218         {0x23,  0x100 | 0x33},  // '#'
219         {0x24,  0x100 | 0x34},  // '$'
220         {0x25,  0x100 | 0x35},  // '%'
221         {0x26,  0x100 | 0x37},  // '&'
222         {0x27,  0x000 | 0xba},  // '''
223         {0x28,  0x100 | 0x39},  // '('
224         {0x29,  0x100 | 0x30},  // ')'
225         {0x2a,  0x100 | 0x38},  // '*'
226         {0x2b,  0x100 | 0xde},  // '+'
227         {0x2c,  0x000 | 0xbc},  // ','
228         {0x2d,  0x000 | 0xbd},  // '-'
229         {0x2e,  0x000 | 0xbe},  // '.'
230         {0x2f,  0x000 | 0xbf},  // '/'
231
232         {0x30,  0x000 | 0x30},  // '0'
233         {0x31,  0x000 | 0x31},  // '1'
234         {0x32,  0x000 | 0x32},  // '2'
235         {0x33,  0x000 | 0x33},  // '3'
236         {0x34,  0x000 | 0x34},  // '4'
237         {0x35,  0x000 | 0x35},  // '5'
238         {0x36,  0x000 | 0x36},  // '6'
239         {0x37,  0x000 | 0x37},  // '7'
240         {0x38,  0x000 | 0x38},  // '8'
241         {0x39,  0x000 | 0x39},  // '9'
242
243         {0x3a,  0x100 | 0xbb},  // ':'
244         {0x3b,  0x000 | 0xbb},  // ';'
245         {0x3c,  0x100 | 0xbc},  // '<'
246         {0x3d,  0x000 | 0xde},  // '='
247         {0x3e,  0x100 | 0xbe},  // '>'
248         {0x3f,  0x100 | 0xbf},  // '?'
249         {0x40,  0x100 | 0x32},  // '@'
250
251         {0x41,  0x400 | 0x41},  // 'A'
252         {0x42,  0x400 | 0x42},  // 'B'
253         {0x43,  0x400 | 0x43},  // 'C'
254         {0x44,  0x400 | 0x44},  // 'D'
255         {0x45,  0x400 | 0x45},  // 'E'
256         {0x46,  0x400 | 0x46},  // 'F'
257         {0x47,  0x400 | 0x47},  // 'G'
258         {0x48,  0x400 | 0x48},  // 'H'
259         {0x49,  0x400 | 0x49},  // 'I'
260         {0x4a,  0x400 | 0x4a},  // 'J'
261         {0x4b,  0x400 | 0x4b},  // 'K'
262         {0x4c,  0x400 | 0x4c},  // 'L'
263         {0x4d,  0x400 | 0x4d},  // 'M'
264         {0x4e,  0x400 | 0x4e},  // 'N'
265         {0x4f,  0x400 | 0x4f},  // 'O'
266         {0x50,  0x400 | 0x50},  // 'P'
267         {0x51,  0x400 | 0x51},  // 'Q'
268         {0x52,  0x400 | 0x52},  // 'R'
269         {0x53,  0x400 | 0x53},  // 'S'
270         {0x54,  0x400 | 0x54},  // 'T'
271         {0x55,  0x400 | 0x55},  // 'U'
272         {0x56,  0x400 | 0x56},  // 'V'
273         {0x57,  0x400 | 0x57},  // 'W'
274         {0x58,  0x400 | 0x58},  // 'X'
275         {0x59,  0x400 | 0x59},  // 'Y'
276         {0x5a,  0x400 | 0x5a},  // 'Z'
277
278         {0x5b,  0x000 | 0xc0},  // '['
279         {0x5c,  0x000 | 0xe2},  // '\'
280         {0x5d,  0x000 | 0xdb},  // ']'
281         {0x5e,  0x100 | 0x36},  // '^'
282         {0x5f,  0x100 | 0xbd},  // '_'
283         {0x60,  0x000 | 0xdd},  // '`'
284
285         {0x61,  0x800 | 0x41},  // 'a'
286         {0x62,  0x800 | 0x42},  // 'b'
287         {0x63,  0x800 | 0x43},  // 'c'
288         {0x64,  0x800 | 0x44},  // 'd'
289         {0x65,  0x800 | 0x45},  // 'e'
290         {0x66,  0x800 | 0x46},  // 'f'
291         {0x67,  0x800 | 0x47},  // 'g'
292         {0x68,  0x800 | 0x48},  // 'h'
293         {0x69,  0x800 | 0x49},  // 'i'
294         {0x6a,  0x800 | 0x4a},  // 'j'
295         {0x6b,  0x800 | 0x4b},  // 'k'
296         {0x6c,  0x800 | 0x4c},  // 'l'
297         {0x6d,  0x800 | 0x4d},  // 'm'
298         {0x6e,  0x800 | 0x4e},  // 'n'
299         {0x6f,  0x800 | 0x4f},  // 'o'
300         {0x70,  0x800 | 0x50},  // 'p'
301         {0x71,  0x800 | 0x51},  // 'q'
302         {0x72,  0x800 | 0x52},  // 'r'
303         {0x73,  0x800 | 0x53},  // 's'
304         {0x74,  0x800 | 0x54},  // 't'
305         {0x75,  0x800 | 0x55},  // 'u'
306         {0x76,  0x800 | 0x56},  // 'v'
307         {0x77,  0x800 | 0x57},  // 'w'
308         {0x78,  0x800 | 0x58},  // 'x'
309         {0x79,  0x800 | 0x59},  // 'y'
310         {0x7a,  0x800 | 0x5a},  // 'z'
311
312         {0x7b,  0x100 | 0xc0},  // '{'
313         {0x7c,  0x100 | 0xe2},  // '|'
314         {0x7d,  0x100 | 0xdb},  // '}'
315         {0x7e,  0x100 | 0xdd},  // '~'
316
317         {0xa1,  0x300 | 0xbe},  // '
318         {0xa2,  0x300 | 0xdb},  // '
319         {0xa3,  0x300 | 0xdd},  // '
320         {0xa4,  0x300 | 0xbc},  // '
321         {0xa5,  0x300 | 0xbf},  // '・'
322         {0xa6,  0x300 | 0x30},  // 'ヲ'
323         {0xa7,  0x300 | 0x33},  // 'ァ'
324         {0xa8,  0x300 | 0x45},  // 'ィ'
325         {0xa9,  0x300 | 0x34},  // 'ゥ'
326         {0xaa,  0x300 | 0x35},  // 'ェ'
327         {0xab,  0x300 | 0x36},  // 'ォ'
328         {0xac,  0x300 | 0x37},  // 'ャ'
329         {0xad,  0x300 | 0x38},  // 'ュ'
330         {0xae,  0x300 | 0x39},  // 'ョ'
331         {0xaf,  0x300 | 0x5a},  // 'ッ'
332         {0xb0,  0x200 | 0xdc},  // 'ー'
333         {0xb1,  0x200 | 0x33},  // 'ア'
334         {0xb2,  0x200 | 0x45},  // 'イ'
335         {0xb3,  0x200 | 0x34},  // 'ウ'
336         {0xb4,  0x200 | 0x35},  // 'エ'
337         {0xb5,  0x200 | 0x36},  // 'オ'
338         {0xb6,  0x200 | 0x54},  // 'カ'
339         {0xb7,  0x200 | 0x47},  // 'キ'
340         {0xb8,  0x200 | 0x48},  // 'ク'
341         {0xb9,  0x200 | 0xba},  // 'ケ'
342         {0xba,  0x200 | 0x42},  // 'コ'
343         {0xbb,  0x200 | 0x58},  // 'サ'
344         {0xbc,  0x200 | 0x44},  // 'シ'
345         {0xbd,  0x200 | 0x52},  // 'ス'
346         {0xbe,  0x200 | 0x50},  // 'セ'
347         {0xbf,  0x200 | 0x43},  // 'ソ'
348         {0xc0,  0x200 | 0x51},  // 'タ'
349         {0xc1,  0x200 | 0x41},  // 'チ'
350         {0xc2,  0x200 | 0x5a},  // 'ツ'
351         {0xc3,  0x200 | 0x57},  // 'テ'
352         {0xc4,  0x200 | 0x53},  // 'ト'
353         {0xc5,  0x200 | 0x55},  // 'ナ'
354         {0xc6,  0x200 | 0x49},  // 'ニ'
355         {0xc7,  0x200 | 0x31},  // 'ヌ'
356         {0xc8,  0x200 | 0xbc},  // 'ネ'
357         {0xc9,  0x200 | 0x4b},  // 'ノ'
358         {0xca,  0x200 | 0x46},  // 'ハ'
359         {0xcb,  0x200 | 0x56},  // 'ヒ'
360         {0xcc,  0x200 | 0x32},  // 'フ'
361         {0xcd,  0x200 | 0xde},  // 'ヘ'
362         {0xce,  0x200 | 0xbd},  // 'ホ'
363         {0xcf,  0x200 | 0x4a},  // 'マ'
364         {0xd0,  0x200 | 0x4e},  // 'ミ'
365         {0xd1,  0x200 | 0xdd},  // 'ム'
366         {0xd2,  0x200 | 0xbf},  // 'メ'
367         {0xd3,  0x200 | 0x4d},  // 'モ'
368         {0xd4,  0x200 | 0x37},  // 'ヤ'
369         {0xd5,  0x200 | 0x38},  // 'ユ'
370         {0xd6,  0x200 | 0x39},  // 'ヨ'
371         {0xd7,  0x200 | 0x4f},  // 'ラ'
372         {0xd8,  0x200 | 0x4c},  // 'リ'
373         {0xd9,  0x200 | 0xbe},  // 'ル'
374         {0xda,  0x200 | 0xbb},  // 'レ'
375         {0xdb,  0x200 | 0xe2},  // 'ロ'
376         {0xdc,  0x200 | 0x30},  // 'ワ'
377         {0xdd,  0x200 | 0x59},  // 'ン'
378         {0xde,  0x200 | 0xc0},  // '゙'
379         {0xdf,  0x200 | 0xdb},  // '゚'
380         {-1, -1},
381 };
382
383 const int auto_key_table_50on_base[][2] = {
384         {0xa1,  0x300 | 0xbf},  // '。'
385         {0xa2,  0x300 | 0xdb},  // '「'
386         {0xa3,  0x300 | 0xdd},  // '」'
387         {0xa4,  0x300 | 0xbe},  // '、'
388         {0xa5,  0x300 | 0xe2},  // '・'
389         {0xa6,  0x200 | 0xbf},  // 'ヲ'
390         {0xa7,  0x300 | 0x31},  // 'ァ'
391         {0xa8,  0x300 | 0x32},  // 'ィ'
392         {0xa9,  0x300 | 0x33},  // 'ゥ'
393         {0xaa,  0x300 | 0x34},  // 'ェ'
394         {0xab,  0x300 | 0x35},  // 'ォ'
395         {0xac,  0x300 | 0x4e},  // 'ャ'
396         {0xad,  0x300 | 0x4d},  // 'ュ'
397         {0xae,  0x300 | 0xbc},  // 'ョ'
398         {0xaf,  0x300 | 0x43},  // 'ッ'
399         {0xb0,  0x300 | 0xba},  // 'ー'
400         {0xb1,  0x200 | 0x31},  // 'ア'
401         {0xb2,  0x200 | 0x32},  // 'イ'
402         {0xb3,  0x200 | 0x33},  // 'ウ'
403         {0xb4,  0x200 | 0x34},  // 'エ'
404         {0xb5,  0x200 | 0x35},  // 'オ'
405         {0xb6,  0x200 | 0x51},  // 'カ'
406         {0xb7,  0x200 | 0x57},  // 'キ'
407         {0xb8,  0x200 | 0x45},  // 'ク'
408         {0xb9,  0x200 | 0x52},  // 'ケ'
409         {0xba,  0x200 | 0x54},  // 'コ'
410         {0xbb,  0x200 | 0x41},  // 'サ'
411         {0xbc,  0x200 | 0x53},  // 'シ'
412         {0xbd,  0x200 | 0x44},  // 'ス'
413         {0xbe,  0x200 | 0x46},  // 'セ'
414         {0xbf,  0x200 | 0x47},  // 'ソ'
415         {0xc0,  0x200 | 0x5a},  // 'タ'
416         {0xc1,  0x200 | 0x58},  // 'チ'
417         {0xc2,  0x200 | 0x43},  // 'ツ'
418         {0xc3,  0x200 | 0x56},  // 'テ'
419         {0xc4,  0x200 | 0x42},  // 'ト'
420         {0xc5,  0x200 | 0x36},  // 'ナ'
421         {0xc6,  0x200 | 0x37},  // 'ニ'
422         {0xc7,  0x200 | 0x38},  // 'ヌ'
423         {0xc8,  0x200 | 0x39},  // 'ネ'
424         {0xc9,  0x200 | 0x30},  // 'ノ'
425         {0xca,  0x200 | 0x59},  // 'ハ'
426         {0xcb,  0x200 | 0x55},  // 'ヒ'
427         {0xcc,  0x200 | 0x49},  // 'フ'
428         {0xcd,  0x200 | 0x4f},  // 'ヘ'
429         {0xce,  0x200 | 0x50},  // 'ホ'
430         {0xcf,  0x200 | 0x48},  // 'マ'
431         {0xd0,  0x200 | 0x4a},  // 'ミ'
432         {0xd1,  0x200 | 0x4b},  // 'ム'
433         {0xd2,  0x200 | 0x4c},  // 'メ'
434         {0xd3,  0x200 | 0xbb},  // 'モ'
435         {0xd4,  0x200 | 0x4e},  // 'ヤ'
436         {0xd5,  0x200 | 0x4d},  // 'ユ'
437         {0xd6,  0x200 | 0xbc},  // 'ヨ'
438         {0xd7,  0x200 | 0xbd},  // 'ラ'
439         {0xd8,  0x200 | 0xde},  // 'リ'
440         {0xd9,  0x200 | 0xdc},  // 'ル'
441         {0xda,  0x200 | 0xc0},  // 'レ'
442         {0xdb,  0x200 | 0xdb},  // 'ロ'
443         {0xdc,  0x200 | 0xbe},  // 'ワ'
444         {0xdd,  0x200 | 0xe2},  // 'ン'
445         {0xde,  0x200 | 0xba},  // '゙'
446         {0xdf,  0x200 | 0xdd},  // '゚'
447         {-1, -1},
448 };
449
450 void EmuThreadClassBase::do_start_auto_key(QString ctext)
451 {
452         //QMutexLocker _locker(&uiMutex);
453
454         if(using_flags->is_use_auto_key()) {
455                 QTextCodec *codec = QTextCodec::codecForName("Shift-Jis");
456                 QByteArray array;
457                 QVector<uint> ucs4_src = ctext.toUcs4();
458                 QString dst;
459                 dst.clear();
460                 uint32_t pool[8] = {0};
461                 for(auto itr = ucs4_src.constBegin(); itr != ucs4_src.constEnd(); ++itr) {
462                         uint val = (*itr);
463                         int chrs = ucs4_kana_zenkaku_to_hankaku((const uint32_t)val, pool, sizeof(pool) / sizeof(uint32_t));
464                         if(chrs > 0) {
465                 #if QT_VERSION >= 0x060000
466                                 dst.append(QString::fromUcs4((char32_t*)pool, chrs));
467                 #else
468                                 dst.append(QString::fromUcs4((uint*)pool, chrs));
469                 #endif
470                         }
471                 }
472                 clipBoardText = dst;
473                 //printf("%s\n", clipBoardText.toLocal8Bit().constData());
474                 array = codec->fromUnicode(clipBoardText);
475                 //printf("Array is:");
476                 //for(int l = 0; l < array.size(); l++) {
477                 //      printf("%02X ", array.at(l));
478                 //}
479                 //printf("\n");
480                 if(clipBoardText.size() > 0) {
481                         int size = array.size();
482                         const char *buf = (char *)(array.constData());
483                         p_emu->stop_auto_key();
484                         p_emu->set_auto_key_list((char *)buf, size);
485                         p_emu->start_auto_key();
486                 }
487         }
488
489 }
490
491 void EmuThreadClassBase::do_stop_auto_key(void)
492 {
493         //QMutexLocker _locker(&uiMutex);
494         //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL,
495         //                                        "AutoKey: stop\n");
496         if(using_flags->is_use_auto_key()) {
497                 p_emu->stop_auto_key();
498         }
499 }
500
501 void EmuThreadClassBase::do_write_protect_floppy_disk(int drv, bool flag)
502 {
503         //QMutexLocker _locker(&uiMutex);
504         std::shared_ptr<USING_FLAGS> p = using_flags;
505         if(p.get() == nullptr) return;
506         if((p->get_max_drive() > drv) && (p->is_use_fd())) {
507                 p_emu->is_floppy_disk_protected(drv, flag);
508         }
509 }
510
511 void EmuThreadClassBase::do_close_floppy_disk(int drv)
512 {
513         //QMutexLocker _locker(&uiMutex);
514         std::shared_ptr<USING_FLAGS> p = using_flags;
515         if(p.get() == nullptr) return;
516         if((p->get_max_drive() > drv) && (p->is_use_fd())) {
517                 p_emu->close_floppy_disk(drv);
518                 emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, drv, QString::fromUtf8(""));
519         }
520 }
521
522 void EmuThreadClassBase::do_open_floppy_disk(int drv, QString path, int bank)
523 {
524         if(path.isEmpty()) return;
525         if(path.isNull()) return;
526
527         std::shared_ptr<USING_FLAGS> p = using_flags;
528         if(p.get() == nullptr) return;
529         if(!(using_flags->is_use_fd())) return;
530         if(!((p->get_max_drive() > drv) && (p->is_use_fd()))) return;
531
532         const _TCHAR *file_path = (const _TCHAR *)(path.toLocal8Bit().constData());
533         if(!(FILEIO::IsFileExisting(file_path))) return; // File not found.
534
535         p_emu->open_floppy_disk(drv, file_path, bank);
536 }
537
538
539 void EmuThreadClassBase::do_select_floppy_disk_d88(int drive, int slot)
540 {
541         if(p_emu == nullptr) return;
542
543         int bank_num = p_emu->d88_file[drive].bank_num;
544         if(bank_num <= 0) return;
545
546         std::shared_ptr<USING_FLAGS>p = using_flags;
547         if(p.get() == nullptr) return;
548         if(p->get_max_d88_banks() <= slot) slot = p->get_max_d88_banks() - 1;
549         if(slot < 0) return;
550         if(bank_num <= slot) return;
551
552         if((p_emu->is_floppy_disk_inserted(drive)) &&
553            (slot != p_emu->d88_file[drive].cur_bank)) {
554                 QString path = get_d88_file_path(drive);
555                 do_open_floppy_disk(drive, path, slot);
556         }
557 }
558
559
560 void EmuThreadClassBase::do_play_tape(int drv, QString name)
561 {
562         if(p_emu == nullptr) return;
563         std::shared_ptr<USING_FLAGS>p = using_flags;
564         if(p.get() == nullptr) return;
565
566         if(p->is_use_tape()) {
567                 //QMutexLocker _locker(&uiMutex);
568                 p_emu->play_tape(drv, name.toLocal8Bit().constData());
569         }
570 }
571
572 void EmuThreadClassBase::do_rec_tape(int drv, QString name)
573 {
574         if(using_flags->is_use_tape()) {
575                 //QMutexLocker _locker(&uiMutex);
576                 p_emu->rec_tape(drv, name.toLocal8Bit().constData());
577                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drv, name);
578         }
579 }
580
581 void EmuThreadClassBase::do_close_tape(int drv)
582 {
583         if(using_flags->is_use_tape()) {
584                 //QMutexLocker _locker(&uiMutex);
585                 p_emu->close_tape(drv);
586                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drv, QString::fromUtf8(""));
587         }
588 }
589
590 void EmuThreadClassBase::do_cmt_push_play(int drv)
591 {
592         if(using_flags->is_use_tape()) {
593                 //QMutexLocker _locker(&uiMutex);
594                 p_emu->push_play(drv);
595         }
596 }
597
598 void EmuThreadClassBase::do_cmt_push_stop(int drv)
599 {
600         if(using_flags->is_use_tape()) {
601                 //QMutexLocker _locker(&uiMutex);
602                 p_emu->push_stop(drv);
603         }
604 }
605
606 void EmuThreadClassBase::do_cmt_push_fast_forward(int drv)
607 {
608         if(using_flags->is_use_tape()) {
609                 //QMutexLocker _locker(&uiMutex);
610                 p_emu->push_fast_forward(drv);
611         }
612 }
613
614 void EmuThreadClassBase::do_cmt_push_fast_rewind(int drv)
615 {
616         if(using_flags->is_use_tape()) {
617                 //QMutexLocker _locker(&uiMutex);
618                 p_emu->push_fast_rewind(drv);
619         }
620 }
621
622 void EmuThreadClassBase::do_cmt_push_apss_forward(int drv)
623 {
624         if(using_flags->is_use_tape()) {
625                 ////QMutexLocker _locker(&uiMutex);
626                 p_emu->push_apss_forward(drv);
627         }
628 }
629
630 void EmuThreadClassBase::do_cmt_push_apss_rewind(int drv)
631 {
632         if(using_flags->is_use_tape()) {
633                 ////QMutexLocker _locker(&uiMutex);
634                 p_emu->push_apss_rewind(drv);
635         }
636 }
637
638 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
639 void EmuThreadClassBase::done_open_tape(int drive, QString path)
640 {
641         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
642
643         if(!(using_flags->is_use_tape())) return;
644         if((drive < 0) || (drive >= using_flags->get_max_tape())) return;
645
646         QStringList list;
647         _TCHAR path_shadow[_MAX_PATH] = {0};
648         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
649         UPDATE_HISTORY(path_shadow, p_config->recent_tape_path[drive], list);
650
651         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
652         strncpy(p_config->initial_tape_dir, __dir, _MAX_PATH - 1);
653
654         QString relpath = QString::fromUtf8("");
655         if(strlen(&(__dir[0])) > 1) {
656                 relpath = QString::fromLocal8Bit(&(__dir[1]));
657         }
658         emit sig_ui_update_tape_list(drive, list);
659         emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drive, relpath);
660 }
661 void EmuThreadClassBase::done_close_tape(int drive)
662 {
663         emit sig_ui_close_tape(drive);
664         emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drive, QString::fromUtf8(""));
665 }
666
667 void EmuThreadClassBase::do_write_protect_quickdisk(int drv, bool flag)
668 {
669         if(using_flags->is_use_qd()) {
670                 ////QMutexLocker _locker(&uiMutex);
671                 //p_emu->write_protect_Qd(drv, flag);
672         }
673 }
674
675 void EmuThreadClassBase::do_close_quickdisk(int drv)
676 {
677         if(using_flags->is_use_qd()) {
678                 //QMutexLocker _locker(&uiMutex);
679                 p_emu->close_quick_disk(drv);
680                 emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drv, QString::fromUtf8(""));
681         }
682 }
683
684 void EmuThreadClassBase::do_open_quickdisk(int drv, QString path)
685 {
686         if(using_flags->is_use_qd()) {
687                 //QMutexLocker _locker(&uiMutex);
688                 p_emu->open_quick_disk(drv, path.toLocal8Bit().constData());
689                 emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drv, path);
690         }
691 }
692 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
693 void EmuThreadClassBase::done_open_quick_disk(int drive, QString path)
694 {
695         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
696
697         if(!(using_flags->is_use_qd())) return;
698         if((drive < 0) || (drive >= using_flags->get_max_qd())) return;
699
700         QStringList list;
701         _TCHAR path_shadow[_MAX_PATH] = {0};
702         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
703         UPDATE_HISTORY(path_shadow, p_config->recent_quick_disk_path[drive], list);
704         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
705         strncpy(p_config->initial_quick_disk_dir, __dir, _MAX_PATH - 1);
706
707         QString relpath = QString::fromUtf8("");
708         if(strlen(&(__dir[0])) > 1) {
709                 relpath = QString::fromLocal8Bit(&(__dir[1]));
710         }
711         emit sig_ui_update_quick_disk_list(drive, list);
712         emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drive, relpath);
713 }
714 void EmuThreadClassBase::done_close_quick_disk(int drive)
715 {
716         emit sig_ui_close_quick_disk(drive);
717         emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drive, QString::fromUtf8(""));
718 }
719
720 void EmuThreadClassBase::do_open_cdrom(int drv, QString path)
721 {
722         if(using_flags->is_use_compact_disc()) {
723                 //QMutexLocker _locker(&uiMutex);
724                 p_emu->open_compact_disc(drv, path.toLocal8Bit().constData());
725                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drv, path);
726         }
727 }
728 void EmuThreadClassBase::do_eject_cdrom(int drv)
729 {
730         if(using_flags->is_use_compact_disc()) {
731                 //QMutexLocker _locker(&uiMutex);
732                 p_emu->close_compact_disc(drv);
733                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drv, QString::fromUtf8(""));
734         }
735 }
736 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
737 void EmuThreadClassBase::done_open_compact_disc(int drive, QString path)
738 {
739         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
740
741         if(!(using_flags->is_use_compact_disc())) return;
742         if((drive < 0) || (drive >= using_flags->get_max_cd())) return;
743
744         QStringList list;
745         _TCHAR path_shadow[_MAX_PATH] = {0};
746         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
747         UPDATE_HISTORY(path_shadow, p_config->recent_compact_disc_path[drive], list);
748
749         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
750         strncpy(p_config->initial_compact_disc_dir, __dir, _MAX_PATH - 1);
751
752         QString relpath = QString::fromUtf8("");
753         if(strlen(&(__dir[0])) > 1) {
754                 relpath = QString::fromLocal8Bit(&(__dir[1]));
755         }
756         emit sig_ui_update_compact_disc_list(drive, list);
757         emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drive, relpath);
758 }
759 void EmuThreadClassBase::done_close_compact_disc(int drive)
760 {
761         emit sig_ui_close_compact_disc(drive);
762         emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drive, QString::fromUtf8(""));
763 }
764
765 void EmuThreadClassBase::do_close_hard_disk(int drv)
766 {
767         if(using_flags->is_use_hdd()) {
768                 //QMutexLocker _locker(&uiMutex);
769                 p_emu->close_hard_disk(drv);
770                 emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, QString::fromUtf8(""));
771         }
772 }
773
774 void EmuThreadClassBase::do_open_hard_disk(int drv, QString path)
775 {
776         if(using_flags->is_use_hdd()) {
777                 //QMutexLocker _locker(&uiMutex);
778                 p_emu->open_hard_disk(drv, path.toLocal8Bit().constData());
779                 emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, path);
780         }
781 }
782 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
783 void EmuThreadClassBase::done_open_hard_disk(int drive, QString path)
784 {
785         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
786
787         if(!(using_flags->is_use_hdd())) return;
788         if((drive < 0) || (drive >= using_flags->get_max_hdd())) return;
789
790         QStringList list;
791         _TCHAR path_shadow[_MAX_PATH] = {0};
792         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
793         UPDATE_HISTORY(path_shadow, p_config->recent_hard_disk_path[drive], list);
794
795         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
796         strncpy(p_config->initial_hard_disk_dir, __dir, _MAX_PATH - 1);
797
798         QString relpath = QString::fromUtf8("");
799         if(strlen(&(__dir[0])) > 1) {
800                 relpath = QString::fromLocal8Bit(&(__dir[1]));
801         }
802         emit sig_ui_update_hard_disk_list(drive, list);
803         emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drive, relpath);
804 }
805 void EmuThreadClassBase::done_close_hard_disk(int drive)
806 {
807         emit sig_ui_close_hard_disk(drive);
808         emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drive, QString::fromUtf8(""));
809 }
810
811 void EmuThreadClassBase::do_close_cart(int drv)
812 {
813         if(using_flags->is_use_cart()) {
814                 //QMutexLocker _locker(&uiMutex);
815                 p_emu->close_cart(drv);
816                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drv, QString::fromUtf8(""));
817         }
818 }
819
820 void EmuThreadClassBase::do_open_cart(int drv, QString path)
821 {
822         if(using_flags->is_use_cart()) {
823                 //QMutexLocker _locker(&uiMutex);
824                 p_emu->open_cart(drv, path.toLocal8Bit().constData());
825                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drv, path);
826         }
827 }
828
829 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
830 void EmuThreadClassBase::done_open_cart(int drive, QString path)
831 {
832         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
833
834         if(!(using_flags->is_use_cart())) return;
835         if((drive < 0) || (drive >= using_flags->get_max_cart())) return;
836
837         QStringList list;
838         _TCHAR path_shadow[_MAX_PATH] = {0};
839         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
840         UPDATE_HISTORY(path_shadow, p_config->recent_cart_path[drive], list);
841
842         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
843         strncpy(p_config->initial_cart_dir, __dir, _MAX_PATH - 1);
844
845         QString relpath = QString::fromUtf8("");
846         if(strlen(&(__dir[0])) > 1) {
847                 relpath = QString::fromLocal8Bit(&(__dir[1]));
848         }
849         emit sig_ui_update_cart_list(drive, list);
850         emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drive, relpath);
851 }
852 void EmuThreadClassBase::done_close_cart(int drive)
853 {
854         emit sig_ui_close_cart(drive);
855         emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drive, QString::fromUtf8(""));
856 }
857
858 void EmuThreadClassBase::do_close_laser_disc(int drv)
859 {
860         if(using_flags->is_use_laser_disc()) {
861                 //QMutexLocker _locker(&uiMutex);
862                 p_emu->close_laser_disc(drv);
863                 emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drv, QString::fromUtf8(""));
864         }
865 }
866
867 void EmuThreadClassBase::do_open_laser_disc(int drv, QString path)
868 {
869         if(using_flags->is_use_laser_disc()) {
870                 //QMutexLocker _locker(&uiMutex);
871                 p_emu->open_laser_disc(drv, path.toLocal8Bit().constData());
872                 emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drv, path);
873         }
874 }
875 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
876 void EmuThreadClassBase::done_open_laser_disc(int drive, QString path)
877 {
878         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
879
880         if(!(using_flags->is_use_laser_disc())) return;
881         if((drive < 0) || (drive >= using_flags->get_max_ld())) return;
882
883         QStringList list;
884         _TCHAR path_shadow[_MAX_PATH] = {0};
885         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
886         UPDATE_HISTORY(path_shadow, p_config->recent_laser_disc_path[drive], list);
887
888         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
889         strncpy(p_config->initial_laser_disc_dir, __dir, _MAX_PATH - 1);
890
891         QString relpath = QString::fromUtf8("");
892         if(strlen(&(__dir[0])) > 1) {
893                 relpath = QString::fromLocal8Bit(&(__dir[1]));
894         }
895         emit sig_ui_update_laser_disc_list(drive, list);
896         emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drive, relpath);
897 }
898 void EmuThreadClassBase::done_close_laser_disc(int drive)
899 {
900         emit sig_ui_close_laser_disc(drive);
901         emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drive, QString::fromUtf8(""));
902 }
903
904 void EmuThreadClassBase::do_load_binary(int drv, QString path)
905 {
906         if(using_flags->is_use_binary_file()) {
907                 //QMutexLocker _locker(&uiMutex);
908                 p_emu->load_binary(drv, path.toLocal8Bit().constData());
909                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drv, path);
910         }
911 }
912
913 void EmuThreadClassBase::do_save_binary(int drv, QString path)
914 {
915         if(using_flags->is_use_binary_file()) {
916                 //QMutexLocker _locker(&uiMutex);
917                 p_emu->save_binary(drv, path.toLocal8Bit().constData());
918                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drv, QString::fromUtf8(""));
919         }
920 }
921
922 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
923 void EmuThreadClassBase::done_open_binary(int drive, QString path)
924 {
925         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
926
927         if(!(using_flags->is_use_binary_file())) return;
928         if((drive < 0) || (drive >= using_flags->get_max_binary())) return;
929
930         QStringList list;
931         _TCHAR path_shadow[_MAX_PATH] = {0};
932         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
933         UPDATE_HISTORY(path_shadow, p_config->recent_binary_path[drive], list);
934         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
935         strncpy(p_config->initial_binary_dir, __dir, _MAX_PATH - 1);
936
937         QString relpath = QString::fromUtf8("");
938         if(strlen(&(__dir[0])) > 1) {
939                 relpath = QString::fromLocal8Bit(&(__dir[1]));
940         }
941         emit sig_ui_update_binary_list(drive, list);
942         emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drive, relpath);
943 }
944 void EmuThreadClassBase::done_close_binary(int drive)
945 {
946         emit sig_ui_close_binary(drive);
947         emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drive, QString::fromUtf8(""));
948 }
949
950 void EmuThreadClassBase::do_write_protect_bubble_casette(int drv, bool flag)
951 {
952         if(using_flags->is_use_bubble()) {
953                 //QMutexLocker _locker(&uiMutex);
954                 p_emu->is_bubble_casette_protected(drv, flag);
955         }
956 }
957
958 void EmuThreadClassBase::do_close_bubble_casette(int drv)
959 {
960         if(using_flags->is_use_bubble()) {
961                 //QMutexLocker _locker(&uiMutex);
962                 p_emu->close_bubble_casette(drv);
963                 p_emu->b77_file[drv].bank_num = 0;
964                 p_emu->b77_file[drv].cur_bank = -1;
965 //              emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drv, QString::fromUtf8(""));
966         }
967 }
968
969 void EmuThreadClassBase::do_open_bubble_casette(int drv, QString path, int bank)
970 {
971         if(!(using_flags->is_use_bubble())) return;
972
973         //QMutexLocker _locker(&uiMutex);
974         QByteArray localPath = path.toLocal8Bit();
975
976         p_emu->b77_file[drv].bank_num = 0;
977         p_emu->b77_file[drv].cur_bank = -1;
978
979         if(check_file_extension(localPath.constData(), ".b77")) {
980
981                 FILEIO *fio = new FILEIO();
982                 if(fio->Fopen(localPath.constData(), FILEIO_READ_BINARY)) {
983                         try {
984                                 fio->Fseek(0, FILEIO_SEEK_END);
985                                 int file_size = fio->Ftell(), file_offset = 0;
986                                 while(file_offset + 0x2b0 <= file_size && p_emu->b77_file[drv].bank_num < using_flags->get_max_b77_banks()) {
987                                         fio->Fseek(file_offset, FILEIO_SEEK_SET);
988                                         char tmp[18];
989                                         memset(tmp, 0x00, sizeof(tmp));
990                                         fio->Fread(tmp, 16, 1);
991                                         memset(p_emu->b77_file[drv].bubble_name[p_emu->b77_file[drv].bank_num], 0x00, 128);
992                                         if(strlen(tmp) > 0) Convert_CP932_to_UTF8(p_emu->b77_file[drv].bubble_name[p_emu->b77_file[drv].bank_num], tmp, 127, 17);
993
994                                         fio->Fseek(file_offset + 0x1c, FILEIO_SEEK_SET);
995                                         file_offset += fio->FgetUint32_LE();
996                                         p_emu->b77_file[drv].bank_num++;
997                                 }
998                                 strcpy(p_emu->b77_file[drv].path, path.toUtf8().constData());
999                                 if(bank >= p_emu->b77_file[drv].bank_num) bank = p_emu->b77_file[drv].bank_num - 1;
1000                                 if(bank < 0) bank = 0;
1001                                 p_emu->b77_file[drv].cur_bank = bank;
1002                         }
1003                         catch(...) {
1004                                 bank = 0;
1005                                 p_emu->b77_file[drv].bank_num = 0;
1006                         }
1007                         fio->Fclose();
1008                 }
1009                 delete fio;
1010         } else {
1011            bank = 0;
1012         }
1013         p_emu->open_bubble_casette(drv, localPath.constData(), bank);
1014         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drv, path);
1015         emit sig_update_recent_bubble(drv);
1016
1017 }
1018 // Signal from EMU:: -> OSD:: -> EMU_THREAD (-> GUI)
1019 void EmuThreadClassBase::done_open_bubble(int drive, QString path)
1020 {
1021         if((using_flags.get() == nullptr) || (p_config == nullptr)) return;
1022
1023         if(!(using_flags->is_use_bubble())) return;
1024         if((drive < 0) || (drive >= using_flags->get_max_bubble())) return;
1025
1026         QStringList list;
1027         _TCHAR path_shadow[_MAX_PATH] = {0};
1028         strncpy(path_shadow, path.toLocal8Bit().constData(), _MAX_PATH - 1);
1029         UPDATE_HISTORY(path_shadow, p_config->recent_bubble_casette_path[drive], list);
1030
1031         const _TCHAR* __dir = get_parent_dir((const _TCHAR *)path_shadow);
1032         strncpy(p_config->initial_bubble_casette_dir, __dir, _MAX_PATH - 1);
1033
1034         emit sig_ui_update_bubble_casette_list(drive, list);
1035         emit sig_ui_clear_b77(drive);
1036
1037         QString relpath = QString::fromUtf8("");
1038         if(strlen(&(__dir[0])) > 1) {
1039                 relpath = QString::fromLocal8Bit(&(__dir[1]));
1040         }
1041         bool _f = check_file_extension(path_shadow, ".b77");
1042         if(_f) {
1043                 if(p_emu != nullptr) {
1044                         int slot = p_emu->b77_file[drive].cur_bank;
1045                         for(int i = 0; i < p_emu->b77_file[drive].bank_num; i++) {
1046                                 if(i >= 16) break;
1047                                 _TCHAR tmpname[128] = {0};
1048                                 my_strcpy_s(tmpname, 127, p_emu->b77_file[drive].bubble_name[i]);
1049                                 QString tmps = QString::fromLocal8Bit(tmpname);
1050                                 emit sig_ui_update_b77(drive, i, tmps);
1051                                 if(i == slot) {
1052                                         emit sig_ui_select_b77(drive, i);
1053                                         relpath = tmps;
1054                                 }
1055                         }
1056                 }
1057         }
1058         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drive, relpath);
1059 }
1060
1061 void EmuThreadClassBase::done_close_bubble(int drive)
1062 {
1063         emit sig_ui_close_bubble_casette(drive);
1064         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drive, QString::fromUtf8(""));
1065 }
1066
1067 void EmuThreadClassBase::done_select_b77(int drive, int slot)
1068 {
1069         if(p_emu == nullptr) return;
1070
1071         if(slot < 0) return;
1072         if(slot >= 16) return;
1073         if(p_emu->b77_file[drive].bank_num < 0) return;
1074         if(p_emu->b77_file[drive].bank_num >= 64) return;
1075         if(p_emu->b77_file[drive].bank_num <= slot) return;
1076         p_emu->b77_file[drive].cur_bank = slot;
1077         _TCHAR tmpname[128] = {0};
1078         my_strcpy_s(tmpname, 127, p_emu->b77_file[drive].bubble_name[slot]);
1079         QString tmps = QString::fromLocal8Bit(tmpname);
1080         emit sig_ui_select_b77(drive, slot);
1081         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drive, tmps);
1082 }
1083
1084 // Debugger
1085
1086 void EmuThreadClassBase::do_close_debugger(void)
1087 {
1088         if(using_flags->is_use_debugger()) {
1089                 emit sig_quit_debugger();
1090         }
1091 }
1092
1093 void EmuThreadClassBase::set_romakana(bool flag)
1094 {
1095         if(using_flags->is_use_auto_key()) {
1096                 p_emu->set_auto_key_char(flag ? 1 : 0);
1097         }
1098 }
1099
1100 void EmuThreadClassBase::moved_mouse(double x, double y, double globalx, double globaly)
1101 {
1102         if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
1103                 mouse_x = x;
1104                 mouse_y = y;
1105 //              bool flag = p_osd->is_mouse_enabled();
1106 //              if(!flag) return;
1107 //              printf("Mouse Moved: %g, %g\n", x, y);
1108 //              p_osd->set_mouse_pointer(floor(x), floor(y));
1109         } else if(using_flags->is_use_mouse()) {
1110 //              double factor = (double)(p_config->mouse_sensitivity & ((1 << 16) - 1));
1111 //              mouse_x = (int)(floor((globalx * factor) / 8192.0));
1112 //              mouse_y = (int)(floor((globaly * factor) / 8192.0));
1113                 mouse_x = globalx;
1114                 mouse_y = globaly;
1115                 //printf("Moved Mouse %d, %d\n", x, y);
1116                 bool flag = p_osd->is_mouse_enabled();
1117                 if(!flag) return;
1118                 //printf("Mouse Moved: %d, %d\n", x, y);
1119                 p_osd->set_mouse_pointer(mouse_x, mouse_y);
1120         }
1121 }
1122
1123 void EmuThreadClassBase::button_pressed_mouse_sub(Qt::MouseButton button)
1124 {
1125
1126         if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) {
1127                 int stat = p_osd->get_mouse_button();
1128                 bool flag = (p_osd->is_mouse_enabled() || using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0));
1129                 switch(button) {
1130                 case Qt::LeftButton:
1131                         stat |= 0x01;
1132                         break;
1133                 case Qt::RightButton:
1134                         stat |= 0x02;
1135                         break;
1136                 case Qt::MiddleButton:
1137                         flag = !flag;
1138                         emit sig_mouse_enable(flag);
1139                         return;
1140                         break;
1141                 default:
1142                         break;
1143                 }
1144                 if(!flag) return;
1145                 p_osd->set_mouse_button(stat);
1146         }
1147 }
1148
1149 void EmuThreadClassBase::button_released_mouse_sub(Qt::MouseButton button)
1150 {
1151
1152         if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) {
1153                 int stat = p_osd->get_mouse_button();
1154                 switch(button) {
1155                 case Qt::LeftButton:
1156                         stat &= 0x7ffffffe;
1157                         break;
1158                 case Qt::RightButton:
1159                         stat &= 0x7ffffffd;
1160                         break;
1161                 case Qt::MiddleButton:
1162                         //emit sig_mouse_enable(false);
1163                         break;
1164                 default:
1165                         break;
1166                 }
1167                 p_osd->set_mouse_button(stat);
1168         }
1169 }
1170
1171 void EmuThreadClassBase::do_notify_power_off()
1172 {
1173         poweroff_notified = true;
1174 }
1175
1176 void EmuThreadClassBase::do_set_display_size(int w, int h, int ww, int wh)
1177 {
1178         p_emu->suspend();
1179         p_emu->set_host_window_size(w, h, true);
1180 }
1181
1182 void EmuThreadClassBase::dec_message_count(void)
1183 {
1184         p_emu->message_count--;
1185 }