1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 	Macintosh interface for TiMidity
21 	by T.Nogami	<t-nogami@happy.email.ne.jp>
22 
23     mac_wrdwindow.c
24     Macintosh graphics driver for WRD
25 */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30 #include <stdlib.h>
31 #include <string.h>
32 #include "timidity.h"
33 
34 #define ENTITY 1
35 #include "mac_wrdwindow.h"
36 
dev_change_1_palette(int code,RGBColor color)37 void dev_change_1_palette(int code, RGBColor color)
38 {
39 	(**(**dispWorld->portPixMap).pmTable).ctTable[code].rgb=color;
40 	(**(**dispWorld->portPixMap).pmTable).ctSeed++;
41 	//CTabChanged( (**dispWorld->portPixMap).pmTable );
42 	dev_palette[0][code]=color;
43 	//if( wrd_palette ){
44 	//	SetEntryUsage(wrd_palette, code, pmAnimated, 0x0000);
45 	//	//SetEntryColor(wrd_palette, code, &color);
46 	//	AnimateEntry(wrd_palette, code, &color);
47 	//	SetEntryUsage(wrd_palette, code, pmTolerant, 0x0000);
48 	//}
49 	pallette_exist |= color.red;
50 	pallette_exist |= color.green;
51 	pallette_exist |= color.blue;
52 }
53 
dev_change_palette(RGBColor pal[16])54 void dev_change_palette(RGBColor pal[16])
55 {					// don't update graphics
56 	int i;
57 	//RGBColor color;
58 	pallette_exist=0;
59 
60 	for( i=0; i<16; i++ ){
61 		pallette_exist |= pal[i].red;
62 		pallette_exist |= pal[i].green;
63 		pallette_exist |= pal[i].blue;
64 		dev_change_1_palette( i, pal[i]);
65 	}
66 	//dev_remake_disp(portRect);
67 	//dev_redisp(portRect);
68 }
69 
dev_init_text_color()70 void dev_init_text_color()
71 {
72 	int code;
73 	for( code=0; code<=7; code++){
74 		//(**(**graphicWorld[0]->portPixMap).pmTable).ctTable[TCODE2INDEX(code)].rgb=textcolor[code];
75 		//(**(**graphicWorld[1]->portPixMap).pmTable).ctTable[TCODE2INDEX(code)].rgb=textcolor[code];
76 		(**(**dispWorld->portPixMap).pmTable).ctTable[TCOLOR_INDEX_SHIFT+code].rgb=textcolor[code];
77 
78 		//(**(**graphicWorld[0]->portPixMap).pmTable).ctSeed++;
79 		//(**(**graphicWorld[1]->portPixMap).pmTable).ctSeed++;
80 		(**(**dispWorld->portPixMap).pmTable).ctSeed++;
81 	}
82 }
83 
expand_horizontality(PixMapHandle pixmap,int width,int height)84 static void expand_horizontality( PixMapHandle pixmap, int width, int height )
85 {			//pixmap must be locked	//for @TON(2)
86 	int	x,y;
87 	Ptr	baseAdr= GetPixBaseAddr(pixmap), xbase;
88 	int	rowBytes= (**pixmap).rowBytes & 0x1FFF;
89 
90 	for( y=0; y<height; y++){
91 		xbase= baseAdr+ rowBytes*y;
92 		for( x=width-1; x>=0; x-- ){
93 			xbase[x*2]= xbase[x*2+1]= xbase[x];
94 		}
95 	}
96 }
97 
dev_draw_text_gmode(PixMapHandle pixmap,int x,int y,const char * s,int len,int pmask,int mode,int fgcolor,int bgcolor,int ton_mode)98 void dev_draw_text_gmode(PixMapHandle pixmap, int x, int y, const char* s, int len,
99 		int pmask, int mode, int fgcolor, int bgcolor, int ton_mode)
100 {			//pixmap must be already locked
101 	GDHandle	oldGD;
102 	GWorldPtr	oldGW;
103 	int		color, trans, width;
104 	Rect		rect= {0,0,16,32},
105 			destrect;
106 
107 	GetGWorld(&oldGW, &oldGD);
108 	LockPixels(charbufWorld->portPixMap);
109 	SetGWorld(charbufWorld,0);
110 		trans=0;
111 		if( fgcolor==trans ) trans++;
112 		if( bgcolor==trans ) trans++;
113 		if( fgcolor==trans ) trans++;
114 
115 		color= ( (mode&2)? bgcolor:trans );
116 		dev_box(charbufWorld->portPixMap, rect, color, 0xFF);
117 
118 		color= ( (mode&1)? fgcolor:trans );
119 		charbufWorld->fgColor= color;
120 		TextMode(srcOr);
121 		MoveTo(0,13);
122 		DrawText(s,0,len);
123 		if( ton_mode==2 ){
124 			expand_horizontality(charbufWorld->portPixMap, len*8, 16);
125 		}
126 
127 		width= len*8;
128 		if( ton_mode==2 ) width*=2;
129 
130 		rect.right=width;
131 		destrect.left=x; destrect.top=y;
132 		destrect.right=x+width; destrect.bottom=destrect.top+16;
133 
134 		MyCopyBits(charbufWorld->portPixMap, pixmap,
135 			rect, destrect, 0x11/*trans*/, trans, pmask,
136 			0, 0, NULL);
137 
138 
139 	SetGWorld(oldGW, oldGD);
140 	UnlockPixels(charbufWorld->portPixMap);
141 }
142 
BlockMoveData_transparent(const void * srcPtr,void * destPtr,Size byteCount,int pmask,int trans)143 static void BlockMoveData_transparent(const void* srcPtr, void *destPtr,
144 				Size byteCount, int pmask, int trans)
145 {
146 	int i, tmp;
147 
148 	if( srcPtr>destPtr ){
149 		for( i=0; i<byteCount; i++){
150 			if( ((char*)srcPtr)[i]!=trans ){
151 				tmp=((char*)destPtr)[i];
152 				tmp &= ~pmask;
153 				tmp |= ( ((char*)srcPtr)[i] & pmask);
154 				((char*)destPtr)[i]= tmp;
155 			}
156 		}
157 	}else{
158 		for( i=byteCount-1; i>=0; i--){
159 			if( ((char*)srcPtr)[i]!=trans ){
160 				tmp=((char*)destPtr)[i];
161 				tmp &= ~pmask;
162 				tmp |= ( ((char*)srcPtr)[i] & pmask);
163 				((char*)destPtr)[i]= tmp;
164 			}
165 		}
166 	}
167 }
168 
169 #define PMASK_COPY(s,d,pmask) ((d)=((d)&~(pmask))|((s)&(pmask)))
170 
BlockMoveData_gmode(const void * srcPtr,void * destPtr,Size byteCount)171 static pascal void BlockMoveData_gmode(const void* srcPtr, void *destPtr,
172 								 Size 	byteCount)
173 {
174 	int i;
175 	const char*	src=srcPtr;
176 	char*		dest=destPtr;
177 
178 	if( srcPtr>destPtr ){
179 		for( i=0; i<byteCount; i++){
180 			PMASK_COPY(src[i],dest[i], gmode_mask);
181 		}
182 	}else{
183 		for( i=byteCount-1; i>=0; i--){
184 			PMASK_COPY(src[i],dest[i], gmode_mask);
185 		}
186 	}
187 }
188 
BlockMoveData_masktrans(const uint8 * srcPtr,uint8 * destPtr,Size byteCount,int trans,int maskx,const uint8 maskdata[])189 static pascal void BlockMoveData_masktrans(const uint8*	srcPtr,	 uint8 *destPtr,
190 			Size 	byteCount, int trans, int maskx, const uint8 maskdata[])
191 {
192 #define  BITON(x, data) (data[(x)/8]&(0x80>>((x)%8)))
193 	int i;
194 
195 	if( srcPtr>destPtr ){
196 		for( i=0; i<byteCount; i++){
197 			if(  srcPtr[i]!=trans  && BITON(i%maskx, maskdata)  ){
198 				PMASK_COPY(srcPtr[i],destPtr[i], gmode_mask);
199 			}
200 		}
201 	}else{
202 		for( i=byteCount-1; i>=0; i--){
203 			if( BITON(i%maskx, maskdata)  ){
204 				PMASK_COPY(srcPtr[i],destPtr[i], gmode_mask);
205 			}
206 		}
207 	}
208 }
209 
210 #if __MC68K__
mymemmove(const void * srcPtr,void * destPtr,Size byteCount)211 static pascal void mymemmove(const void* srcPtr, void * destPtr,Size byteCount)
212 {
213 	memmove(destPtr, srcPtr, byteCount);
214 }
215  #define BlockMoveData mymemmove
216 #endif
217 
MyCopyBits(PixMapHandle srcPixmap,PixMapHandle dstPixmap,Rect srcRect,Rect dstRect,short mode,int trans,int pmask,int maskx,int masky,const uint8 maskdata[])218 void MyCopyBits(PixMapHandle srcPixmap, PixMapHandle dstPixmap,
219 		Rect srcRect, Rect dstRect, short mode, int trans, int pmask,
220 		int maskx, int masky, const uint8 maskdata[])
221 {														//I ignore destRect.right,bottom
222 	int srcRowBytes= (**srcPixmap).rowBytes & 0x1FFF,
223 		destRowBytes= (**dstPixmap).rowBytes & 0x1FFF,
224 		y1, y2, width,hight, cut, dy, maskwidth;
225 	Ptr	srcAdr= GetPixBaseAddr(srcPixmap),
226 		dstAdr= GetPixBaseAddr(dstPixmap);
227 	Rect	srcBounds=  (**srcPixmap).bounds,
228 			dstBounds=  (**dstPixmap).bounds;
229 
230 
231 	//check params
232 	//chech src top
233 	if( srcRect.top<srcBounds.top ){
234 		cut= srcBounds.top-srcRect.top;
235 		srcRect.top+=cut; dstRect.top+=cut;
236 	}
237 	if( srcRect.top>srcBounds.bottom ) return;
238 	//check left
239 	if( srcRect.left  <srcBounds.left ){
240 		cut= srcBounds.left-srcRect.left;
241 		srcRect.left+= cut; dstRect.left+=cut;
242 	}
243 	if( srcRect.left>srcBounds.right ) return;
244 	//chech src bottom
245 	if( srcRect.bottom>srcBounds.bottom ){
246 		cut= srcRect.bottom-srcBounds.bottom;
247 		srcRect.bottom-= cut; dstRect.bottom-=cut;
248 	}
249 	if( srcRect.bottom<srcBounds.top ) return;
250 	//check right
251 	if( srcRect.right >srcBounds.right ){
252 		cut= srcRect.right-srcBounds.right;
253 		srcRect.right-= cut; srcBounds.right-= cut;
254 	}
255 	if( srcRect.right<srcBounds.left ) return;
256 
257 	width=srcRect.right-srcRect.left;
258 	hight=srcRect.bottom-srcRect.top;
259 
260 	//check dest
261 	//check top
262 	if( dstRect.top  <dstBounds.top ){
263 		cut= dstBounds.top-dstRect.top;
264 		srcRect.top+=cut; dstRect.top+=cut;
265 	}
266 	if( dstRect.top>dstBounds.bottom ) return;
267 	//check hight
268 	if( dstRect.top+hight>dstBounds.bottom ){
269 		hight=dstBounds.bottom-dstRect.top;
270 		srcRect.bottom=srcRect.top+hight;
271 	}
272 	//check left
273 	if( dstRect.left <dstBounds.left ){
274 		cut= dstBounds.left-dstRect.left;
275 		srcRect.left+= cut; dstRect.left+=cut;
276 	}
277 	if( dstRect.left>dstBounds.right ) return;
278 	//check width
279 	if( dstRect.left+width>dstBounds.right )
280 		width=dstBounds.right-dstRect.left;
281 
282 	switch( mode ){
283 	case 0://srcCopy
284 	case 0x10:
285 		{
286 			pascal void (*func)(const void* srcPtr, void *	destPtr,Size byteCount);
287 			if( pmask==0xFF ) func=BlockMoveData;
288 				else func= BlockMoveData_gmode;
289 			if( srcRect.top >= dstRect.top ){
290 				for( y1=srcRect.top, y2=dstRect.top; y1<srcRect.bottom; y1++,y2++ ){
291 					func( &(srcAdr[y1*srcRowBytes+srcRect.left]),
292 									&(dstAdr[y2*destRowBytes+dstRect.left]), width);
293 				}
294 			}else{
295 				for( y1=srcRect.bottom-1, y2=dstRect.top+hight-1; y1>=srcRect.top; y1--, y2-- ){
296 					func( &(srcAdr[y1*srcRowBytes+srcRect.left]),
297 									&(dstAdr[y2*destRowBytes+dstRect.left]), width);
298 				}
299 			}
300 		}
301 		break;
302 	case 0x11://transparent
303 		if( srcRect.top >= dstRect.top ){
304 			for( y1=srcRect.top, y2=dstRect.top; y1<srcRect.bottom; y1++,y2++ ){
305 				BlockMoveData_transparent( &(srcAdr[y1*srcRowBytes+srcRect.left]),
306 							&(dstAdr[y2*destRowBytes+dstRect.left]), width, pmask, trans);
307 			}
308 		}else{
309 			for( y1=srcRect.bottom-1, y2=dstRect.top+hight-1; y1>=srcRect.top; y1--, y2-- ){
310 				BlockMoveData_transparent( &(srcAdr[y1*srcRowBytes+srcRect.left]),
311 							&(dstAdr[y2*destRowBytes+dstRect.left]), width, pmask, trans);
312 			}
313 		}
314 		break;
315 	case 0x30:
316 	case 0x31: // masking & transparent //sherry op=0x62
317 		if( maskx<=0 ) break;
318 		maskwidth= ((maskx+7)& ~0x07)/8; //kiriage
319 		if( srcRect.top >= dstRect.top ){
320 			for( y1=srcRect.top, y2=dstRect.top, dy=0; y1<srcRect.bottom; y1++,y2++,dy++,dy%=masky ){
321 				BlockMoveData_masktrans( (uint8 *)&(srcAdr[y1*srcRowBytes+srcRect.left]),
322 					(uint8 *)&(dstAdr[y2*destRowBytes+dstRect.left]), width, trans,
323 					maskx, &maskdata[maskwidth*dy]);
324 			}
325 		}else{
326 			for( y1=srcRect.bottom-1, y2=dstRect.top+hight-1,dy=hight-1; y1>=srcRect.top; y1--, y2--,dy+=masky-1, dy%=masky ){
327 				BlockMoveData_masktrans( (uint8 *)&(srcAdr[y1*srcRowBytes+srcRect.left]),
328 					(uint8 *)&(dstAdr[y2*destRowBytes+dstRect.left]), width, trans,
329 					maskx, &maskdata[maskwidth*dy]);
330 			}
331 		}
332 		break;
333 	}
334 }
335 
dev_line(int x1,int y1,int x2,int y2,int color,int style,int pmask,PixMapHandle pixmap)336 void dev_line(int x1, int y1, int x2, int y2, int color, int style,
337 	int pmask, PixMapHandle pixmap )
338 {
339 	int	i, dx, dy, s, step;
340 	int	rowBytes= (**pixmap).rowBytes & 0x1FFF;
341 	Ptr	baseAdr= GetPixBaseAddr(pixmap);
342 	Rect	bounds=  (**pixmap).bounds;
343 	Point	pt;
344 	static const int mask[8]={0x80,0x40,0x20,0x10, 0x08,0x04,0x02,0x01};
345 	int	style_count=0;
346 
347 #define DOT(x,y,col) {Ptr p=&baseAdr[y*rowBytes+x]; pt.h=x;pt.v=y;    \
348 		if(PtInRect(pt,&bounds)){(*p)&=~pmask; (*p)|=col;} }
349 
350 	color &= pmask;
351 	step= ( (x1<x2)==(y1<y2) ) ? 1:-1;
352 	dx= abs(x2-x1); dy=abs(y2-y1);
353 
354 	if( dx>dy ){
355 		if( x1>x2 ){ x1=x2; y1=y2; }
356 		if(style & mask[style_count]){ DOT(x1,y1,color); }
357 					//else { DOT(x1,y1,0); }
358 		style_count= (style_count+1)%8;
359 		s= dx/2;
360 		for(i=x1+1; i<x1+dx; i++){
361 			s-= dy;
362 			if( s<0 ){ s+=dx; y1+=step;}
363 			if(style & mask[style_count]){ DOT(i,y1,color); }
364 						//else{ DOT(i,y1,0); }
365 			style_count= (style_count+1)%8;
366 		}
367 	}else{
368 		if( y1>y2 ){ x1=x2; y1=y2; }
369 		if(style & mask[style_count]){ DOT(x1,y1,color); }
370 					//else{ DOT(x1,y1,0); }
371 		style_count= (style_count+1)%8;
372 		s= dy/2;
373 		for(i=y1+1; i<y1+dy; i++){
374 			s-= dx;
375 			if( s<0 ){ s+=dy; x1+=step;}
376 			if(style & mask[style_count]){ DOT(x1,i,color); }
377 						//else{ DOT(x1,i,0); }
378 			style_count= (style_count+1)%8;
379 		}
380 	}
381 }
382 
dev_box(PixMapHandle pixmap,Rect rect,int color,int pmask)383 void dev_box(PixMapHandle pixmap, Rect rect, int color, int pmask)
384 {
385 	int		rowBytes= (**pixmap).rowBytes & 0x1FFF,
386 			x, y1, width,hight, tmp;
387 	Ptr		baseAdr= GetPixBaseAddr(pixmap);
388 	Rect	bounds=  (**pixmap).bounds;
389 
390 	//check params
391 	//chech src top
392 	if( rect.top<bounds.top ){
393 		rect.top=bounds.top;
394 	}
395 	if( rect.top>bounds.bottom ) return;
396 	//check left
397 	if( rect.left  <bounds.left ){
398 		rect.left= bounds.left;
399 	}
400 	if( rect.left>bounds.right ) return;
401 	//chech src bottom
402 	if( rect.bottom>bounds.bottom ){
403 		rect.bottom= bounds.bottom;
404 	}
405 	if( rect.bottom<bounds.top ) return;
406 	//check right
407 	if( rect.right >bounds.right ){
408 		rect.right= bounds.right;
409 	}
410 	if( rect.right<bounds.left ) return;
411 
412 	width=rect.right-rect.left;
413 	hight=rect.bottom-rect.top;
414 	color &= pmask;
415 
416 		for( y1=rect.top; y1<rect.bottom; y1++ ){
417 			for( x=rect.left; x<rect.right; x++){
418 				tmp=baseAdr[y1*rowBytes+x];
419 				tmp &= ~pmask;
420 				tmp |= color;
421 				baseAdr[y1*rowBytes+x]=tmp;
422 			}
423 		}
424 	}
425 
mac_setfont(GWorldPtr world,Str255 fontname)426 void mac_setfont(GWorldPtr world, Str255 fontname)
427 {
428 	GDHandle	oldGD;
429 	GWorldPtr	oldGW;
430 
431 	GetGWorld(&oldGW, &oldGD);
432 	LockPixels(world->portPixMap);
433 	{
434 		short		fontID;
435 		SetGWorld( world, 0);
436 		GetFNum(fontname, &fontID);
437 		TextFont(fontID);
438 		TextSize(14);
439 		TextFace(extend/*|bold*/);
440 	}
441 	SetGWorld(oldGW, oldGD);
442 	UnlockPixels(world->portPixMap);
443 }
444