/* TiMidity++ -- MIDI to WAVE converter and player Copyright (C) 1999-2004 Masanao Izumo Copyright (C) 1995 Tuukka Toivonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Macintosh interface for TiMidity by T.Nogami mac_c.c Macintosh control mode */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include "timidity.h" #include "common.h" #include "output.h" #include "controls.h" #include "instrum.h" #include "playmidi.h" #include "mfnode.h" #include "miditrace.h" #ifdef SUPPORT_SOUNDSPEC #include "soundspec.h" #endif /* SUPPORT_SOUNDSPEC */ #include "mac_main.h" #include "mac_util.h" #include "mac_c.h" #ifdef MAC_USE_OMS #include "mac_oms.h" #endif // ******************************* static void ctl_refresh(void); static void ctl_total_time(int tt); static void ctl_master_volume(int mv); static void ctl_file_name(char *name); static void ctl_current_time(int ct, int v); static void ctl_note(int status, int ch, int note, int vel); static void ctl_volume(int channel, int val); static void ctl_expression(int channel, int val); static void ctl_panning(int channel, int val); static void ctl_sustain(int channel, int val); static void ctl_pitch_bend(int channel, int val); static void ctl_reset(void); static int ctl_open(int using_stdin, int using_stdout); static int ctl_pass_playing_list(int number_of_files, char *list_of_files[]); static void ctl_close(void); static int ctl_read(int32 *valp); static int cmsg(int type, int verbosity_level, char *fmt, ...); static void ctl_event(CtlEvent *e); /**********************************/ /* export the interface functions */ #define ctl mac_control_mode ControlMode ctl= { "mac interface", 'm', "mac", 1,1,0, 0, ctl_open, ctl_close, ctl_pass_playing_list, ctl_read, NULL, cmsg, ctl_event }; static uint32 cuepoint = 0; static int cuepoint_pending = 0; // *********************************************** Boolean gCursorIsWatch, gHasDragMgr; #define FILESTR_LEN 40 #define TIMESTR_LEN 10 char fileStr[FILESTR_LEN]="", timeStr[TIMESTR_LEN]=""; Rect rFileName={10,10, 26,140}, rTime={10,150, 26,200}, rLogo={38,5,94,98}, rVol={28,220,92,239}, rPlay={40,110,62,142}, rStop={40,145,62,177}, rPause={40,180,62,212}, rPrevious={70,110,92,142}, rForward={70,145,92,177}, rEject={70,180,92,212}, rLoop={8,210,28,240}; PicHandle logo, logoDown; //static RgnHandle receiveRgn; CIconHandle button[6], iconPlay, iconPause, iconVol, iconTab, iconNotLoop,iconLoop; static TEHandle gLogTE=0,gDocTE=0; /****************************************/ static Boolean recieveHiliting; pascal OSErr DragTrackingProc( DragTrackingMessage theMessage, WindowPtr /*window*/, void* /*theRefCon*/, DragReference /*drag*/) { switch (theMessage) { case kDragTrackingEnterWindow: SetPort(mac_PlayerWindow.ref); //ShowDragHilite(drag, receiveRgn, true); DrawPicture(logoDown, &rLogo); recieveHiliting=true; break; case kDragTrackingInWindow: break; case kDragTrackingLeaveWindow: if( recieveHiliting ) { SetPort(mac_PlayerWindow.ref); //HideDragHilite(drag); DrawPicture(logo, &rLogo); recieveHiliting=false; } break; } return noErr; } pascal OSErr DragReceiveFunc( WindowPtr /*window*/, void* /*theRefCon*/, DragReference drag) { long i; char* data; unsigned short numFlavors; Size dataSize; ItemReference theItem; unsigned short itemCount; FlavorType flavor; if( recieveHiliting ) { int oldListEnd=mac_n_files; CountDragItems(drag, &itemCount); for( i=1; i<=itemCount; i++) { GetDragItemReferenceNumber(drag, i, &theItem); if( noErr!=CountDragItemFlavors(drag, theItem, &numFlavors)) continue; if( noErr!=GetFlavorType(drag, theItem, 1, &flavor)) continue; if( noErr!=GetFlavorDataSize(drag, theItem, flavor, &dataSize)) continue; data= (char*)malloc(dataSize); if( data==0 ) continue; if( noErr!=GetFlavorData(drag, theItem, flavor, data, &dataSize, 0)) continue; if(flavor== flavorTypeHFS) AddHFS2PlayList((HFSFlavor*)data); free(data); } if( gShuffle ) ShuffleList( oldListEnd, mac_n_files); } return noErr; } // ***************************************************** #pragma mark - int open_window(MacWindow* macwin, short resID) { macwin->ref=GetNewCWindow(resID, 0, (WindowRef)-1); if( macwin->ref==0) mac_ErrorExit("\pCannot open Window!"); SetWRefCon(macwin->ref, (long)macwin); return 0; } void position_window(MacWindow* macwin) { Point p; p.h=macwin->X; p.v=macwin->Y; if( PtInRect(p, &qd.screenBits.bounds) ){ MoveWindow(macwin->ref, macwin->X, macwin->Y, true); } SizeWindow(macwin->ref, macwin->width, macwin->hight, 0); if( macwin->show ) ShowWindow(macwin->ref); } static void setsize_window(MacWindow* macwin) { SizeWindow(macwin->ref, macwin->width, macwin->hight, 0); } void goaway_default(MacWindow* macwin) { HideWindow(macwin->ref); macwin->show=false; } void close_default(MacWindow* macwin) { Point p; Rect r; //Get Log Window position SetPortWindowPort(macwin->ref); p.v=p.h=0; LocalToGlobal(&p); macwin->X=p.h, macwin->Y=p.v; r= GetWindowPort(macwin->ref)->portRect; macwin->width= r.right-r.left; macwin->hight= r.bottom-r.top; } // ***************************************************** #pragma mark - #pragma mark =================Player Window static int open_PlayerWin(); static void click_PlayerWin(Point local, short modifiers); static void update_PlayerWin(); static void goaway_PlayerWin(MacWindow*); static int message_PlayerWin(int message, long param); #define win mac_PlayerWindow MacWindow win={ 0, //WindowRef open_PlayerWin, click_PlayerWin, update_PlayerWin, goaway_PlayerWin, close_default, message_PlayerWin, 1, 10,50 }; void mac_setVolume(short amplitude) { SndCommand theCmd; if( amplitude<0 ) amplitude=0; if( amplitude>255 ) amplitude=255; theCmd.cmd=ampCmd; theCmd.param1=amplitude; SndDoImmediate(gSndCannel, &theCmd); } void DoVolume() { short lastAmp=mac_amplitude; //SndCommand theCmd; Point p; SetPortWindowPort(win.ref); GetMouse(&p); /*GlobalToLocal(&p);*/ if( PtInRect(p, &rVol) && FrontWindow()==win.ref ) { mac_amplitude=255*((double)rVol.bottom-10-p.v)/(rVol.bottom-rVol.top-20); if( mac_amplitude<0 ) mac_amplitude=0; if( mac_amplitude>255 ) mac_amplitude=255; if( lastAmp!=mac_amplitude ) { //theCmd.cmd=ampCmd; //theCmd.param1=mac_amplitude; //SndDoImmediate(gSndCannel, &theCmd); mac_setVolume(mac_amplitude); InvalRect(&rVol); } } } void DrawButton() { SetPortWindowPort(win.ref); PlotCIcon(&rPlay, skin_state==PLAYING || skin_state==PAUSE? iconPlay:button[0] ); PlotCIcon(&rStop, button[1]); PlotCIcon(&rPause, skin_state==PAUSE? iconPause:button[2] ); PlotCIcon(&rPrevious, button[3]); PlotCIcon(&rForward, button[4]); PlotCIcon(&rEject, button[5]); } static void DrawFileStr() { SetPortWindowPort(win.ref); TETextBox(fileStr, strlen(fileStr), &rFileName, teCenter); } static void DrawTimeStr() { SetPortWindowPort(win.ref); TETextBox(timeStr, strlen(timeStr), &rTime, teCenter); } static int open_PlayerWin() /*success-> return 0;*/ { int i; OSErr err; RGBColor back={0,0,0}, fore={65535,65535,65535}; open_window( &win, kPlayerWinID); position_window(&win); SetPortWindowPort(win.ref); RGBForeColor(&fore); RGBBackColor(&back); logo= GetPicture(128); logoDown= GetPicture(132); for(i=0; i<6; i++) button[i]= GetCIcon(i+200); iconPlay=GetCIcon(210); iconPause=GetCIcon(211); iconVol=GetCIcon(206); iconTab=GetCIcon(207); iconNotLoop=GetCIcon(208); iconLoop=GetCIcon(209); if(gHasDragMgr) { //receiveRgn=NewRgn(); //if( receiveRgn ) { //GetWindowContentRgn(win.ref, receiveRgn); err=InstallTrackingHandler(NewDragTrackingHandlerProc(DragTrackingProc), (WindowPtr)win.ref, 0); if(err) ExitToShell(); err=InstallReceiveHandler(NewDragReceiveHandlerProc(DragReceiveFunc), (WindowPtr)win.ref, 0); if(err) ExitToShell(); } } return 0; } static void click_PlayerWin(Point p, short /*modifiers*/) { if( PtInRect(p, &rStop)){ mac_rc=RC_QUIT; ctl_current_time(0,0); } else if( PtInRect(p, &rPlay)){ mac_rc=RC_CONTINUE; } else if( PtInRect(p, &rPause)){ mac_rc=RC_TOGGLE_PAUSE; } else if( PtInRect(p, &rPrevious)){ mac_rc=RC_PREVIOUS; } else if( PtInRect(p, &rForward)){ mac_rc=RC_NEXT; } else if( PtInRect(p, &rEject)){ if( skin_state==PLAYING ) mac_rc=RC_QUIT; skin_state=WAITING; mac_n_files=nPlaying=0; fileStr[0]=timeStr[0]=0; init_ListWin(); update_PlayerWin(); } else if( PtInRect(p, &rLoop)){ skin_f_repeat=!skin_f_repeat; SetPortWindowPort(win.ref); InvalRect(&rLoop); return; } /* don't call mac_HandleControl();*/ else if( PtInRect(p, &rVol)) DoVolume(); else return; /* no button click*/ /* if button clicked */ mac_HandleControl(); } static void update_PlayerWin() { short y=((double)mac_amplitude/255)*(rVol.bottom-rVol.top-20); Rect rFrame,rTab; SetPortWindowPort(win.ref); DrawButton(); skin_f_repeat? PlotCIcon(&rLoop, iconLoop):PlotCIcon(&rLoop, iconNotLoop); PlotCIcon(&rVol, iconVol); SetRect(&rTab, rVol.left+2, rVol.top+49-y, rVol.right-2, rVol.top+59-y); PlotCIcon(&rTab, iconTab); rFrame=rFileName; InsetRect(&rFrame, -2, -2); DrawPicture(GetPicture(129), &rFrame); rFrame=rTime; InsetRect(&rFrame, -2, -2); DrawPicture(GetPicture(130), &rFrame); DrawPicture(logo, &rLogo); DrawTimeStr(); DrawFileStr(); } static void goaway_PlayerWin(MacWindow *macwin) { Do_Quit(); } static int message_PlayerWin(int /*message*/, long /*param*/) { return -1; } #undef win // ***************************************************** #pragma mark - #pragma mark ==================Log Window static int open_LogWin(); static void click_LogWin(Point local, short modifiers); static void update_LogWin(); static int message_LogWin(int message, long param); #define win mac_LogWindow MacWindow win={ 0, //WindowRef open_LogWin, click_LogWin, update_LogWin, goaway_default, close_default, message_LogWin, 1, 270,60, 300,200 }; static void PrintLogStr(char str[]) { int len=strlen(str); if( !mac_LogWindow.show ) return; if( (**gLogTE).teLength > 10000) /* clear first half*/ { TEFeatureFlag(teFAutoScroll, teBitClear, gLogTE); TESetSelect(0, 5000, gLogTE); TEDelete(gLogTE); } TESetSelect((**gLogTE).teLength, (**gLogTE).teLength, gLogTE); /* move to end*/ if( len>=1 && str[len-1]=='\n' ){ str[len-1]=0; len--; //convert dos return code to mac's } TEInsert(str, len, gLogTE); TESelView(gLogTE); TEFeatureFlag(teFAutoScroll, teBitSet, gLogTE); } static int open_LogWin() /*success-> return 0;*/ { open_window(&win, kLogWinID); position_window(&win); setsize_window(&win); SetPortWindowPort(win.ref); TextSize(10); gLogTE=TENew(&win.ref->portRect, &win.ref->portRect); if( gLogTE==0 ) mac_ErrorExit("\ppCannot open LogWindow!"); TEFeatureFlag(teFAutoScroll, teBitSet, gLogTE); TEActivate(gLogTE); return 0; } static void click_LogWin(Point local, short /*modifiers*/) { TEClick(local, 0, gLogTE); } static void update_LogWin() { SetPortWindowPort(win.ref); TEUpdate(&win.ref->portRect, gLogTE); } static int message_LogWin(int message, long /*param*/) { Rect rect; switch(message){ case MW_GROW: rect=win.ref->portRect; //rect.right-=15; rect.bottom-=15; rect = win.ref->portRect; rect.right -= 15; //rect.bottom -= 15; (**gLogTE).viewRect= (**gLogTE).destRect= rect; (**gLogTE).destRect.right = (**gLogTE).destRect.right - 14; TECalText(gLogTE); TESetSelect((**gLogTE).teLength, (**gLogTE).teLength, gLogTE); return 0; } return -1; //not supported } #undef win // ***************************************************** #pragma mark - #pragma mark ==================List Window ListHandle gPlaylist; static int open_ListWin(); static void click_ListWin(Point local, short modifiers); static void update_ListWin(); static int message_ListWin(int message, long param); enum{ MW_LIST_SELECT= 0x00010001, MW_DOC_SET= 0x00020001 }; #define win mac_ListWindow MacWindow win={ 0, //WindowRef open_ListWin, click_ListWin, update_ListWin, goaway_default, close_default, message_ListWin, 1, 100,100, 300,200 }; void change_ListRow( short row, const MidiFile* file) { Point aCell; char buf[256]="",*p; if( file && file->mfn && file->mfn->title ) { strncpy(buf, file->mfn->title, sizeof(buf) - 1); buf[sizeof(buf)-1] = '\0'; } p= strrchr(file->filename, PATH_SEP); if( p ){ size_t len = strlen(buf); snprintf(&buf[len], sizeof(buf)-len-1, " (%s)", p+1); buf[sizeof(buf)-1] = '\0'; } SetPt(&aCell, 0, row); LSetCell( buf, strlen(buf), aCell, gPlaylist); } void add_ListWin(MidiFile * file) { short rowNum=1; //Str255 fullPath; //GetFullPath(&file->spec, fullPath); file->mfn=make_new_MFnode_entry(file->filename); rowNum = (**gPlaylist).dataBounds.bottom; rowNum = LAddRow(1, rowNum, gPlaylist); change_ListRow( rowNum, file); } void init_ListWin() { short rowNum= (**gPlaylist).dataBounds.bottom; SetPortWindowPort(win.ref); LDelRow(0, 0, gPlaylist); } static int open_ListWin() /*success-> return 0;*/ { Rect listRect, dataBounds; Point cSize; open_window(&win, kListWinID); position_window(&win); setsize_window(&win); SetPortWindowPort(win.ref); TextSize(10); listRect=win.ref->portRect; listRect.right-=14; listRect.bottom-=14; dataBounds.top=dataBounds.left=0; dataBounds.right=1; dataBounds.bottom=0; cSize.h=1024; cSize.v=14; gPlaylist = LNew(&listRect, &dataBounds, cSize, 0, win.ref, 1, 1, 0, 1); return 0; } static void click_ListWin(Point local, short modifiers) { Boolean doubleclick; Cell cell; SetPortWindowPort(win.ref); doubleclick=LClick(local, modifiers, gPlaylist); if(doubleclick){ mac_rc=RC_LOAD_FILE; cell = LLastClick(gPlaylist); nPlaying=cell.v; mac_HandleControl(); } } static void update_ListWin() { SetPortWindowPort(win.ref); LUpdate( win.ref->visRgn, gPlaylist); DrawGrowIcon(win.ref); } static int message_ListWin(int message, long param) { Cell cell; Rect rect; switch(message){ case MW_GROW: rect=win.ref->portRect; LSize(rect.right-14, rect.bottom-14, gPlaylist); return 0; case MW_LIST_SELECT: LDeselectAll(gPlaylist); cell.h=0; cell.v=param; LSetSelect(true, cell, gPlaylist); LAutoScroll(gPlaylist); return 0; } return -1; //not supported } #undef win // ***************************************************** #pragma mark - #pragma mark ==================Doc Window static int open_DocWin(); static void click_DocWin(Point local, short modifiers); static void update_DocWin(); static void close_DocWin(); static int message_DocWin(int message, long param); #define win mac_DocWindow MacWindow win={ 0, //WindowRef open_DocWin, click_DocWin, update_DocWin, goaway_default, close_default, message_DocWin, 0, 150,150, 300,200 }; static void PrintDocStr(char str[]) { if( (**gDocTE).teLength > 10000) /* clear first half*/ { TESetSelect(0, 5000, gDocTE); TEDelete(gDocTE); } TESetSelect((**gDocTE).teLength, (**gDocTE).teLength, gDocTE); /* move to end*/ TEInsert(str, strlen(str), gDocTE); TESelView(gDocTE); } static int open_DocWin() /*success-> return 0;*/ { Rect r; open_window(&win, kDocWinID); position_window(&win); setsize_window(&win); SetPortWindowPort(win.ref); TextSize(10); r=win.ref->portRect; r.right-=16; gDocTE=TENew(&r, &r); if( gDocTE==0 ) mac_ErrorExit("\pCannot open DocWindow!"); TEFeatureFlag(teFAutoScroll, teBitSet, gDocTE); TEActivate(gDocTE); return 0; } static void click_DocWin(Point local, short /*modifiers*/) { TEClick(local, 0, gDocTE); } static void update_DocWin() { SetPortWindowPort(win.ref); DrawGrowIcon(win.ref); TEUpdate(&win.ref->portRect, gDocTE); } static int message_DocWin(int message, long param) { switch(message){ case MW_GROW: { Rect rect; rect=win.ref->portRect; //rect.right-=15; rect.bottom-=15; rect = win.ref->portRect; rect.right -= 16; //rect.bottom -= 15; (**gDocTE).viewRect= (**gDocTE).destRect= rect; //(**gDocTE).destRect.right = (**gDocTE).destRect.right - 14; TECalText(gDocTE); TESetSelect((**gDocTE).teLength, (**gDocTE).teLength, gDocTE); return 0; } case MW_DOC_SET: { const char *midiname=(char*)param; char *p, docname[256]; //midiname= (char*)param; strncpy(docname, midiname, sizeof docname - 1); docname[sizeof docname - 1] = '\0'; if((p = strrchr(docname, '.')) == NULL){ return 0; } else if(p - docname >= sizeof docname - 4) { return 0; /* cannot strcpy: that cause buffer overrun */ } if('A' <= p[1] && p[1] <= 'Z') strcpy(p + 1, "DOC"); else strcpy(p + 1, "doc"); TEReadFile( docname, gDocTE ); break; } } return -1; //not supported } #undef win // ***************************************************** #pragma mark - #pragma mark ================== spec Window static int open_SpecWin(); static void click_SpecWin(Point local, short modifiers); static void update_SpecWin(); static void goaway_SpecWin(MacWindow*); static int message_SpecWin(int message, long param); #define win mac_SpecWindow MacWindow win={ 0, //WindowRef open_SpecWin, click_SpecWin, update_SpecWin, goaway_SpecWin, close_default, message_SpecWin, 0, 100,100 }; static int open_SpecWin() /*success-> return 0;*/ { #ifdef SUPPORT_SOUNDSPEC open_window(&win, kSpecWinID); position_window(&win); //always //if( win.show ){ //Preference on open_soundspec(); soundspec_update_wave(NULL, 0); //} #endif /* SUPPORT_SOUNDSPEC */ return 0; } static void click_SpecWin(Point /*local*/, short /*modifiers*/) { } static void update_SpecWin() { SetPortWindowPort(win.ref); } static void goaway_SpecWin(MacWindow *macwin) { goaway_default(macwin); //close_soundspec(); } static int message_SpecWin(int message, long /*param*/) { Rect rect; switch(message){ case MW_GROW: rect=win.ref->portRect; //rect.right-=15; rect.bottom-=15; rect = win.ref->portRect; rect.right -= 15; //rect.bottom -= 15; return 0; } return -1; //not supported } #undef win // ***************************************************** #pragma mark - static MacWindow* WindowList[]={ &mac_PlayerWindow, &mac_LogWindow, &mac_ListWindow, &mac_WrdWindow, &mac_DocWindow, &mac_SpecWindow, &mac_TraceWindow, &mac_SkinWindow, 0 }; void DoUpdate(WindowRef win_ref) { MacWindow* macwin; macwin = (MacWindow*)GetWRefCon(win_ref); if( macwin ) macwin->update(); } static void mac_AdjustMenus(short modifiers) { MenuHandle filenemu=GetMenu(mFile), synthemu=GetMenu(mSynth); //CheckItem(filenemu, iLogWindow & 0xFFFF, gShowMsg); //CheckItem(filenemu, iListWindow & 0xFFFF, gShowList); //CheckItem(filenemu, iWrdWindow & 0xFFFF, gShowWrd); if( modifiers & optionKey ){ //EnableItem(filenemu, iSkinWindow); EnableItem(synthemu, iQuickTime); EnableItem(synthemu, iOMS); } } void HandleMouseDown(EventRecord *event) { short part; WindowRef window; MacWindow *macwin; Rect growRect={100,100,32000,32000}; long size; part=FindWindow(event->where, &window); macwin = (MacWindow*)GetWRefCon(window); switch(part) { case inMenuBar: mac_AdjustMenus(event->modifiers); mac_HandleMenuSelect(MenuSelect(event->where), event->modifiers); HiliteMenu(0); break; case inContent: SetPortWindowPort(window); SelectWindow(window); GlobalToLocal(&event->where); if(macwin) macwin->click(event->where, event->modifiers); break; case inDrag: DragWindow(window, event->where, &qd.screenBits.bounds); break; case inGrow: SetPortWindowPort(window); size=GrowWindow(window, event->where, &growRect); if( size ) { SizeWindow(window, size&0x0000FFFF, size>>16, 0); EraseRect(&GetWindowPort(window)->portRect); InvalRect(&GetWindowPort(window)->portRect); if( macwin ) macwin->message(MW_GROW, size); } break; case inGoAway: if( TrackGoAway(window, event->where) ){ if( macwin ){ macwin->goaway(macwin); } } break; //case inZoomIn: //case inZoomOut: // break; } } // ***************************************************** #pragma mark - #pragma mark ===============control function static int ctl_open(int /*using_stdin*/, int /*using_stdout*/) /*success-> return 0;*/ { int i, err; for(i=0; WindowList[i]; i++){ err=WindowList[i]->open(); if(err) break; } if( !err ) ctl.opened=1; return err; } static void ctl_close(void) { int i; for( i=0; WindowList[i]; i++ ){ WindowList[i]->close(WindowList[i]); } ctl.opened=0; return; } static int ctl_pass_playing_list(int init_number_of_files, char * /*init_list_of_files*/ []) { EventRecord event; if( init_number_of_files!=0 ){ cmsg(CMSG_FATAL, VERB_NORMAL, "ctl_pass_playing_list: Sorry. Fatal error."); } #ifdef MAC_USE_OMS mac_oms_setup(); #endif { FSSpec spec; OSErr err; err=FSMakeFSSpec(0, 0, MAC_STARTUP_FOLDER_NAME, &spec); if( err==noErr ){ mac_add_fsspec( &spec ); } } gQuit=false; while(!gQuit) { WaitNextEvent(everyEvent, &event, 1,0); mac_HandleEvent(&event); } Do_Quit(); return 0; } static Boolean UserWantsControl() { /* Mouse downĄ€or key downĄ„*/ KeyMap km; GetKeys(km); km[1] &= ~0x02; /* exclude caps lock */ return Button() || km[0]|| km[1] || km[2] || km[3] || skin_state==PAUSE; } static int ctl_read(int32* /*valp*/) { int ret; if (cuepoint_pending) { *valp = cuepoint; cuepoint_pending = 0; return RC_FORWARD; } //if( gCursorIsWatch ){ gCursorIsWatch=false; InitCursor(); } if( gQuit ) Do_Quit(); /* Quit Apple event occured */ if( mac_rc ){ret=mac_rc; mac_rc=0; return ret;} if( !gBusy || UserWantsControl()){ YieldToAnyThread(); } return RC_NONE; } static void ctl_lyric(int lyricid) { char *lyric; lyric = event2string(lyricid); if(lyric == NULL) return; ctl.cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", lyric + 1); } static void ctl_gslcd(int lyricid) { char *lyric; lyric = event2string(lyricid); if(lyric == NULL) return; if( lyric[0] == ME_GSLCD ){ int i,j, data, mask; char tmp[3]= "00"; lyric++; for( j=0; j<4; j++ ){ for( i=0; i<16; i++ ){ tmp[0]= lyric[0]; tmp[1]= lyric[1]; lyric+=2; sscanf(tmp, "%X", &data); mask=0x10; ctl_note((data&mask)? VOICE_ON:-1, i, 40+j*10, 127); ctl_note((data&mask)? VOICE_ON:-1, i, 41+j*10, 127); mask>>=1; ctl_note((data&mask)? VOICE_ON:-1, i, 42+j*10, 127); ctl_note((data&mask)? VOICE_ON:-1, i, 43+j*10, 127); mask>>=1; ctl_note((data&mask)? VOICE_ON:-1, i, 44+j*10, 127); ctl_note((data&mask)? VOICE_ON:-1, i, 45+j*10, 127); mask>>=1; ctl_note((data&mask)? VOICE_ON:-1, i, 46+j*10, 127); ctl_note((data&mask)? VOICE_ON:-1, i, 47+j*10, 127); mask>>=1; ctl_note((data&mask)? VOICE_ON:-1, i, 48+j*10, 127); ctl_note((data&mask)? VOICE_ON:-1, i, 49+j*10, 127); mask>>=1; } } return; } //else normal text ctl.cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", lyric + 1); } static int cmsg(int type, int verbosity_level, char * fmt, ...) { #define BUFSIZE 1024 char buf[BUFSIZE]; va_list ap; if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) && ctl.verbosityrate); mac_SkinWindow.message(MW_SKIN_TOTAL_TIME, tt/play_mode->rate); } static void ctl_master_volume(int /*mv*/) {} static void ctl_file_name(char *name) { int i; char *s; for( i=strlen(name); i>=0; i--) if( name[i]==PATH_SEP ) { s=&name[i]+1; //remove pathname break; } snprintf(fileStr, FILESTR_LEN, "%d. %s", nPlaying+1, s); if (ctl.verbosity>=0 || ctl.trace_playing){ DrawFileStr(); } mac_ListWindow.message(MW_LIST_SELECT, nPlaying); mac_DocWindow.message(MW_DOC_SET, (long)name); mac_trc_update_all_info(); mac_SkinWindow.message(MW_SKIN_FILENAME, (long)fileStr); } static void ctl_current_time(int current, int /*v*/) { static int lastSec=-1, lastYieldThread=-1; int mins, secs, realSecs; if( gStartTick==0 ) gStartTick=TickCount(); /*select*/ realSecs=(TickCount()-gStartTick)/60; /*real time*/ secs=current; if( secs!=lastSec && (skin_state==PLAYING || skin_state==PAUSE)) { lastSec=secs; mins=secs/60; secs-=mins*60; snprintf(timeStr, TIMESTR_LEN, "%02d:%02d", mins, secs); DrawTimeStr(); mac_trc_update_time(current,-1); mac_SkinWindow.message(MW_SKIN_TIME, lastSec); } if( realSecs!=lastYieldThread ){ lastYieldThread= realSecs; mac_trc_update_time(current,-1); mac_trc_update_voices(); if( (realSecs % (evil_level*evil_level))==0 ) YieldToAnyThread(); // YieldToAnyThread every 1sec } } static void ctl_note(int status, int ch, int note, int vel) { if( ! mac_TraceWindow.show ) return; if(note == -1) { //if(ctl.trace_playing && !midi_trace.flush_flag) // push_midi_trace0(update_indicator); return; } //push_midi_note(v_ctl_note, note); v_ctl_note( status, ch, note, vel); } static void ctl_program(int ch, int val, char *comm){mac_ctl_program(ch,val,comm);} static void ctl_volume(int /*channel*/, int /*val*/) {} static void ctl_expression(int /*channel*/, int /*val*/) {} static void ctl_panning(int /*channel*/, int /*val*/) {} static void ctl_sustain(int /*channel*/, int /*val*/) {} static void ctl_pitch_bend(int /*channel*/, int /*val*/) {} static void ctl_reset(void) { mac_ctl_reset_trc(); } static void ctl_event(CtlEvent *e) { switch(e->type) { case CTLE_NOW_LOADING: ctl_file_name((char *)e->v1); break; case CTLE_LOADING_DONE: break; case CTLE_PLAY_START: ctl_total_time((int)e->v1); break; case CTLE_PLAY_END: break; case CTLE_CUEPOINT: cuepoint = e->v1; cuepoint_pending = 1; break; case CTLE_TEMPO: break; case CTLE_METRONOME: break; case CTLE_CURRENT_TIME: ctl_current_time((int)e->v1, (int)e->v2); break; case CTLE_NOTE: ctl_note((int)e->v1, (int)e->v2, (int)e->v3, (int)e->v4); break; case CTLE_MASTER_VOLUME: ctl_master_volume((int)e->v1); break; case CTLE_PROGRAM: ctl_program((int)e->v1, (int)e->v2, (char *)e->v3); break; case CTLE_VOLUME: ctl_volume((int)e->v1, (int)e->v2); break; case CTLE_EXPRESSION: ctl_expression((int)e->v1, (int)e->v2); break; case CTLE_PANNING: ctl_panning((int)e->v1, (int)e->v2); break; case CTLE_SUSTAIN: ctl_sustain((int)e->v1, (int)e->v2); break; case CTLE_PITCH_BEND: ctl_pitch_bend((int)e->v1, (int)e->v2); break; case CTLE_MOD_WHEEL: ctl_pitch_bend((int)e->v1, e->v2 ? -1 : 0x2000); break; case CTLE_CHORUS_EFFECT: break; case CTLE_REVERB_EFFECT: break; case CTLE_LYRIC: ctl_lyric((int)e->v1); break; case CTLE_GSLCD: ctl_gslcd((int)e->v1); break; case CTLE_REFRESH: ctl_refresh(); break; case CTLE_RESET: ctl_reset(); break; #ifdef SUPPORT_SOUNDSPEC case CTLE_SPEANA: ctl_speana_data((double *)e->v1, (int)e->v2); break; #endif /* SUPPORT_SOUNDSPEC */ } }