1 /***********************************************************************
2 * ����ե��å����� (�����ƥ��¸)
3 *
4 * �ܺ٤ϡ� graph.h ����
5 ************************************************************************/
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "quasi88.h"
11 #include "graph.h"
12 #include "device.h"
13
14
15
16 HINSTANCE g_hInstance;
17 HWND g_hWnd;
18 HMENU g_hMenu;
19 int g_keyrepeat;
20
21
22
23 static T_GRAPH_SPEC graph_spec; /* ���ܾ��� */
24
25 static int graph_exist; /* ���ǡ����������Ѥ� */
26 static T_GRAPH_INFO graph_info; /* ���λ��Ρ����̾��� */
27
28
29 /************************************************************************
30 * ����ե��å������ν����
31 * ����ե��å�������ư��
32 * ����ե��å������ν�λ
33 ************************************************************************/
34
graph_init(void)35 const T_GRAPH_SPEC *graph_init(void)
36 {
37 if (verbose_proc) {
38 printf("Initializing Graphic System ... ");
39 }
40
41 graph_spec.window_max_width = 640;
42 graph_spec.window_max_height = 480;
43 graph_spec.fullscreen_max_width = 0;
44 graph_spec.fullscreen_max_height = 0;
45 graph_spec.forbid_status = FALSE;
46 graph_spec.forbid_half = FALSE;
47
48 if (verbose_proc)
49 printf("OK\n");
50
51 return &graph_spec;
52 }
53
54 /************************************************************************/
55
56 static DWORD winStyle;
57 static int create_window(int width, int height);
58 static void calc_window_size(int *width, int *height);
59
60 static unsigned char *buffer = NULL;
61 static BITMAPINFO bmpInfo;
62
graph_setup(int width,int height,int fullscreen,double aspect)63 const T_GRAPH_INFO *graph_setup(int width, int height,
64 int fullscreen, double aspect)
65 {
66 int win_width, win_height;
67
68 /* fullscreen, aspect ��̤���� */
69
70 /* ���ե������Хåե�����ݤ��� */
71
72 if (buffer) {
73 free(buffer);
74 }
75
76 buffer = malloc(width * height * sizeof(unsigned long));
77 if (buffer == FALSE) {
78 return NULL;
79 }
80
81 memset(&bmpInfo, 0, sizeof(bmpInfo));
82
83 bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
84 bmpInfo.bmiHeader.biWidth = width;
85 bmpInfo.bmiHeader.biHeight = - height;
86 bmpInfo.bmiHeader.biPlanes = 1;
87 bmpInfo.bmiHeader.biBitCount = 32;
88 bmpInfo.bmiHeader.biCompression = BI_RGB;
89
90
91 /* ������ɥ����������ʤ����ꥵ���� */
92
93 if (graph_exist == FALSE) { /* ������ɥ���̵��������� */
94
95 if (create_window(width, height) == FALSE) {
96 free(buffer);
97 buffer = NULL;
98 return NULL;
99 }
100
101 } else { /* ������ɥ���ͭ��Хꥵ���� */
102
103 win_width = width;
104 win_height = height;
105 calc_window_size(&win_width, &win_height);
106 SetWindowPos(g_hWnd,
107 HWND_TOP, 0, 0, /* ���ߡ�(̵�뤵���) */
108 win_width, win_height, /* ������ɥ��������⤵ */
109 SWP_NOMOVE | SWP_NOZORDER);
110 }
111
112 /* graph_info �˽����åȤ��� */
113
114 graph_info.fullscreen = FALSE;
115 graph_info.width = width;
116 graph_info.height = height;
117 graph_info.byte_per_pixel = 4;
118 graph_info.byte_per_line = width * 4;
119 graph_info.buffer = buffer;
120 graph_info.nr_color = 255;
121 graph_info.write_only = FALSE;
122 graph_info.broken_mouse = FALSE;
123 graph_info.draw_start = NULL;
124 graph_info.draw_finish = NULL;
125 graph_info.dont_frameskip = FALSE;
126
127 graph_exist = TRUE;
128
129 return &graph_info;
130 }
131
132
133
134 /*
135 * ������ɥ�����������
136 */
create_window(int width,int height)137 static int create_window(int width, int height)
138 {
139 WNDCLASSEX wc;
140 int win_width, win_height;
141
142 /* ������ɥ����饹�ξ�������� */
143 wc.cbSize = sizeof(wc); /* ��¤�Υ����� */
144 wc.style = 0; /* ������ɥ��������� */
145 wc.lpfnWndProc = WndProc; /* ������ɥ��ץ������� */
146 wc.cbClsExtra = 0; /* ��ĥ���� */
147 wc.cbWndExtra = 0; /* ��ĥ���� */
148 wc.hInstance = g_hInstance; /* �����ϥ�ɥ� */
149 wc.hIcon = NULL; /* �������� */
150 /*
151 wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION),
152 IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
153 */
154 wc.hIconSm = wc.hIcon; /* �������������� */
155 wc.hCursor = NULL; /* �ޥ����������� */
156 /*
157 wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),
158 IMAGE_CURSOR, 0, 0,
159 LR_DEFAULTSIZE | LR_SHARED);
160 */
161 /* ������ɥ��ط� */
162 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
163 /* wc.lpszMenuName = NULL;*/ /* ��˥塼̾ */
164 wc.lpszMenuName = "QUASI88"; /* ��˥塼̾ �� quasi88.rc */
165 wc.lpszClassName = "Win32App"; /* ������ɥ����饹̾ Ŭ�� */
166
167 /* ������ɥ����饹����Ͽ���� */
168 if (RegisterClassEx(&wc) == 0) { return FALSE; }
169
170 /* ������ɥ���������Ϥ��� */
171 winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
172
173 /* ������ɥ��������η� */
174 win_width = width;
175 win_height = height;
176 calc_window_size(&win_width, &win_height);
177
178 /* ������ɥ���������� */
179 g_hWnd = CreateWindowEx(WS_EX_ACCEPTFILES, /* ��ĥ������ɥ��������� */
180 wc.lpszClassName, /* ������ɥ����饹̾ */
181 "QUASI88 win32", /* �����ȥ�С�ʸ���� */
182 winStyle, /* ������ɥ��������� */
183 CW_USEDEFAULT, /* ������ɥ���x��ɸ */
184 CW_USEDEFAULT, /* ������ɥ���y��ɸ */
185 win_width, /* ������ɥ����� */
186 win_height, /* ������ɥ��ι⤵ */
187 NULL, /* �ƥ�����ɥ��Υϥ�ɥ� */
188 NULL, /* ��˥塼�ϥ�ɥ� */
189 g_hInstance, /* �����ϥ�ɥ� */
190 NULL); /* �ղþ��� */
191
192 if (g_hWnd == NULL) { return FALSE; }
193
194 /* ������ɥ���ɽ������ */
195 ShowWindow(g_hWnd, SW_SHOW);
196 UpdateWindow(g_hWnd);
197
198 /* ��˥塼�ϥ�ɥ� */
199 g_hMenu = GetMenu(g_hWnd);
200
201 /* Drug & Drop ��� */
202 #if 0
203 /* ������ɥ��κ������ˡ� WS_EX_ACCEPTFILES ��Ĥ��Ƥ���Τǡ���������� */
204 DragAcceptFiles(g_hWnd, TRUE);
205 #endif
206
207
208 #if 0
209 if (verbose_proc) { /* �ǥ����ץ쥤���� */
210 HDC hdc;
211 hdc = GetDC(g_hWnd);
212 fprintf(debugfp, "Info: H-pixel %d\n", GetDeviceCaps(hdc, HORZRES));
213 fprintf(debugfp, "Info: V-pixel %d\n", GetDeviceCaps(hdc, VERTRES));
214 fprintf(debugfp, "Info: Depth %d\n", GetDeviceCaps(hdc, BITSPIXEL));
215 ReleaseDC(g_hWnd, hdc);
216 }
217 #endif
218 return TRUE;
219 }
220
221
222
223 /*
224 * �����Υ�����ɥ��������������
225 */
calc_window_size(int * width,int * height)226 static void calc_window_size(int *width, int *height)
227 {
228 RECT rect;
229
230 rect.left = 0; rect.right = *width;
231 rect.top = 0; rect.bottom = *height;
232
233 AdjustWindowRectEx(&rect, /* ���饤����ȶ�� */
234 winStyle, /* ������ɥ��������� */
235 TRUE, /* ��˥塼�ե饰 */
236 0); /* ��ĥ������ɥ��������� */
237
238 *width = rect.right - rect.left; /* �����Υ�����ɥ����� */
239 *height = rect.bottom - rect.top; /* �����Υ�����ɥ��ι⤵ */
240 }
241
242
243
244 /************************************************************************/
245
graph_exit(void)246 void graph_exit(void)
247 {
248 if (buffer) {
249 free(buffer);
250 }
251 }
252
253 /************************************************************************
254 * �����
255 * �����
256 ************************************************************************/
257
graph_add_color(const PC88_PALETTE_T color[],int nr_color,unsigned long pixel[])258 void graph_add_color(const PC88_PALETTE_T color[],
259 int nr_color, unsigned long pixel[])
260 {
261 int i;
262 for (i=0; i<nr_color; i++) {
263
264 pixel[i] = ((((unsigned long) color[i].red) << 16) |
265 (((unsigned long) color[i].green) << 8) |
266 (((unsigned long) color[i].blue)));
267
268 /* RGB()�ޥ���ϡ������ȿž���Ƥ���ΤǻȤ��ʤ� */
269 }
270 }
271
272 /************************************************************************/
273
graph_remove_color(int nr_pixel,unsigned long pixel[])274 void graph_remove_color(int nr_pixel, unsigned long pixel[])
275 {
276 /* ���˴ؤ��Ƥϲ���������ʤ��Τǡ������Ǥ�ʤˤ⤷�ʤ� */
277 }
278
279 /************************************************************************
280 * ����ե��å��ι���
281 ************************************************************************/
282
283 static int graph_update_counter = 0;
284
graph_update_WM_PAINT(void)285 int graph_update_WM_PAINT(void)
286 {
287 int drawn;
288 HDC hdc;
289 PAINTSTRUCT ps;
290
291 hdc = BeginPaint(g_hWnd, &ps);
292
293 /* graph_update() �ˤ�ꡢ WM_PAINT ���٥�Ȥ�ȯ��������硢���褹�롣
294 OS �������ȯ�������� WM_PAINT ���٥�Ȥξ��ϡ��ʤˤ⤷�ʤ���
295 (quasi88_expose() �ν����ˤ�ꡢ graph_update() ���ƤӽФ���뤿��) */
296
297 if (graph_update_counter > 0) {
298 #if 1 /* �ɤ���� API �Ǥ�褵����®�٤ϡ� */
299 StretchDIBits(hdc,
300 0, 0, graph_info.width, graph_info.height,
301 0, 0, graph_info.width, graph_info.height,
302 buffer, &bmpInfo, DIB_RGB_COLORS, SRCCOPY);
303 #else /* ���ä��ϡ�ž����ι⤵��������Ǥ��ʤ� */
304 SetDIBitsToDevice(hdc,
305 0, 0, graph_info.width, graph_info.height,
306 0, 0, 0, graph_info.height,
307 buffer, &bmpInfo, DIB_RGB_COLORS);
308 #endif
309 graph_update_counter = 0;
310 drawn = TRUE;
311 } else {
312 drawn = FALSE;
313 }
314
315 /*
316 fprintf(debugfp,
317 "%s %d:(%3d,%3d)-(%3d,%3d)\n",
318 (drawn) ? "update" : "EXPOSE", graph_update_counter,
319 ps.rcPaint.left, ps.rcPaint.top,
320 ps.rcPaint.right, ps.rcPaint.bottom);
321 */
322 EndPaint(g_hWnd, &ps);
323
324 return drawn;
325 }
326
graph_update(int nr_rect,T_GRAPH_RECT rect[])327 void graph_update(int nr_rect, T_GRAPH_RECT rect[])
328 {
329 graph_update_counter = 1;
330
331 InvalidateRect(g_hWnd, NULL, FALSE);
332 UpdateWindow(g_hWnd);
333
334 /* �����ǡ�ľ�ܥ�����ɥ�����褦�Ȥ����Τ������ʤ��ޤ������ʤ���
335 WndProc() �������Ǥ�����������ɥ�����ϤǤ��ʤ��Τ��ʡ�
336
337 �Ȥꤢ������ InvalidateRect() ��ȡ� WM_PAINT ���٥�Ȥ�ȯ������
338 �Τǡ����θ�� WndProc() �� WM_PAINT �����ˤ����褵���뤳�Ȥˤ��褦��
339
340 ���ʤߤˡ� InvalidateRect() ��ľ��ˡ� UpdateWindow() ��ƤӽФ��ȡ�
341 ���δؿ��������� WndProc() ���ƤӽФ��졢 WM_PAINT �ν������Ԥ���
342 �餷�����Ĥޤ� UpdateWindow() ������ä�����������Ͻ���äƤ��롣
343
344 ���褳���� nr_rect �������֤��褦�ˤ��٤��ʤΤ��������ݤʤΤ�
345 �����̤�1��������褵���Ƥ��롣(®���ޥ���ʤ鵤�ˤʤ�ʤ� ^^;) */
346 }
347
348
349 /************************************************************************
350 * �����ȥ������
351 * °��������
352 ************************************************************************/
353
graph_set_window_title(const char * title)354 void graph_set_window_title(const char *title)
355 {
356 }
357
358 /************************************************************************/
359
graph_set_attribute(int mouse_show,int grab,int keyrepeat_on)360 void graph_set_attribute(int mouse_show, int grab, int keyrepeat_on)
361 {
362 g_keyrepeat = keyrepeat_on;
363
364 if (mouse_show) ShowCursor(TRUE);
365 else ShowCursor(FALSE);
366 }
367