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