1 /***********************************************************************
2  * ����ե��å����� (�����ƥ��¸)
3  *
4  *	�ܺ٤ϡ� graph.h ����
5  ************************************************************************/
6 
7 /*----------------------------------------------------------------------*
8  * Classic�С������Υ����������ɤ�����ʬ�ϡ�                          *
9  * Koichi NISHIDA ��� Classic iP6 PC-6001/mk2/6601 emulator �Υ������� *
10  * ���ͤˤ����Ƥ��������ޤ�����                                         *
11  *                                                   (c) Koichi NISHIDA *
12  *----------------------------------------------------------------------*/
13 
14 #include <stdio.h>
15 
16 #include "quasi88.h"
17 #include "graph.h"
18 #include "device.h"
19 
20 
21 #ifdef	SUPPORT_DOUBLE
22 #error !
23 #endif
24 
25 
26 /********************** �����Х��ѿ� **********************/
27 
28 // main window & graphic world
29 WindowRef	macWin;
30 GWorldPtr	macGw;
31 
32 QDGlobals	macQd;
33 
34 int		mac_8bpp = TRUE;	/* ͥ��Ū�ˡ�256���⡼�ɤ�ư����� */
35 
36 
37 /************************************************************************/
38 /* ���ɽ�����֡������餷�� */
39 #define WIN_X 20
40 #define WIN_Y 60
41 
42 /* ��������ο�����Ȥ� */
43 #define	ALL_COLORS	(24)
44 
45 // default palette
46 static PaletteHandle defPalette;
47 static int	nr_color_used;
48 
49 static void InitColor(void);
50 
51 
52 static	T_GRAPH_SPEC	graph_spec;		/* ���ܾ���		*/
53 
54 static	int		graph_exist;		/* ���ǡ����������Ѥ�	*/
55 static	T_GRAPH_INFO	graph_info;		/* ���λ��Ρ����̾���	*/
56 
57 
58 /************************************************************************
59  *	CLASSIC�ν����
60  *	CLASSIC�ν�λ
61  ************************************************************************/
62 static unsigned long displayOrigDepth;
63 static unsigned long displayDepth;
64 static unsigned long chkSysDepth(void);
65 
mac_init(void)66 void	mac_init(void)
67 {
68     SysEnvRec sys;
69 
70     // initialize
71     InitGraf((Ptr) &macQd.thePort);
72     InitFonts();
73     InitWindows();
74     InitMenus();
75     TEInit();
76     InitDialogs(NULL);
77     InitCursor();
78 
79     // color QD check
80     SysEnvirons(1, &sys);
81     if (! sys.hasColorQD) ExitToShell();
82 
83     // depth check
84 #ifdef	SUPPORT_16BPP
85     if (mac_8bpp) displayDepth = 8;	/* 256���⡼��  ������˥����å����� */
86     else          displayDepth = 16;	/* 32000���⡼�ɤ�����˥����å����� */
87     if (! HasDepth(GetMainDevice(), displayDepth, 1, 1)) {
88 	if (displayDepth == 8) displayDepth = 16;
89 	else                   displayDepth = 8;
90 	if (! HasDepth(GetMainDevice(), displayDepth, 1, 1)) {
91 	    mac_error_dialog( "Sorry, 256 or 32000 Color mode only!" );
92 	    ExitToShell();
93 	}
94     }
95 #else
96     displayDepth = 8;
97     if (! HasDepth(GetMainDevice(), displayDepth, 1, 1)) {
98 	mac_error_dialog( "Sorry, 256 Color mode only!" );
99 	ExitToShell();
100     }
101 #endif
102 
103     // change depth
104     displayOrigDepth = chkSysDepth();
105     SetDepth(GetMainDevice(), displayDepth, 1, 1);
106 
107     // menu resource
108 #if 0
109     {
110 	Handle menuBar;
111 	menuBar = GetNewMBar(128);
112 	if (! menuBar) ExitToShell();
113 	SetMenuBar(menuBar);
114 	DisposeHandle(menuBar);
115 	AppendResMenu(GetMenuHandle(128),'DRVR');
116 	DrawMenuBar();
117     }
118 #else
119 	if (! mac_create_menubar()) ExitToShell();
120 #endif
121 
122     /*�������Ϥ�Roman��*/
123     KeyScript(smKeyRoman);
124 }
125 
126 /************************************************************************/
127 
mac_exit(void)128 void	mac_exit(void)
129 {
130     /*�������Ϥ����᤹*/
131     KeyScript(smKeySwapScript);
132 
133     SetDepth(GetMainDevice(), displayOrigDepth, 1, 1);
134     ExitToShell();
135 }
136 
137 /*----------------------------------------------------------------------*/
138 // get depth of main device
chkSysDepth(void)139 static unsigned long chkSysDepth(void)
140 {
141     GDHandle ghd;
142     PixMapHandle phd;
143     int depth = 1;
144 
145     ghd = GetMainDevice();
146     phd = (*ghd)->gdPMap;
147     if (!(depth = (*phd)->pixelSize))
148 	depth = 1;
149     return depth;
150 }
151 
152 
153 /************************************************************************
154  *	����ե��å������ν����
155  *	����ե��å�������ư��
156  *	����ե��å������ν�λ
157  ************************************************************************/
158 
graph_init(void)159 const T_GRAPH_SPEC	*graph_init(void)
160 {
161     int	win_w, win_h;
162     int	ful_w, ful_h;
163 
164     if (verbose_proc) {
165 	printf("Initializing Graphic System ... \n");
166     }
167 
168 
169     /* ���̥����������������ˡ��? */
170     win_w = 10000;
171     win_h = 10000;
172     ful_w = 640;
173     ful_h = 480;
174 
175     graph_spec.window_max_width      = win_w;
176     graph_spec.window_max_height     = win_h;
177     graph_spec.fullscreen_max_width  = ful_w;
178     graph_spec.fullscreen_max_height = ful_h;
179     graph_spec.forbid_status         = FALSE;
180     graph_spec.forbid_half           = FALSE;
181 
182     if (verbose_proc)
183 	printf("  INFO: %dbpp->%dbpp(%dbyte), Maxsize=win(%d,%d),full(%d,%d)\n",
184 	       (int)displayOrigDepth, (int)displayDepth, (int)displayDepth/8,
185 	       win_w, win_h, ful_w, ful_h);
186 
187     // to get key up event
188     SetEventMask(everyEvent);
189 
190     /* �ѥ�åȤ��������� */
191     if (verbose_proc) printf("  Color Initialized\n");
192     InitColor();
193 
194     return &graph_spec;
195 }
196 
197 /************************************************************************/
198 
199 static void createWindow(int width, int height);
200 static void toWindowMode(void);
201 static void toFullscreenMode(int width, int height);
202 
203 
graph_setup(int width,int height,int fullscreen,double aspect)204 const T_GRAPH_INFO	*graph_setup(int width, int height,
205 				     int fullscreen, double aspect)
206 {
207     T_GRAPH_INFO *info = &graph_info;
208 
209     /* aspect ��̤���� */
210 
211     if (verbose_proc){
212 	if (graph_exist) printf("Re-Initializing Graphic System ... \n");
213 	if (fullscreen) printf("  Trying full screen mode <%dx%d> ... ",
214 			       width, height);
215 	else            printf("  Opening window ... ");
216     }
217 
218     if (graph_exist == FALSE) {			/* ��� */
219 	createWindow(width, height);
220 	if (fullscreen) {
221 	    toFullscreenMode(width, height);
222 	}
223     } else {					/* 2���ܰʹ� */
224 	if (info->fullscreen) {
225 	    if (fullscreen) {				/* FULL �� FULL */
226 
227 		toWindowMode();
228 		createWindow(width, height);
229 		toFullscreenMode(width, height);
230 
231 	    } else {					/* FULL �� WIN */
232 		toWindowMode();
233 		/* ��������ľ���� toFullscreenMode �Τ�Ʊ���ʤ�������ס� */
234 		createWindow(width, height);
235 	    }
236 
237 	} else {
238 	    if (fullscreen) {				/* WIN �� FULL */
239 
240 		/* ��������ľ���� createWindow �Τ�Ʊ���ʤ�������ס� */
241 		createWindow(width, height);
242 		toFullscreenMode(width, height);
243 
244 	    } else {					/* WIN �� WIN */
245 		createWindow(width, height);
246 	    }
247 	}
248     }
249 
250     if (verbose_proc) printf("OK (%dx%d)\n", info->width, info->height);
251 
252     graph_exist = TRUE;
253 
254     info->byte_per_pixel = displayDepth / 8;
255     info->nr_color	 = ALL_COLORS;
256     info->write_only	 = FALSE;
257     info->broken_mouse	 = (info->fullscreen) ? TRUE : FALSE;
258     info->draw_start	 = NULL;
259     info->draw_finish	 = NULL;
260     info->dont_frameskip = FALSE;
261 
262     /* ���������١����ѺѤߤο��������ͤ��᤹ */
263     nr_color_used = 1;
264     return info;
265 }
266 
267 /*======================================================================*/
268 
createWindow(int width,int height)269 static void createWindow(int width, int height)
270 {
271     T_GRAPH_INFO *info = &graph_info;
272 
273     Rect rect;
274     PixMapHandle pmh;
275 
276 
277     SetRect(&rect, WIN_X, WIN_Y, WIN_X + width, WIN_Y + height);
278     // re-size window
279     if (macWin) DisposeWindow(macWin);
280     macWin = NewCWindow(NULL, &rect, "\p", true, documentProc, (WindowRef)-1L, false, 0);
281 
282 
283     // re-create off screen
284     if (macGw) {
285 	pmh = GetGWorldPixMap(macGw);
286 	UnlockPixels(pmh);
287 	DisposeGWorld(macGw);
288     }
289     SetRect(&rect, 0, 0, width, height);
290     NewGWorld(&macGw, displayDepth, &rect, NULL, NULL, 0);
291     pmh = GetGWorldPixMap(macGw);
292     LockPixels(pmh);
293 
294 
295     info->fullscreen    = FALSE;
296     info->width         = width;
297     info->height        = height;
298     info->byte_per_line = ((**pmh).rowBytes & 0x3fff);
299     info->buffer        = GetPixBaseAddr(pmh);
300 
301     //memset(info->buffer, 0x00, info->byte_per_line * info->height);
302 
303     if (displayDepth == 8) {
304 	PixMapHandle pixmap;
305 	CTabHandle ctab;
306 	GDHandle mainhd;
307 	RGBColor rgb;
308 	int i;
309 
310 	NSetPalette(macWin, defPalette, pmAllUpdates);
311 	ActivatePalette(macWin);
312 
313 	pixmap = GetGWorldPixMap(macGw);
314 	ctab = (*pixmap)->pmTable;
315 	mainhd = GetMainDevice();
316 
317 	for (i=0; i<ALL_COLORS + 1; i++) {
318 	    GetEntryColor(defPalette, i, &rgb);
319 	    (*ctab)->ctTable[i].rgb = rgb;
320 	    (*ctab)->ctTable[i].value = i;
321 	}
322 	(*ctab)->ctSeed = (*(*(*mainhd)->gdPMap)->pmTable)->ctSeed;
323     }
324 }
325 
326 
327 // for full screen
328 static Ptr screenRestore;
329 static WindowRef macWinRestore;
330 
331 
332 // change to window mode
toWindowMode(void)333 static void toWindowMode(void)
334 {
335     T_GRAPH_INFO *info = &graph_info;
336 
337     PixMapHandle pmh;
338 
339     if (displayDepth == 8) {
340 	macWin = macWinRestore;
341     }
342 
343     EndFullScreen(screenRestore, 0);
344     SetDepth(GetMainDevice(), displayDepth, 1, 1);
345     pmh = GetGWorldPixMap(macGw);
346 
347     info->fullscreen    = FALSE;
348     /* info->width      = ;	toFullscreenMode ��	*/
349     /* info->height     = ;	���ꤷ���������ˤʤ�	*/
350     info->byte_per_line = ((**pmh).rowBytes & 0x3fff);
351     info->buffer        = GetPixBaseAddr(pmh);
352 
353     if (displayDepth == 8) {
354 	NSetPalette(macWin, defPalette, pmAllUpdates);
355 	ActivatePalette(macWin);
356     }
357 }
358 
359 // change to full screen mode
toFullscreenMode(int width,int height)360 static void toFullscreenMode(int width, int height)
361 {
362     T_GRAPH_INFO *info = &graph_info;
363 
364     GDHandle mainDevice = GetMainDevice();
365     PixMapHandle pmh;
366     RGBColor black = {0, 0, 0};
367     short screenWidth  = width;
368     short screenHeight = height;
369 
370 
371     if (displayDepth == 8) {
372 	macWinRestore = macWin;
373 
374 	if (BeginFullScreen(&screenRestore, mainDevice, &screenWidth, &screenHeight,
375 			    &macWin, &black, fullScreenHideCursor) != noErr) return;
376     } else {
377 	if (BeginFullScreen(&screenRestore, mainDevice, &screenWidth, &screenHeight,
378 			    NULL,    &black, fullScreenHideCursor) != noErr) return;
379     }
380 
381     pmh = (**mainDevice).gdPMap;
382 
383     info->fullscreen    = TRUE;
384     info->width         = screenWidth;
385     info->height        = screenHeight;
386     info->byte_per_line = ((**pmh).rowBytes & 0x3fff);
387     info->buffer        = GetPixBaseAddr(pmh);
388 
389     //memset(info->buffer, 0x00, info->byte_per_line * info->height);
390 
391     if (displayDepth == 8) {
392 	NSetPalette(macWin, defPalette, pmAllUpdates);
393 	ActivatePalette(macWin);
394     }
395 }
396 
397 
398 /************************************************************************/
399 
graph_exit(void)400 void	graph_exit(void)
401 {
402     if (graph_exist) {
403 	if (graph_info.fullscreen) toWindowMode();
404 	CloseWindow(macWin);
405     }
406 }
407 
408 
409 
mac_is_fullscreen(void)410 int	mac_is_fullscreen(void)
411 {
412     if (graph_exist) {
413 	if (graph_info.fullscreen) return TRUE;
414     }
415     return FALSE;
416 }
417 
418 
419 
420 /************************************************************************
421  *	���γ���
422  *	���β���
423  ************************************************************************/
424 
graph_add_color(const PC88_PALETTE_T color[],int nr_color,unsigned long pixel[])425 void	graph_add_color(const PC88_PALETTE_T color[],
426 			int nr_color, unsigned long pixel[])
427 {
428     if (displayDepth == 8) {
429 	PixMapHandle pixmap;
430 	CTabHandle ctab;
431 	GDHandle mainhd;
432 	RGBColor rgb;
433 	int i;
434 
435 	for (i=0; i<nr_color; i++) {
436 	    rgb.red   = (unsigned short)color[i].red   << 8;
437 	    rgb.green = (unsigned short)color[i].green << 8;
438 	    rgb.blue  = (unsigned short)color[i].blue  << 8;
439 	    SetEntryColor (defPalette, nr_color_used + i, &rgb);
440 
441 	    pixel[i] = nr_color_used + i;
442 	}
443 	nr_color_used += nr_color;
444 
445 
446 	/* ���ν��������ɬ�פʤΤ��� �ե륹���꡼��Ǥ����פʤΡ� */
447 	if (graph_exist &&
448 	    graph_info.fullscreen == FALSE) {
449 
450 	    pixmap = GetGWorldPixMap(macGw);
451 	    ctab = (*pixmap)->pmTable;
452 	    mainhd = GetMainDevice();
453 
454 	    for (i=0; i<ALL_COLORS + 1; i++) {
455 		GetEntryColor(defPalette, i, &rgb);
456 		(*ctab)->ctTable[i].rgb = rgb;
457 		(*ctab)->ctTable[i].value = i;
458 	    }
459 	    (*ctab)->ctSeed = (*(*(*mainhd)->gdPMap)->pmTable)->ctSeed;
460 	}
461 
462 	/* �����ɬ�ܤΤ褦���������̤�����Ĥ������� */
463 	ActivatePalette(macWin);
464 
465     } else {
466 	int i;
467 	for (i=0; i<nr_color; i++) {
468 	    pixel[i] = ( ((unsigned short)(color[i].red   >> 3) << 10) |
469 			 ((unsigned short)(color[i].green >> 3) <<  5) |
470 			 ((unsigned short)(color[i].blue  >> 3)) );
471 	}
472     }
473 }
474 
475 /************************************************************************/
476 
graph_remove_color(int nr_pixel,unsigned long pixel[])477 void	graph_remove_color(int nr_pixel, unsigned long pixel[])
478 {
479     nr_color_used -= nr_pixel;
480 }
481 
482 /*======================================================================*/
483 
484 /* set up coltable, alind8? etc. */
InitColor(void)485 static void InitColor(void)
486 {
487     if (displayDepth == 8) {
488 	RGBColor rgb;
489 	int i;
490 	const int param[ALL_COLORS][3] = // {R,G,B}
491 	{
492 	    { 0x0000, 0x0000, 0x0000 },		/* ���� ���ǽ���� */
493 	};
494 
495 	defPalette = NewPalette(ALL_COLORS + 1, NULL, pmTolerant + pmExplicit, 0);
496 
497 	// 0 is preserved by Mac
498 	rgb.red = rgb.green = rgb.blue = 255;
499 	SetEntryColor(defPalette, 0, &rgb);
500 
501 	/* �Ȥꤢ�������ǥե���Ȥο������ */
502 	for (i=0; i<ALL_COLORS; i++) {
503 	    rgb.red   = param[i][0];
504 	    rgb.green = param[i][1];
505 	    rgb.blue  = param[i][2];
506 	    SetEntryColor(defPalette, i + 1, &rgb);
507 	}
508     }
509 }
510 
511 /************************************************************************
512  *	����ե��å��ι���
513  ************************************************************************/
514 
515 static void draw(int x0, int y0, int x1, int y1);
516 
graph_update(int nr_rect,T_GRAPH_RECT rect[])517 void	graph_update(int nr_rect, T_GRAPH_RECT rect[])
518 {
519     int i;
520 
521     if (graph_info.fullscreen == FALSE) {
522 	for (i=0; i<nr_rect; i++) {
523 	    draw(rect[i].x,
524 		 rect[i].y,
525 		 rect[i].x + rect[i].width,
526 		 rect[i].y + rect[i].height);
527 	}
528     }
529 }
530 
531 /*======================================================================*/
532 // draw
draw(int x0,int y0,int x1,int y1)533 static void draw(int x0, int y0, int x1, int y1)
534 {
535     CGrafPtr port;
536     GWorldPtr gptr;
537     GDHandle ghd;
538     Rect rect;
539 
540     // blit !
541     GetGWorld(&gptr, &ghd);
542     port = GetWindowPort(macWin);
543     SetGWorld(port, NULL);
544     SetRect(&rect, x0, y0, x1, y1);
545     //SetRect(&rect, 0, 0, graph_info.width, graph_info.height);
546     CopyBits(&((GrafPtr)macGw)->portBits, &(macWin->portBits), &rect, &rect,
547 	     srcCopy, NULL);
548     SetGWorld(gptr, ghd);
549 }
550 
551 
552 
mac_draw_immidiate(void)553 void	mac_draw_immidiate(void)
554 {
555     if (graph_info.fullscreen == FALSE) {
556 	draw(0, 0, graph_info.width, graph_info.height);
557     }
558 }
559 
560 
561 
562 /************************************************************************
563  *	�����ȥ������
564  *	°��������
565  ************************************************************************/
566 // Window title strings
567 static Str255 wtitle;
568 
graph_set_window_title(const char * title)569 void	graph_set_window_title(const char *title)
570 {
571     wtitle[0] = strlen(title);
572     memcpy(wtitle+1, title, wtitle[0]);
573 
574     if (macWin) {
575 	SetWTitle(macWin, wtitle);
576     }
577 }
578 
579 /************************************************************************/
580 
graph_set_attribute(int mouse_show,int grab,int keyrepeat_on)581 void	graph_set_attribute(int mouse_show, int grab, int keyrepeat_on)
582 {
583     /* ����λ������狼��ʤ��� */
584     (void)mouse_show;
585     (void)grab;
586     (void)keyrepeat_on;
587 }
588