OSDN Git Service

キーボード関連の構造体化
[heavyosecpu/HeavyOSECPU.git] / dpndenv.c
1 #include "osecpu.h"\r
2 \r
3 \r
4 #if (DRV_OSNUM == 0x0002)\r
5 //\r
6 // for Mac OSX 32-bit\r
7 //\r
8 #include <mach/mach.h>\r
9 #include <Cocoa/Cocoa.h>\r
10 \r
11 @interface OSECPUView : NSView\r
12 {\r
13         unsigned char *_buf;\r
14         int _sx;\r
15         int _sy;\r
16         CGContextRef _context;\r
17 }\r
18 \r
19 - (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy;\r
20 - (void)drawRect:(NSRect)rect;\r
21 @end\r
22 \r
23 @implementation OSECPUView\r
24 - (id)initWithFrame:(NSRect)frameRect buf:(unsigned char *)buf sx:(int)sx sy:(int)sy\r
25 {\r
26         self = [super initWithFrame:frameRect];\r
27         if (self) {\r
28                 _buf = buf;\r
29                 _sx = sx;\r
30                 _sy = sy;\r
31         }\r
32         return self;\r
33 }\r
34 \r
35 - (void)drawRect:(NSRect)rect {\r
36         CGColorSpaceRef colorSpace;\r
37         CGImageRef image;\r
38         CGContextRef currentContext;\r
39         \r
40         currentContext = [[NSGraphicsContext currentContext] graphicsPort];\r
41         colorSpace= CGColorSpaceCreateDeviceRGB();\r
42         \r
43         // ビットマップコンテキストにvramイメージを生成\r
44         _context = CGBitmapContextCreate (_buf, _sx, _sy, 8, 4 * _sx, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst));\r
45         image = CGBitmapContextCreateImage(_context);\r
46         \r
47         // 生成したvramイメージをViewに描画\r
48         CGContextDrawImage(currentContext, NSRectToCGRect(rect), image);\r
49         \r
50         // メモリ解放\r
51         CFRelease(colorSpace);\r
52         CFRelease(image);\r
53 }\r
54 \r
55 - (void)keyDown:(NSEvent *)theEvent\r
56 {\r
57         int i, j;\r
58         unichar kc;\r
59         \r
60         if([[theEvent characters] length] != 1){\r
61                 return;\r
62         }\r
63         \r
64         kc = [[theEvent characters] characterAtIndex:0];\r
65         \r
66         // 通常キー\r
67         i = KEY_EMPTY;\r
68         if (kc == '\r') i = KEY_ENTER;\r
69         if (kc == 0x1b) i = KEY_ESC;\r
70         if (kc == 0x7F)         i = KEY_BACKSPACE;\r
71         if (kc == '\t')         i = KEY_TAB;\r
72         if (kc == NSPageUpFunctionKey)          i = KEY_PAGEUP;\r
73         if (kc == NSPageDownFunctionKey)                i = KEY_PAGEDWN;\r
74         if (kc == NSEndFunctionKey)             i = KEY_END;\r
75         if (kc == NSHomeFunctionKey)            i = KEY_HOME;\r
76         if (kc == NSLeftArrowFunctionKey)               i = KEY_LEFT;\r
77         if (kc == NSRightArrowFunctionKey)              i = KEY_RIGHT;\r
78         if (kc == NSUpArrowFunctionKey)         i = KEY_UP;\r
79         if (kc == NSDownArrowFunctionKey)               i = KEY_DOWN;\r
80         if (kc == NSInsertFunctionKey)  i = KEY_INS;\r
81         if (kc == NSDeleteFunctionKey)  i = KEY_DEL;\r
82         if (i == KEY_EMPTY && isascii(kc)){\r
83                 i = kc;\r
84         }\r
85         // 修飾キー\r
86         // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき?\r
87         j = 0;\r
88         /*\r
89         if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L;\r
90         if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L;\r
91         if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R;\r
92         if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R;\r
93         if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R;\r
94         if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L;\r
95         if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK;\r
96         if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL;\r
97          */\r
98         \r
99         // NSLog(@"%X", i);\r
100         if (i != -1) {\r
101                 putKeybuf(i | j);\r
102         }\r
103 }\r
104 /*\r
105 - (void)keyUp:(NSEvent *)theEvent\r
106 {\r
107         NSLog(@"kUp");\r
108 }\r
109  */\r
110 @end\r
111 \r
112 @interface Main : NSObject<NSWindowDelegate>\r
113 {\r
114         int argc;\r
115         const unsigned char **argv;\r
116         char *winClosed;\r
117         OSECPUView *_view;\r
118         NSWindow *mainWindow;\r
119         NSMenu *mainMenu;\r
120 }\r
121 \r
122 - (void)runApp;\r
123 - (void)createThread:(int)_argc args:(const unsigned char **)_argv;\r
124 - (BOOL)windowShouldClose:(id)sender;\r
125 - (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int)sy winClosed:(char *)_winClosed;\r
126 - (void)flushWin:(NSRect)rect;\r
127 @end\r
128 \r
129 @implementation Main\r
130 - (void)runApp\r
131 {\r
132         // Sub thread\r
133         NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];\r
134         int retv;\r
135         retv = HeavyOSECPUMain(argc, (char **)argv);\r
136         [NSApp terminate:self];\r
137         [pool release];\r
138         exit(retv);\r
139 }\r
140 \r
141 - (void)createThread : (int)_argc args:(const unsigned char **)_argv\r
142 {\r
143         argc = _argc;\r
144         argv = _argv;\r
145         NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(runApp) object:nil] autorelease];\r
146         [thread start];\r
147 }\r
148 \r
149 - (BOOL)windowShouldClose:(id)sender\r
150 {\r
151         *winClosed = 1;\r
152         return YES;\r
153 }\r
154 \r
155 - (void)windowDidBecomeKey:(NSNotification *)notification\r
156 {\r
157         [mainWindow makeFirstResponder:_view];\r
158 }\r
159 \r
160 - (void)openWin:(unsigned char *)buf sx:(int)sx sy:(int) sy winClosed:(char *)_winClosed\r
161 {\r
162         mainWindow = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, sx, sy) styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask backing: NSBackingStoreBuffered defer: NO];\r
163         mainWindow.delegate = self;\r
164         [mainWindow setTitle: @"osecpu"];\r
165         [mainWindow center];\r
166         [mainWindow makeKeyAndOrderFront:self];\r
167         [mainWindow setReleasedWhenClosed:YES];\r
168         \r
169         winClosed = _winClosed;\r
170         \r
171         _view = [[OSECPUView alloc] initWithFrame:NSMakeRect(0,0,sx,sy) buf:buf sx:sx sy:sy];\r
172         [mainWindow.contentView addSubview:_view];\r
173 }\r
174 \r
175 - (void)flushWin : (NSRect)rect\r
176 {\r
177         [_view setNeedsDisplayInRect:rect];\r
178 }\r
179 \r
180 @end\r
181 \r
182 id objc_main;\r
183 \r
184 int main(int argc, char **argv)\r
185 {\r
186         // Main thread\r
187         NSAutoreleasePool* pool;\r
188         ProcessSerialNumber psn = {0, kCurrentProcess};\r
189         \r
190         // ForegroundApplicationになれるように設定(こうしないとキーイベントが取得できない)\r
191         TransformProcessType(&psn, kProcessTransformToForegroundApplication);\r
192                 \r
193         objc_main = [[Main alloc] init];\r
194         NSApp = [NSApplication sharedApplication];\r
195         \r
196         pool = [[NSAutoreleasePool alloc] init];\r
197         [objc_main createThread:argc args:(const unsigned char **)argv];\r
198         [NSApp run];\r
199         [pool release];\r
200         return 0;\r
201 }\r
202 \r
203 void *mallocRWE(int bytes)\r
204 {\r
205         void *p = malloc(bytes);\r
206         vm_protect(mach_task_self(), (vm_address_t) p, bytes, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);\r
207         return p;\r
208 }\r
209 \r
210 void drv_openWin(int sx, int sy, unsigned char *buf, char *winClosed)\r
211 {\r
212         [objc_main openWin:buf sx:sx sy:sy winClosed:winClosed];\r
213 }\r
214 \r
215 void drv_flshWin(int sx, int sy, int x0, int y0)\r
216 {\r
217         [objc_main flushWin:NSMakeRect(x0,y0,sx,sy)];\r
218 }\r
219 \r
220 void drv_sleep(int msec)\r
221 {\r
222         [NSThread sleepForTimeInterval:0.001*msec];\r
223         return;\r
224 }\r
225 \r
226 \r
227 #elif (DRV_OSNUM == 0x0003)\r
228 \r
229 #error "Your OS is not supported."\r
230 \r
231 #elif (DRV_OSNUM == 0x0001)\r
232 //\r
233 // for Windows 32-bit\r
234 //\r
235 #include <windows.h>\r
236 \r
237 #define TIMER_ID                         1\r
238 #define TIMER_INTERVAL          10\r
239 \r
240 struct BLD_WORK {\r
241         HINSTANCE hi;\r
242         HWND hw;\r
243         BITMAPINFO bmi;\r
244         int tmcount1, tmcount2, flags, smp; /* bit0: 終了 */\r
245         HANDLE mtx;\r
246         char *winClosed;\r
247 };\r
248 \r
249 struct BLD_WORK bld_work;\r
250 \r
251 struct BL_WIN {\r
252         int xsiz, ysiz, *buf;\r
253 };\r
254 \r
255 struct BL_WORK {\r
256         struct BL_WIN win;\r
257         jmp_buf jb;\r
258         int csiz_x, csiz_y, cx, cy, col0, col1, tabsiz, slctwin;\r
259         int tmcount, tmcount0, mod, rand_seed;\r
260         int *cbuf;\r
261         unsigned char *ftyp;\r
262         unsigned char **fptn;\r
263         int *ccol, *cbak;\r
264         int *kbuf, kbuf_rp, kbuf_wp, kbuf_c;\r
265 };\r
266 \r
267 struct BL_WORK bl_work;\r
268 \r
269 #define BL_SIZ_KBUF                     8192\r
270 \r
271 #define BL_WAITKEYF             0x00000001\r
272 #define BL_WAITKEYNF    0x00000002\r
273 #define BL_WAITKEY              0x00000003\r
274 #define BL_GETKEY               0x00000004\r
275 #define BL_CLEARREP             0x00000008\r
276 #define BL_DELFFF               0x00000010\r
277 \r
278 #define BL_KEYMODE              0x00000000      // 作りかけ, make/remake/breakが見えるかどうか\r
279 \r
280 #define w       bl_work\r
281 #define dw      bld_work\r
282 \r
283 void bld_openWin(int x, int y, char *winClosed);\r
284 void bld_flshWin(int sx, int sy, int x0, int y0);\r
285 LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp);\r
286 void bl_cls();\r
287 int bl_iCol(int i);\r
288 void bl_readyWin(int n);\r
289 \r
290 static HANDLE threadhandle;\r
291 \r
292 int main(int argc, char **argv)\r
293 {\r
294         // Program entry point\r
295         return HeavyOSECPUMain(argc, argv);\r
296 }\r
297 \r
298 void *mallocRWE(int bytes)\r
299 {\r
300         void *p = malloc(bytes);\r
301         DWORD dmy;\r
302         VirtualProtect(p, bytes, PAGE_EXECUTE_READWRITE, &dmy);\r
303         return p;\r
304 }\r
305 \r
306 static int winthread(void *dmy)\r
307 {\r
308         WNDCLASSEX wc;\r
309         RECT r;\r
310         int i, x, y;\r
311         MSG msg;\r
312         \r
313         x = dw.bmi.bmiHeader.biWidth;\r
314         y = -dw.bmi.bmiHeader.biHeight;\r
315         \r
316         wc.cbSize = sizeof (WNDCLASSEX);\r
317         wc.style = CS_HREDRAW | CS_VREDRAW;\r
318         wc.lpfnWndProc = WndProc;\r
319         wc.cbClsExtra = 0;\r
320         wc.cbWndExtra = 0;\r
321         wc.hInstance = dw.hi;\r
322         wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),\r
323                                                                 IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
324         wc.hIconSm = wc.hIcon;\r
325         wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),\r
326                                                                         IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
327         wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;\r
328         wc.lpszMenuName = NULL;\r
329         wc.lpszClassName = "WinClass";\r
330         if (RegisterClassEx(&wc) == 0)\r
331                 return 1;\r
332         r.left = 0;\r
333         r.top = 0;\r
334         r.right = x;\r
335         r.bottom = y;\r
336         AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);\r
337         x = r.right - r.left;\r
338         y = r.bottom - r.top;\r
339         \r
340         char *t = "osecpu";\r
341         \r
342         dw.hw = CreateWindowA("WinClass", t, WS_OVERLAPPEDWINDOW,\r
343                                                   CW_USEDEFAULT, CW_USEDEFAULT, x, y, NULL, NULL, dw.hi, NULL);\r
344         if (dw.hw == NULL)\r
345                 return 1;\r
346         ShowWindow(dw.hw, SW_SHOW);\r
347         UpdateWindow(dw.hw);\r
348         SetTimer(dw.hw, TIMER_ID, TIMER_INTERVAL, NULL);\r
349         SetTimer(dw.hw, TIMER_ID + 1, TIMER_INTERVAL * 10, NULL);\r
350         SetTimer(dw.hw, TIMER_ID + 2, TIMER_INTERVAL * 100, NULL);\r
351         dw.flags |= 2 | 4;\r
352         \r
353         for (;;) {\r
354                 i = GetMessage(&msg, NULL, 0, 0);\r
355                 if (i == 0 || i == -1)  /* エラーもしくは終了メッセージ */\r
356                         break;\r
357                 /* そのほかはとりあえずデフォルト処理で */\r
358                 TranslateMessage(&msg);\r
359                 DispatchMessage(&msg);\r
360         }\r
361         //      PostQuitMessage(0);\r
362         dw.flags |= 1; /* 終了, bld_waitNF()が見つける */\r
363         if (dw.winClosed != NULL)\r
364                 *dw.winClosed = 1;\r
365         return 0;\r
366 }\r
367 \r
368 void bld_openWin(int sx, int sy, char *winClosed)\r
369 {\r
370         static int i;\r
371         \r
372         dw.bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);\r
373         dw.bmi.bmiHeader.biWidth = sx;\r
374         dw.bmi.bmiHeader.biHeight = -sy;\r
375         dw.bmi.bmiHeader.biPlanes = 1;\r
376         dw.bmi.bmiHeader.biBitCount = 32;\r
377         dw.bmi.bmiHeader.biCompression = BI_RGB;\r
378         dw.winClosed = winClosed;\r
379         \r
380         threadhandle = CreateThread(NULL, 0, (void *)&winthread, NULL, 0, (void *)&i);\r
381         \r
382         return;\r
383 }\r
384 \r
385 void drv_flshWin(int sx, int sy, int x0, int y0)\r
386 {\r
387         InvalidateRect(dw.hw, NULL, FALSE);\r
388         UpdateWindow(dw.hw);\r
389         return;\r
390 }\r
391 \r
392 LRESULT CALLBACK WndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)\r
393 {\r
394         int i, j;\r
395         if (msg == WM_PAINT) {\r
396                 PAINTSTRUCT ps;\r
397                 HDC hdc = BeginPaint(dw.hw, &ps);\r
398                 SetDIBitsToDevice(hdc, 0, 0, w.win.xsiz, w.win.ysiz,\r
399                                                   0, 0, 0, w.win.ysiz, w.win.buf, &dw.bmi, DIB_RGB_COLORS);\r
400                 EndPaint(dw.hw, &ps);\r
401         }\r
402         if (msg == WM_DESTROY) {\r
403                 PostQuitMessage(0);\r
404                 return 0;\r
405         }\r
406         if (msg == WM_TIMER && wp == TIMER_ID) {\r
407                 w.tmcount += TIMER_INTERVAL;\r
408                 return 0;\r
409         }\r
410         if (msg == WM_TIMER && wp == TIMER_ID + 1) {\r
411                 dw.tmcount1 += TIMER_INTERVAL * 10;\r
412                 w.tmcount = dw.tmcount1;\r
413                 return 0;\r
414         }\r
415         if (msg == WM_TIMER && wp == TIMER_ID + 2) {\r
416                 dw.tmcount2 += TIMER_INTERVAL * 100;\r
417                 w.tmcount = dw.tmcount1 = dw.tmcount2;\r
418                 return 0;\r
419         }\r
420         if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {\r
421                 // 通常キー\r
422                 i = KEY_EMPTY;\r
423                 if (wp == VK_RETURN)    i = KEY_ENTER;\r
424                 if (wp == VK_ESCAPE)    i = KEY_ESC;\r
425                 if (wp == VK_BACK)              i = KEY_BACKSPACE;\r
426                 if (wp == VK_TAB)               i = KEY_TAB;\r
427                 if (wp == VK_PRIOR)             i = KEY_PAGEUP;\r
428                 if (wp == VK_NEXT)              i = KEY_PAGEDWN;\r
429                 if (wp == VK_END)               i = KEY_END;\r
430                 if (wp == VK_HOME)              i = KEY_HOME;\r
431                 if (wp == VK_LEFT)              i = KEY_LEFT;\r
432                 if (wp == VK_RIGHT)             i = KEY_RIGHT;\r
433                 if (wp == VK_UP)                i = KEY_UP;\r
434                 if (wp == VK_DOWN)              i = KEY_DOWN;\r
435                 if (wp == VK_INSERT)    i = KEY_INS;\r
436                 if (wp == VK_DELETE)    i = KEY_DEL;\r
437                 // 修飾キー\r
438                 // TODO : 下の方の右辺、iとjが混ざっているのは修正すべき?\r
439                 j = 0;\r
440                 if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_L;\r
441                 if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_L;\r
442                 if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= KEY_MODIFIER_CONTROL_R;\r
443                 if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= KEY_MODIFIER_MENU_R;\r
444                 if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_R;\r
445                 if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= KEY_MODIFIER_SHIFT_L;\r
446                 if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= KEY_MODIFIER_NUMLOCK;\r
447                 if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= KEY_MODIFIER_CAPITAL;\r
448                 if (j != 0) {\r
449                         if ('A' <= wp && wp <= 'Z'){\r
450                                 i = wp;\r
451                         }\r
452                 }\r
453                 if (i != -1) {\r
454                         putKeybuf(i | j);\r
455                         return 0;\r
456                 }\r
457         }\r
458         if (msg == WM_KEYUP) {\r
459                 i = 0xfff;\r
460         }\r
461         if (msg == WM_CHAR) {\r
462                 i = 0;\r
463                 if (' ' <= wp && wp <= 0x7e) {\r
464                         i = wp;\r
465                         j &= 0;\r
466                         if ((GetKeyState(VK_LCONTROL) & (1 << 15)) != 0) j |= 1 << 17;\r
467                         if ((GetKeyState(VK_LMENU)    & (1 << 15)) != 0) j |= 1 << 18;\r
468                         if ((GetKeyState(VK_RCONTROL) & (1 << 15)) != 0) j |= 1 << 25;\r
469                         if ((GetKeyState(VK_RMENU)    & (1 << 15)) != 0) j |= 1 << 26;\r
470                         if ((GetKeyState(VK_RSHIFT)   & (1 << 15)) != 0) i |= 1 << 24;\r
471                         if ((GetKeyState(VK_LSHIFT)   & (1 << 15)) != 0) i |= 1 << 16;\r
472                         if ((GetKeyState(VK_NUMLOCK)  & (1 << 0)) != 0) i |= 1 << 22;\r
473                         if ((GetKeyState(VK_CAPITAL)  & (1 << 0)) != 0) i |= 1 << 23;\r
474                         if (('A' <= wp && wp <= 'Z') || ('a' <= wp && wp <= 'z')) {\r
475                                 if (j != 0) {\r
476                                         i |= j;\r
477                                         i &= ~0x20;\r
478                                 }\r
479                         }\r
480                         putKeybuf(i);\r
481                         return 0;\r
482                 }\r
483         }\r
484         return DefWindowProc(hw, msg, wp, lp);\r
485 }\r
486 \r
487 void drv_openWin(int sx, int sy, UCHAR *buf, char *winClosed)\r
488 {\r
489         w.win.buf = (int *)buf;\r
490         w.win.xsiz = sx;\r
491         w.win.ysiz = sy;\r
492         bld_openWin(sx, sy, winClosed);\r
493         return;\r
494 }\r
495 \r
496 void drv_sleep(int msec)\r
497 {\r
498         Sleep(msec);\r
499         //      MsgWaitForMultipleObjects(1, &threadhandle, FALSE, msec, QS_ALLINPUT);\r
500         /* 勉強不足でまだ書き方が分かりません! */\r
501         return;\r
502 }\r
503 \r
504 #else\r
505 \r
506 #error "Illegal OS type. Edit osecpu.h and look at DRV_OSNUM"\r
507 \r
508 #endif