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 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 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 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 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 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 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 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 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__ 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 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 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 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 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